OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 part of bindings; | 5 part of bindings; |
6 | 6 |
7 abstract class Stub extends core.MojoEventHandler { | 7 /// Generated StubControl classes implement this interface. |
| 8 /// StubControl objects are accessible through the [ctrl] field on Stubs. |
| 9 abstract class StubControl<T> implements StubMessageHandler { |
| 10 T impl; |
| 11 } |
| 12 |
| 13 /// Generated Stub classes extend this base class. |
| 14 class Stub<T> { |
| 15 // In general it's probalby better to avoid adding fields and methods to this |
| 16 // class. Names added to this class have to be mangled by Mojo bindings |
| 17 // generation to avoid name conflicts. |
| 18 |
| 19 /// Proxies control the StubMessageHandler by way of this [StubControl] |
| 20 /// object. |
| 21 final StubControl<T> ctrl; |
| 22 |
| 23 Stub(this.ctrl); |
| 24 |
| 25 /// This is a convenience method that simply forwards to ctrl.close(). |
| 26 /// If a Mojo interface has a method 'close', its name will be mangled to be |
| 27 /// 'close_'. |
| 28 Future close({bool immediate: false}) => ctrl.close(immediate: immediate); |
| 29 |
| 30 /// This getter and setter pair is for convenience and simply forwards to |
| 31 /// ctrl.impl. If a Mojo interface has a method 'close', its name will be |
| 32 /// mangled to be 'impl_'. |
| 33 T get impl => ctrl.impl; |
| 34 set impl(T impl) { |
| 35 ctrl.impl = impl; |
| 36 } |
| 37 } |
| 38 |
| 39 abstract class StubMessageHandler extends core.MojoEventHandler { |
8 int _outstandingResponseFutures = 0; | 40 int _outstandingResponseFutures = 0; |
9 bool _isClosing = false; | 41 bool _isClosing = false; |
10 Completer _closeCompleter; | 42 Completer _closeCompleter; |
11 | 43 |
12 Stub.fromEndpoint(core.MojoMessagePipeEndpoint endpoint, | 44 StubMessageHandler.fromEndpoint(core.MojoMessagePipeEndpoint endpoint, |
13 {bool autoBegin: true}) | 45 {bool autoBegin: true}) |
14 : super.fromEndpoint(endpoint, autoBegin: autoBegin); | 46 : super.fromEndpoint(endpoint, autoBegin: autoBegin); |
15 | 47 |
16 Stub.fromHandle(core.MojoHandle handle, {bool autoBegin: true}) | 48 StubMessageHandler.fromHandle(core.MojoHandle handle, {bool autoBegin: true}) |
17 : super.fromHandle(handle, autoBegin: autoBegin); | 49 : super.fromHandle(handle, autoBegin: autoBegin); |
18 | 50 |
19 Stub.unbound() : super.unbound(); | 51 StubMessageHandler.unbound() : super.unbound(); |
20 | 52 |
| 53 /// Generated StubControl classes implement this method to route messages to |
| 54 /// the correct implementation method. |
21 dynamic handleMessage(ServiceMessage message); | 55 dynamic handleMessage(ServiceMessage message); |
22 | 56 |
| 57 /// Generated StubControl classes implement this getter to return the version |
| 58 /// of the mojom interface for which the bindings are generated. |
| 59 int get version; |
| 60 |
| 61 @override |
23 void handleRead() { | 62 void handleRead() { |
24 var result = endpoint.queryAndRead(); | 63 var result = endpoint.queryAndRead(); |
25 if ((result.data == null) || (result.dataLength == 0)) { | 64 if ((result.data == null) || (result.dataLength == 0)) { |
26 throw new MojoCodecError('Unexpected empty message or error: $result'); | 65 throw new MojoCodecError('Unexpected empty message or error: $result'); |
27 } | 66 } |
28 | 67 |
29 // Prepare the response. | 68 // Prepare the response. |
30 var message; | 69 var message; |
31 var response; | 70 var response; |
32 try { | 71 try { |
(...skipping 24 matching lines...) Expand all Loading... |
57 super.close().then((_) { | 96 super.close().then((_) { |
58 if (_isClosing) { | 97 if (_isClosing) { |
59 _isClosing = false; | 98 _isClosing = false; |
60 _closeCompleter.complete(null); | 99 _closeCompleter.complete(null); |
61 _closeCompleter = null; | 100 _closeCompleter = null; |
62 } | 101 } |
63 }); | 102 }); |
64 } | 103 } |
65 } | 104 } |
66 | 105 |
67 void _sendResponse(Message response) { | 106 @override |
68 if (isOpen) { | |
69 endpoint.write( | |
70 response.buffer, response.buffer.lengthInBytes, response.handles); | |
71 // FailedPrecondition is only used to indicate that the other end of | |
72 // the pipe has been closed. We can ignore the close here and wait for | |
73 // the PeerClosed signal on the event stream. | |
74 assert((endpoint.status == core.MojoResult.kOk) || | |
75 (endpoint.status == core.MojoResult.kFailedPrecondition)); | |
76 if (_isClosing && (_outstandingResponseFutures == 0)) { | |
77 // This was the final response future for which we needed to send | |
78 // a response. It is safe to close. | |
79 super.close().then((_) { | |
80 if (_isClosing) { | |
81 _isClosing = false; | |
82 _closeCompleter.complete(null); | |
83 _closeCompleter = null; | |
84 } | |
85 }); | |
86 } | |
87 } | |
88 } | |
89 | |
90 void handleWrite() { | 107 void handleWrite() { |
91 throw 'Unexpected write signal in client.'; | 108 throw 'Unexpected write signal in client.'; |
92 } | 109 } |
93 | 110 |
94 // NB: |immediate| should only be true when calling close() while handling an | 111 // NB: |immediate| should only be true when calling close() while handling an |
95 // exception thrown from handleRead(), e.g. when we receive a malformed | 112 // exception thrown from handleRead(), e.g. when we receive a malformed |
96 // message, or when we have received the PEER_CLOSED event. | 113 // message, or when we have received the PEER_CLOSED event. |
97 @override | 114 @override |
98 Future close({bool immediate: false}) { | 115 Future close({bool immediate: false}) { |
99 if (isOpen && | 116 if (isOpen && |
(...skipping 21 matching lines...) Expand all Loading... |
121 Message buildResponse(Struct response, int name) { | 138 Message buildResponse(Struct response, int name) { |
122 var header = new MessageHeader(name); | 139 var header = new MessageHeader(name); |
123 return response.serializeWithHeader(header); | 140 return response.serializeWithHeader(header); |
124 } | 141 } |
125 | 142 |
126 Message buildResponseWithId(Struct response, int name, int id, int flags) { | 143 Message buildResponseWithId(Struct response, int name, int id, int flags) { |
127 var header = new MessageHeader.withRequestId(name, flags, id); | 144 var header = new MessageHeader.withRequestId(name, flags, id); |
128 return response.serializeWithHeader(header); | 145 return response.serializeWithHeader(header); |
129 } | 146 } |
130 | 147 |
| 148 @override |
131 String toString() { | 149 String toString() { |
132 var superString = super.toString(); | 150 var superString = super.toString(); |
133 return "Stub(${superString})"; | 151 return "StubMessageHandler(${superString})"; |
134 } | 152 } |
135 | 153 |
136 int get version; | |
137 | |
138 /// Returns a service description, which exposes the mojom type information | 154 /// Returns a service description, which exposes the mojom type information |
139 /// of the service being stubbed. | 155 /// of the service being stubbed. |
140 /// Note: The description is null or incomplete if type info is unavailable. | 156 /// Note: The description is null or incomplete if type info is unavailable. |
141 service_describer.ServiceDescription get description => null; | 157 service_describer.ServiceDescription get description => null; |
| 158 |
| 159 void _sendResponse(Message response) { |
| 160 if (isOpen) { |
| 161 endpoint.write( |
| 162 response.buffer, response.buffer.lengthInBytes, response.handles); |
| 163 // FailedPrecondition is only used to indicate that the other end of |
| 164 // the pipe has been closed. We can ignore the close here and wait for |
| 165 // the PeerClosed signal on the event stream. |
| 166 assert((endpoint.status == core.MojoResult.kOk) || |
| 167 (endpoint.status == core.MojoResult.kFailedPrecondition)); |
| 168 if (_isClosing && (_outstandingResponseFutures == 0)) { |
| 169 // This was the final response future for which we needed to send |
| 170 // a response. It is safe to close. |
| 171 super.close().then((_) { |
| 172 if (_isClosing) { |
| 173 _isClosing = false; |
| 174 _closeCompleter.complete(null); |
| 175 _closeCompleter = null; |
| 176 } |
| 177 }); |
| 178 } |
| 179 } |
| 180 } |
142 } | 181 } |
OLD | NEW |