OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 import 'dart:nativewrappers'; | 5 import 'dart:nativewrappers'; |
6 | 6 |
7 import 'dart:_mojo/application.dart'; | 7 import 'dart:_mojo/application.dart'; |
8 import 'dart:_mojo/bindings.dart'; | 8 import 'dart:_mojo/bindings.dart'; |
9 import 'dart:_mojo/core.dart'; | 9 import 'dart:_mojo/core.dart'; |
10 import 'dart:_mojo/mojo/network_error.mojom.dart'; | 10 import 'dart:_mojo/mojo/network_error.mojom.dart'; |
11 import 'dart:_mojo_services/mojo/host_resolver.mojom.dart'; | 11 import 'dart:_mojo_services/mojo/host_resolver.mojom.dart'; |
12 import 'dart:_mojo_services/mojo/net_address.mojom.dart'; | 12 import 'dart:_mojo_services/mojo/net_address.mojom.dart'; |
13 import 'dart:_mojo_services/mojo/network_service.mojom.dart'; | 13 import 'dart:_mojo_services/mojo/network_service.mojom.dart'; |
14 import 'dart:_mojo_services/mojo/tcp_bound_socket.mojom.dart'; | 14 import 'dart:_mojo_services/mojo/tcp_bound_socket.mojom.dart'; |
15 import 'dart:_mojo_services/mojo/tcp_connected_socket.mojom.dart'; | 15 import 'dart:_mojo_services/mojo/tcp_connected_socket.mojom.dart'; |
16 import 'dart:_mojo_services/mojo/tcp_server_socket.mojom.dart'; | 16 import 'dart:_mojo_services/mojo/tcp_server_socket.mojom.dart'; |
17 import 'dart:_mojo_services/mojo/files/file.mojom.dart'; | 17 import 'dart:_mojo_services/mojo/files/file.mojom.dart'; |
18 import 'dart:_mojo_services/mojo/files/files.mojom.dart'; | 18 import 'dart:_mojo_services/mojo/files/files.mojom.dart'; |
19 import 'dart:_mojo_services/mojo/files/directory.mojom.dart'; | 19 import 'dart:_mojo_services/mojo/files/directory.mojom.dart'; |
20 import 'dart:_mojo_services/mojo/files/ioctl.mojom.dart'; | 20 import 'dart:_mojo_services/mojo/files/ioctl.mojom.dart'; |
21 import 'dart:_mojo_services/mojo/files/types.mojom.dart' as types; | 21 import 'dart:_mojo_services/mojo/files/types.mojom.dart' as types; |
22 | 22 |
| 23 // TODO(zra): Investigate the runtime cost of using these wrapper classes. |
| 24 // Port to use the callback API where necessary to recover performance. |
| 25 class _NetworkServiceProxy extends FuturizedProxy<NetworkServiceProxy> { |
| 26 Map<Symbol, Function> _mojoMethods; |
| 27 NetworkServiceProxy _nsProxy; |
| 28 |
| 29 _NetworkServiceProxy(NetworkServiceProxy p) : super(p) { |
| 30 _mojoMethods = <Symbol, Function>{ |
| 31 #createTcpBoundSocket: p.createTcpBoundSocket, |
| 32 #createTcpConnectedSocket: p.createTcpConnectedSocket, |
| 33 #createHttpServer: p.createHttpServer, |
| 34 }; |
| 35 _nsProxy = p; |
| 36 } |
| 37 Map<Symbol, Function> get mojoMethods => _mojoMethods; |
| 38 |
| 39 Function get createUrlLoader => _nsProxy.createUrlLoader; |
| 40 Function get getCookieStore => _nsProxy.getCookieStore; |
| 41 Function get createWebSocket => _nsProxy.createWebSocket; |
| 42 Function get createUdpSocket => _nsProxy.createUdpSocket; |
| 43 Function get registerUrlLoaderInterceptor => |
| 44 _nsProxy.registerUrlLoaderInterceptor; |
| 45 Function get createHostResolver => _nsProxy.createHostResolver; |
| 46 |
| 47 static final Map<Symbol, Function> _mojoResponses = { |
| 48 #createTcpBoundSocket: |
| 49 new NetworkServiceCreateTcpBoundSocketResponseParams#init, |
| 50 #createTcpConnectedSocket: |
| 51 new NetworkServiceCreateTcpConnectedSocketResponseParams#init, |
| 52 #createHttpServer: |
| 53 new NetworkServiceCreateHttpServerResponseParams#init, |
| 54 }; |
| 55 Map<Symbol, Function> get mojoResponses => _mojoResponses; |
| 56 } |
| 57 |
| 58 class _HostResolverProxy extends FuturizedProxy<HostResolverProxy> { |
| 59 Map<Symbol, Function> _mojoMethods; |
| 60 |
| 61 _HostResolverProxy(HostResolverProxy proxy) : super(proxy) { |
| 62 _mojoMethods = <Symbol, Function>{ |
| 63 #getHostAddresses: proxy.getHostAddresses, |
| 64 }; |
| 65 } |
| 66 Map<Symbol, Function> get mojoMethods => _mojoMethods; |
| 67 |
| 68 _HostResolverProxy.unbound() : this(new HostResolverProxy.unbound()); |
| 69 |
| 70 static final Map<Symbol, Function> _mojoResponses = { |
| 71 #getHostAddresses: new HostResolverGetHostAddressesResponseParams#init, |
| 72 }; |
| 73 Map<Symbol, Function> get mojoResponses => _mojoResponses; |
| 74 } |
| 75 |
| 76 class _TcpBoundSocketProxy extends FuturizedProxy<TcpBoundSocketProxy> { |
| 77 Map<Symbol, Function> _mojoMethods; |
| 78 |
| 79 _TcpBoundSocketProxy(TcpBoundSocketProxy proxy) : super(proxy) { |
| 80 _mojoMethods = <Symbol, Function>{ |
| 81 #startListening: proxy.startListening, |
| 82 #connect: proxy.connect, |
| 83 }; |
| 84 } |
| 85 Map<Symbol, Function> get mojoMethods => _mojoMethods; |
| 86 |
| 87 _TcpBoundSocketProxy.unbound() : this(new TcpBoundSocketProxy.unbound()); |
| 88 |
| 89 static final Map<Symbol, Function> _mojoResponses = { |
| 90 #startListening: new TcpBoundSocketStartListeningResponseParams#init, |
| 91 #connect: new TcpBoundSocketConnectResponseParams#init, |
| 92 }; |
| 93 Map<Symbol, Function> get mojoResponses => _mojoResponses; |
| 94 } |
| 95 |
| 96 class _TcpServerSocketProxy extends FuturizedProxy<TcpServerSocketProxy> { |
| 97 Map<Symbol, Function> _mojoMethods; |
| 98 |
| 99 _TcpServerSocketProxy(TcpServerSocketProxy proxy) : super(proxy) { |
| 100 _mojoMethods = <Symbol, Function>{ |
| 101 #accept: proxy.accept, |
| 102 }; |
| 103 } |
| 104 Map<Symbol, Function> get mojoMethods => _mojoMethods; |
| 105 |
| 106 _TcpServerSocketProxy.unbound() : this(new TcpServerSocketProxy.unbound()); |
| 107 |
| 108 static final Map<Symbol, Function> _mojoResponses = { |
| 109 #accept: new TcpServerSocketAcceptResponseParams#init, |
| 110 }; |
| 111 Map<Symbol, Function> get mojoResponses => _mojoResponses; |
| 112 } |
| 113 |
| 114 class _FilesProxy extends FuturizedProxy<FilesProxy> { |
| 115 Map<Symbol, Function> _mojoMethods; |
| 116 |
| 117 _FilesProxy(FilesProxy proxy) : super(proxy) { |
| 118 _mojoMethods = <Symbol, Function>{ |
| 119 #openFileSystem: proxy.openFileSystem, |
| 120 }; |
| 121 } |
| 122 Map<Symbol, Function> get mojoMethods => _mojoMethods; |
| 123 |
| 124 static final Map<Symbol, Function> _mojoResponses = { |
| 125 #openFileSystem: new FilesOpenFileSystemResponseParams#init, |
| 126 }; |
| 127 Map<Symbol, Function> get mojoResponses => _mojoResponses; |
| 128 } |
| 129 |
| 130 class _FileProxy extends FuturizedProxy<FileProxy> { |
| 131 Map<Symbol, Function> _mojoMethods; |
| 132 |
| 133 _FileProxy(FileProxy proxy) : super(proxy) { |
| 134 _mojoMethods = <Symbol, Function>{ |
| 135 #close_: proxy.close_, |
| 136 #read: proxy.read, |
| 137 #write: proxy.write, |
| 138 #readToStream: proxy.readToStream, |
| 139 #writeFromStream: proxy.writeFromStream, |
| 140 #tell: proxy.tell, |
| 141 #seek: proxy.seek, |
| 142 #stat: proxy.stat, |
| 143 #truncate: proxy.truncate, |
| 144 #touch: proxy.touch, |
| 145 #dup: proxy.dup, |
| 146 #repoen: proxy.reopen, |
| 147 #asBuffer: proxy.asBuffer, |
| 148 #ioctl: proxy.ioctl, |
| 149 }; |
| 150 } |
| 151 Map<Symbol, Function> get mojoMethods => _mojoMethods; |
| 152 |
| 153 _FileProxy.unbound() : this(new FileProxy.unbound()); |
| 154 |
| 155 static final Map<Symbol, Function> _mojoResponses = { |
| 156 #close_: new FileCloseResponseParams#init, |
| 157 #read: new FileReadResponseParams#init, |
| 158 #write: new FileWriteResponseParams#init, |
| 159 #readToStream: new FileReadToStreamResponseParams#init, |
| 160 #writeFromStream: new FileWriteFromStreamResponseParams#init, |
| 161 #tell: new FileTellResponseParams#init, |
| 162 #seek: new FileSeekResponseParams#init, |
| 163 #stat: new FileStatResponseParams#init, |
| 164 #truncate: new FileTruncateResponseParams#init, |
| 165 #touch: new FileTouchResponseParams#init, |
| 166 #dup: new FileDupResponseParams#init, |
| 167 #repoen: new FileReopenResponseParams#init, |
| 168 #asBuffer: new FileAsBufferResponseParams#init, |
| 169 #ioctl: new FileIoctlResponseParams#init, |
| 170 }; |
| 171 Map<Symbol, Function> get mojoResponses => _mojoResponses; |
| 172 } |
| 173 |
| 174 class _DirectoryProxy extends FuturizedProxy<DirectoryProxy> { |
| 175 Map<Symbol, Function> _mojoMethods; |
| 176 |
| 177 _DirectoryProxy(DirectoryProxy proxy) : super(proxy) { |
| 178 _mojoMethods = <Symbol, Function>{ |
| 179 #read: proxy.read, |
| 180 #stat: proxy.stat, |
| 181 #touch: proxy.touch, |
| 182 #openFile: proxy.openFile, |
| 183 #openDirectory: proxy.openDirectory, |
| 184 #rename: proxy.rename, |
| 185 #delete: proxy.delete, |
| 186 }; |
| 187 } |
| 188 Map<Symbol, Function> get mojoMethods => _mojoMethods; |
| 189 |
| 190 _DirectoryProxy.unbound() : this(new DirectoryProxy.unbound()); |
| 191 |
| 192 static final Map<Symbol, Function> _mojoResponses = { |
| 193 #read: new DirectoryReadResponseParams#init, |
| 194 #stat: new DirectoryStatResponseParams#init, |
| 195 #touch: new DirectoryTouchResponseParams#init, |
| 196 #openFile: new DirectoryOpenFileResponseParams#init, |
| 197 #openDirectory: new DirectoryOpenDirectoryResponseParams#init, |
| 198 #rename: new DirectoryRenameResponseParams#init, |
| 199 #delete: new DirectoryDeleteResponseParams#init, |
| 200 }; |
| 201 Map<Symbol, Function> get mojoResponses => _mojoResponses; |
| 202 } |
| 203 |
23 // When developing, set fileSystemDeveloper to true and the file system will | 204 // When developing, set fileSystemDeveloper to true and the file system will |
24 // persist under ~/MojoAppPersistentCaches/. | 205 // persist under ~/MojoAppPersistentCaches/. |
25 const bool fileSystemDeveloper = false; | 206 const bool fileSystemDeveloper = false; |
26 const String fileSystemName = | 207 const String fileSystemName = |
27 fileSystemDeveloper ? 'app_persistent_cache' : null; | 208 fileSystemDeveloper ? 'app_persistent_cache' : null; |
28 | 209 |
29 // System temp path relative to the root directory. | 210 // System temp path relative to the root directory. |
30 const String systemTempPath = 'tmp'; | 211 const String systemTempPath = 'tmp'; |
31 | 212 |
32 // | 213 // |
33 // Mojo objects and helper functions used by the 'dart:io' library. | 214 // Mojo objects and helper functions used by the 'dart:io' library. |
34 // | 215 // |
35 int _networkServiceHandle; | 216 int _networkServiceHandle; |
36 int _filesServiceHandle; | 217 int _filesServiceHandle; |
37 NetworkServiceProxy _networkService; | 218 _NetworkServiceProxy _networkService; |
38 HostResolverProxy _hostResolver; | 219 _HostResolverProxy _hostResolver; |
39 FilesProxy _files; | 220 _FilesProxy _files; |
40 DirectoryProxy _rootDirectory; | 221 _DirectoryProxy _rootDirectory; |
41 DirectoryProxy _systemTempDirectory; | 222 _DirectoryProxy _systemTempDirectory; |
42 | 223 |
43 void _initialize( | 224 void _initialize( |
44 int networkServiceHandle, int filesServiceHandle, String scriptPath) { | 225 int networkServiceHandle, int filesServiceHandle, String scriptPath) { |
45 if (networkServiceHandle != MojoHandle.INVALID) { | 226 if (networkServiceHandle != MojoHandle.INVALID) { |
46 _networkServiceHandle = networkServiceHandle; | 227 _networkServiceHandle = networkServiceHandle; |
47 } | 228 } |
48 if (filesServiceHandle != MojoHandle.INVALID) { | 229 if (filesServiceHandle != MojoHandle.INVALID) { |
49 _filesServiceHandle = filesServiceHandle; | 230 _filesServiceHandle = filesServiceHandle; |
50 } | 231 } |
51 // TODO(floitsch): do this lazily once _Platform.script is a getter. | 232 // TODO(floitsch): do this lazily once _Platform.script is a getter. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 _rootDirectory.close(immediate: true); | 268 _rootDirectory.close(immediate: true); |
88 _rootDirectory = null; | 269 _rootDirectory = null; |
89 } | 270 } |
90 if (_systemTempDirectory != null) { | 271 if (_systemTempDirectory != null) { |
91 _systemTempDirectory.close(immediate: true); | 272 _systemTempDirectory.close(immediate: true); |
92 _systemTempDirectory = null; | 273 _systemTempDirectory = null; |
93 } | 274 } |
94 } | 275 } |
95 | 276 |
96 /// Get the singleton NetworkServiceProxy. | 277 /// Get the singleton NetworkServiceProxy. |
97 NetworkServiceProxy _getNetworkService() { | 278 _NetworkServiceProxy _getNetworkService() { |
98 if (_networkService != null) { | 279 if (_networkService != null) { |
99 return _networkService; | 280 return _networkService; |
100 } | 281 } |
101 _networkService = new NetworkServiceProxy.fromHandle( | 282 var networkService = new NetworkServiceProxy.fromHandle( |
102 new MojoHandle(_networkServiceHandle).pass()); | 283 new MojoHandle(_networkServiceHandle).pass()); |
| 284 _networkService = new _NetworkServiceProxy(networkService); |
103 _networkServiceHandle = null; | 285 _networkServiceHandle = null; |
104 return _networkService; | 286 return _networkService; |
105 } | 287 } |
106 | 288 |
107 /// Get the singleton HostResolverProxy. | 289 /// Get the singleton HostResolverProxy. |
108 HostResolverProxy _getHostResolver() { | 290 _HostResolverProxy _getHostResolver() { |
109 if (_hostResolver != null) { | 291 if (_hostResolver != null) { |
110 return _hostResolver; | 292 return _hostResolver; |
111 } | 293 } |
112 var networkService = _getNetworkService(); | 294 _NetworkServiceProxy networkService = _getNetworkService(); |
113 if (networkService == null) { | 295 if (networkService == null) { |
114 return null; | 296 return null; |
115 } | 297 } |
116 _hostResolver = new HostResolverProxy.unbound(); | 298 _hostResolver = new _HostResolverProxy.unbound(); |
117 networkService.createHostResolver(_hostResolver); | 299 networkService.createHostResolver(_hostResolver.proxy); |
118 // Remove the host resolver's handle from the open set because it is not | 300 // Remove the host resolver's handle from the open set because it is not |
119 // under application control and does not affect isolate shutdown. | 301 // under application control and does not affect isolate shutdown. |
120 _hostResolver.ctrl.endpoint.handle.pass(); | 302 _hostResolver.proxy.ctrl.endpoint.handle.pass(); |
121 return _hostResolver; | 303 return _hostResolver; |
122 } | 304 } |
123 | 305 |
124 /// Get the singleton FilesProxy. | 306 /// Get the singleton FilesProxy. |
125 FilesProxy _getFiles() { | 307 _FilesProxy _getFiles() { |
126 if (_files != null) { | 308 if (_files != null) { |
127 return _files; | 309 return _files; |
128 } | 310 } |
129 _files = new FilesProxy.fromHandle( | 311 var files = new FilesProxy.fromHandle( |
130 new MojoHandle(_filesServiceHandle).pass()); | 312 new MojoHandle(_filesServiceHandle).pass()); |
| 313 _files = new _FilesProxy(files); |
131 _filesServiceHandle = null; | 314 _filesServiceHandle = null; |
132 return _files; | 315 return _files; |
133 } | 316 } |
134 | 317 |
135 /// Get the singleton DirectoryProxy for the root directory. | 318 /// Get the singleton DirectoryProxy for the root directory. |
136 Future<DirectoryProxy> _getRootDirectory() async { | 319 Future<_DirectoryProxy> _getRootDirectory() async { |
137 if (_rootDirectory != null) { | 320 if (_rootDirectory != null) { |
138 return _rootDirectory; | 321 return _rootDirectory; |
139 } | 322 } |
140 FilesProxy files = _getFiles(); | 323 _FilesProxy files = _getFiles(); |
141 assert(files != null); | 324 assert(files != null); |
142 _rootDirectory = new DirectoryProxy.unbound(); | 325 _rootDirectory = new _DirectoryProxy.unbound(); |
143 var response = | 326 var response = |
144 await files.openFileSystem(fileSystemName, _rootDirectory); | 327 await files.openFileSystem(fileSystemName, _rootDirectory.proxy); |
145 // Remove the root directory's handle from the open set because it is not | 328 // Remove the root directory's handle from the open set because it is not |
146 // under application control and does not affect isolate shutdown. | 329 // under application control and does not affect isolate shutdown. |
147 _rootDirectory.ctrl.endpoint.handle.pass(); | 330 _rootDirectory.proxy.ctrl.endpoint.handle.pass(); |
148 | 331 |
149 // Ensure system temporary directory exists before returning the root | 332 // Ensure system temporary directory exists before returning the root |
150 // directory. | 333 // directory. |
151 await _getSystemTempDirectory(); | 334 await _getSystemTempDirectory(); |
152 return _rootDirectory; | 335 return _rootDirectory; |
153 } | 336 } |
154 | 337 |
155 /// Get the singleton DirectoryProxy for the system temp directory. | 338 /// Get the singleton DirectoryProxy for the system temp directory. |
156 Future<DirectoryProxy> _getSystemTempDirectory() async { | 339 Future<_DirectoryProxy> _getSystemTempDirectory() async { |
157 if (_systemTempDirectory != null) { | 340 if (_systemTempDirectory != null) { |
158 return _systempTempDirectory; | 341 return _systempTempDirectory; |
159 } | 342 } |
160 DirectoryProxy rootDirectory = await _getRootDirectory(); | 343 _DirectoryProxy rootDirectory = await _getRootDirectory(); |
161 int flags = types.kOpenFlagRead | | 344 int flags = types.kOpenFlagRead | |
162 types.kOpenFlagWrite | | 345 types.kOpenFlagWrite | |
163 types.kOpenFlagCreate; | 346 types.kOpenFlagCreate; |
164 _systemTempDirectory = new DirectoryProxy.unbound(); | 347 _systemTempDirectory = new _DirectoryProxy.unbound(); |
165 var response = | 348 var response = |
166 await rootDirectory.openDirectory(systemTempPath, | 349 await rootDirectory.openDirectory(systemTempPath, |
167 _systemTempDirectory, | 350 _systemTempDirectory.proxy, |
168 flags); | 351 flags); |
169 assert(response.error == types.Error.ok); | 352 assert(response.error == types.Error.ok); |
170 // Remove the system temp directory's handle from the open set because it | 353 // Remove the system temp directory's handle from the open set because it |
171 // is not under application control and does not affect isolate shutdown. | 354 // is not under application control and does not affect isolate shutdown. |
172 _systemTempDirectory.ctrl.endpoint.handle.pass(); | 355 _systemTempDirectory.proxy.ctrl.endpoint.handle.pass(); |
173 return _systemTempDirectory; | 356 return _systemTempDirectory; |
174 } | 357 } |
175 | 358 |
176 /// Static utility methods for converting between 'dart:io' and | 359 /// Static utility methods for converting between 'dart:io' and |
177 /// 'mojo:network_service' structs. | 360 /// 'mojo:network_service' structs. |
178 class _NetworkServiceCodec { | 361 class _NetworkServiceCodec { |
179 /// Returns a string representation of an ip address encoded in [address]. | 362 /// Returns a string representation of an ip address encoded in [address]. |
180 /// Supports both IPv4 and IPv6. | 363 /// Supports both IPv4 and IPv6. |
181 static String _addressToString(List<int> address) { | 364 static String _addressToString(List<int> address) { |
182 String r = ''; | 365 String r = ''; |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 } | 477 } |
295 | 478 |
296 static _throwOnError(NetworkError error) { | 479 static _throwOnError(NetworkError error) { |
297 if (_okay(error)) { | 480 if (_okay(error)) { |
298 return; | 481 return; |
299 } | 482 } |
300 throw new OSError(error.description, error.code); | 483 throw new OSError(error.description, error.code); |
301 } | 484 } |
302 } | 485 } |
303 | 486 |
OLD | NEW |