OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "ios/web/webui/mojo_facade.h" | 5 #import "ios/web/webui/mojo_facade.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/sys_string_conversions.h" | 10 #include "base/strings/sys_string_conversions.h" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
58 evaluator_ = | 58 evaluator_ = |
59 [OCMockObject mockForProtocol:@protocol(CRWJSInjectionEvaluator)]; | 59 [OCMockObject mockForProtocol:@protocol(CRWJSInjectionEvaluator)]; |
60 facade_ = base::MakeUnique<MojoFacade>( | 60 facade_ = base::MakeUnique<MojoFacade>( |
61 interface_provider_.get(), | 61 interface_provider_.get(), |
62 static_cast<id<CRWJSInjectionEvaluator>>(evaluator_)); | 62 static_cast<id<CRWJSInjectionEvaluator>>(evaluator_)); |
63 } | 63 } |
64 | 64 |
65 OCMockObject* evaluator() { return evaluator_; } | 65 OCMockObject* evaluator() { return evaluator_; } |
66 MojoFacade* facade() { return facade_.get(); } | 66 MojoFacade* facade() { return facade_.get(); } |
67 | 67 |
68 void CreateMessagePipe(uint32_t* handle0, uint32_t* handle1) { | |
69 NSDictionary* create = @{ | |
70 @"name" : @"Mojo.createMessagePipe", | |
71 @"args" : @{}, | |
72 }; | |
73 std::string response_as_string = | |
74 facade()->HandleMojoMessage(GetJson(create)); | |
75 | |
76 // Verify handles. | |
77 ASSERT_FALSE(response_as_string.empty()); | |
78 NSDictionary* response_as_dict = GetObject(response_as_string); | |
79 ASSERT_TRUE([response_as_dict isKindOfClass:[NSDictionary class]]); | |
80 ASSERT_EQ(MOJO_RESULT_OK, [response_as_dict[@"result"] unsignedIntValue]); | |
81 *handle0 = [response_as_dict[@"handle0"] unsignedIntValue]; | |
82 *handle1 = [response_as_dict[@"handle1"] unsignedIntValue]; | |
83 } | |
84 | |
85 void CloseHandle(uint32_t handle) { | |
86 NSDictionary* close = @{ | |
87 @"name" : @"MojoHandle.close", | |
88 @"args" : @{ | |
89 @"handle" : @(handle), | |
90 }, | |
91 }; | |
92 std::string result = facade()->HandleMojoMessage(GetJson(close)); | |
93 EXPECT_TRUE(result.empty()); | |
94 } | |
95 | |
68 private: | 96 private: |
69 void BindTestUIHandlerMojoRequest( | 97 void BindTestUIHandlerMojoRequest( |
70 const service_manager::BindSourceInfo& source_info, | 98 const service_manager::BindSourceInfo& source_info, |
71 TestUIHandlerMojoRequest request) {} | 99 TestUIHandlerMojoRequest request) {} |
72 | 100 |
73 std::unique_ptr<WebStateInterfaceProvider> interface_provider_; | 101 std::unique_ptr<WebStateInterfaceProvider> interface_provider_; |
74 OCMockObject* evaluator_; | 102 OCMockObject* evaluator_; |
75 std::unique_ptr<MojoFacade> facade_; | 103 std::unique_ptr<MojoFacade> facade_; |
76 }; | 104 }; |
77 | 105 |
78 // Tests connecting to existing interface and closing the handle. | 106 // Tests binding an interface. |
79 TEST_F(MojoFacadeTest, GetInterfaceAndCloseHandle) { | 107 TEST_F(MojoFacadeTest, BindInterface) { |
80 // Bind to the interface. | 108 uint32_t handle0, handle1; |
Eugene But (OOO till 7-30)
2017/06/24 01:09:51
nit: Per Style Guide, please initialize local vari
yzshen1
2017/06/26 20:09:59
Done.
| |
109 CreateMessagePipe(&handle0, &handle1); | |
110 | |
111 // Pass handle0 as interface request. | |
81 NSDictionary* connect = @{ | 112 NSDictionary* connect = @{ |
82 @"name" : @"interface_provider.getInterface", | 113 @"name" : @"Mojo.bindInterface", |
83 @"args" : @{ | 114 @"args" : @{ |
84 @"interfaceName" : @"::TestUIHandlerMojo", | 115 @"interfaceName" : @"::TestUIHandlerMojo", |
116 @"requestHandle" : @(handle0), | |
85 }, | 117 }, |
86 }; | 118 }; |
87 | 119 |
88 std::string handle_as_string = facade()->HandleMojoMessage(GetJson(connect)); | 120 std::string handle_as_string = facade()->HandleMojoMessage(GetJson(connect)); |
89 EXPECT_FALSE(handle_as_string.empty()); | 121 EXPECT_TRUE(handle_as_string.empty()); |
90 int handle = 0; | |
91 EXPECT_TRUE(base::StringToInt(handle_as_string, &handle)); | |
92 | 122 |
93 // Close the handle. | 123 CloseHandle(handle1); |
94 NSDictionary* close = @{ | |
95 @"name" : @"core.close", | |
96 @"args" : @{ | |
97 @"handle" : @(handle), | |
98 }, | |
99 }; | |
100 std::string result_as_string = facade()->HandleMojoMessage(GetJson(close)); | |
101 EXPECT_FALSE(result_as_string.empty()); | |
102 int result = 0; | |
103 EXPECT_TRUE(base::StringToInt(result_as_string, &result)); | |
104 EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result)); | |
105 } | 124 } |
106 | 125 |
107 // Tests creating a message pipe without options. | 126 // Tests creating a message pipe. |
108 TEST_F(MojoFacadeTest, CreateMessagePipeWithoutOptions) { | 127 TEST_F(MojoFacadeTest, CreateMessagePipe) { |
109 // Create a message pipe. | 128 uint32_t handle0, handle1; |
110 NSDictionary* create = @{ | 129 CreateMessagePipe(&handle0, &handle1); |
111 @"name" : @"core.createMessagePipe", | |
112 @"args" : @{ | |
113 @"optionsDict" : [NSNull null], | |
114 }, | |
115 }; | |
116 std::string response_as_string = facade()->HandleMojoMessage(GetJson(create)); | |
117 | 130 |
118 // Verify handles. | 131 CloseHandle(handle0); |
119 EXPECT_FALSE(response_as_string.empty()); | 132 CloseHandle(handle1); |
120 NSDictionary* response_as_dict = GetObject(response_as_string); | |
121 EXPECT_TRUE([response_as_dict isKindOfClass:[NSDictionary class]]); | |
122 id handle0 = response_as_dict[@"handle0"]; | |
123 EXPECT_TRUE(handle0); | |
124 id handle1 = response_as_dict[@"handle1"]; | |
125 EXPECT_TRUE(handle1); | |
126 | |
127 // Close handle0. | |
128 NSDictionary* close0 = @{ | |
129 @"name" : @"core.close", | |
130 @"args" : @{ | |
131 @"handle" : handle0, | |
132 }, | |
133 }; | |
134 std::string result0_as_string = facade()->HandleMojoMessage(GetJson(close0)); | |
135 EXPECT_FALSE(result0_as_string.empty()); | |
136 int result0 = 0; | |
137 EXPECT_TRUE(base::StringToInt(result0_as_string, &result0)); | |
138 EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result0)); | |
139 | |
140 // Close handle1. | |
141 NSDictionary* close1 = @{ | |
142 @"name" : @"core.close", | |
143 @"args" : @{ | |
144 @"handle" : handle1, | |
145 }, | |
146 }; | |
147 std::string result1_as_string = facade()->HandleMojoMessage(GetJson(close1)); | |
148 EXPECT_FALSE(result1_as_string.empty()); | |
149 int result1 = 0; | |
150 EXPECT_TRUE(base::StringToInt(result1_as_string, &result1)); | |
151 EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result1)); | |
152 } | 133 } |
153 | 134 |
154 // Tests watching the pipe. | 135 // Tests watching the pipe. |
155 TEST_F(MojoFacadeTest, Watch) { | 136 TEST_F(MojoFacadeTest, Watch) { |
156 // Create a message pipe. | 137 uint32_t handle0, handle1; |
157 NSDictionary* create = @{ | 138 CreateMessagePipe(&handle0, &handle1); |
158 @"name" : @"core.createMessagePipe", | |
159 @"args" : @{ | |
160 @"optionsDict" : [NSNull null], | |
161 }, | |
162 }; | |
163 std::string response_as_string = facade()->HandleMojoMessage(GetJson(create)); | |
164 | |
165 // Verify handles. | |
166 EXPECT_FALSE(response_as_string.empty()); | |
167 NSDictionary* response_as_dict = GetObject(response_as_string); | |
168 EXPECT_TRUE([response_as_dict isKindOfClass:[NSDictionary class]]); | |
169 id handle0 = response_as_dict[@"handle0"]; | |
170 EXPECT_TRUE(handle0); | |
171 id handle1 = response_as_dict[@"handle1"]; | |
172 EXPECT_TRUE(handle1); | |
173 | 139 |
174 // Start watching one end of the pipe. | 140 // Start watching one end of the pipe. |
175 int callback_id = 99; | 141 int callback_id = 99; |
176 NSDictionary* watch = @{ | 142 NSDictionary* watch = @{ |
177 @"name" : @"support.watch", | 143 @"name" : @"MojoHandle.watch", |
178 @"args" : @{ | 144 @"args" : @{ |
179 @"handle" : handle0, | 145 @"handle" : @(handle0), |
180 @"signals" : @(MOJO_HANDLE_SIGNAL_READABLE), | 146 @"signals" : @(MOJO_HANDLE_SIGNAL_READABLE), |
181 @"callbackId" : @(callback_id), | 147 @"callbackId" : @(callback_id), |
182 }, | 148 }, |
183 }; | 149 }; |
184 std::string watch_id_as_string = facade()->HandleMojoMessage(GetJson(watch)); | 150 std::string watch_id_as_string = facade()->HandleMojoMessage(GetJson(watch)); |
185 EXPECT_FALSE(watch_id_as_string.empty()); | 151 EXPECT_FALSE(watch_id_as_string.empty()); |
186 int watch_id = 0; | 152 int watch_id = 0; |
187 EXPECT_TRUE(base::StringToInt(watch_id_as_string, &watch_id)); | 153 EXPECT_TRUE(base::StringToInt(watch_id_as_string, &watch_id)); |
188 | 154 |
189 // Start waiting for the watch callback. | 155 // Start waiting for the watch callback. |
190 __block bool callback_received = false; | 156 __block bool callback_received = false; |
191 NSString* expected_script = | 157 NSString* expected_script = |
192 [NSString stringWithFormat:@"__crWeb.mojo.signalWatch(%d, %d)", | 158 [NSString stringWithFormat: |
193 callback_id, MOJO_RESULT_OK]; | 159 @"Mojo.internal.watchCallbacksHolder.callCallback(%d, %d)", |
160 callback_id, MOJO_RESULT_OK]; | |
194 [[[evaluator() expect] andDo:^(NSInvocation*) { | 161 [[[evaluator() expect] andDo:^(NSInvocation*) { |
195 callback_received = true; | 162 callback_received = true; |
196 | 163 |
197 // Cancel the watch immediately to ensure there are no additional | 164 // Cancel the watch immediately to ensure there are no additional |
198 // notifications. | 165 // notifications. |
199 NSDictionary* cancel_watch = @{ | 166 NSDictionary* cancel_watch = @{ |
200 @"name" : @"support.cancelWatch", | 167 @"name" : @"MojoWatcher.cancel", |
201 @"args" : @{ | 168 @"args" : @{ |
202 @"watchId" : @(watch_id), | 169 @"watchId" : @(watch_id), |
203 }, | 170 }, |
204 }; | 171 }; |
205 std::string result_as_string = | 172 std::string result_as_string = |
206 facade()->HandleMojoMessage(GetJson(cancel_watch)); | 173 facade()->HandleMojoMessage(GetJson(cancel_watch)); |
207 EXPECT_TRUE(result_as_string.empty()); | 174 EXPECT_TRUE(result_as_string.empty()); |
208 }] executeJavaScript:expected_script completionHandler:nil]; | 175 }] executeJavaScript:expected_script completionHandler:nil]; |
209 | 176 |
210 // Write to the other end of the pipe. | 177 // Write to the other end of the pipe. |
211 NSDictionary* write = @{ | 178 NSDictionary* write = @{ |
212 @"name" : @"core.writeMessage", | 179 @"name" : @"MojoHandle.writeMessage", |
213 @"args" : @{ | 180 @"args" : |
214 @"handle" : handle1, | 181 @{@"handle" : @(handle1), @"handles" : @[], @"buffer" : @{@"0" : @0}}, |
215 @"handles" : @[], | |
216 @"flags" : @(MOJO_WRITE_MESSAGE_FLAG_NONE), | |
217 @"buffer" : @{@"0" : @0} | |
218 }, | |
219 }; | 182 }; |
220 std::string result_as_string = facade()->HandleMojoMessage(GetJson(write)); | 183 std::string result_as_string = facade()->HandleMojoMessage(GetJson(write)); |
221 EXPECT_FALSE(result_as_string.empty()); | 184 EXPECT_FALSE(result_as_string.empty()); |
222 int result = 0; | 185 int result = 0; |
223 EXPECT_TRUE(base::StringToInt(result_as_string, &result)); | 186 EXPECT_TRUE(base::StringToInt(result_as_string, &result)); |
224 EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result)); | 187 EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result)); |
225 | 188 |
226 base::test::ios::WaitUntilCondition( | 189 base::test::ios::WaitUntilCondition( |
227 ^{ | 190 ^{ |
228 return callback_received; | 191 return callback_received; |
229 }, | 192 }, |
230 true, base::TimeDelta()); | 193 true, base::TimeDelta()); |
194 | |
195 CloseHandle(handle0); | |
196 CloseHandle(handle1); | |
231 } | 197 } |
232 | 198 |
233 // Tests reading the message from the pipe. | 199 // Tests reading the message from the pipe. |
234 TEST_F(MojoFacadeTest, ReadWrite) { | 200 TEST_F(MojoFacadeTest, ReadWrite) { |
235 // Create a message pipe. | 201 uint32_t handle0, handle1; |
236 NSDictionary* create = @{ | 202 CreateMessagePipe(&handle0, &handle1); |
237 @"name" : @"core.createMessagePipe", | |
238 @"args" : @{ | |
239 @"optionsDict" : [NSNull null], | |
240 }, | |
241 }; | |
242 std::string response_as_string = facade()->HandleMojoMessage(GetJson(create)); | |
243 | |
244 // Verify handles. | |
245 EXPECT_FALSE(response_as_string.empty()); | |
246 NSDictionary* response_as_dict = GetObject(response_as_string); | |
247 EXPECT_TRUE([response_as_dict isKindOfClass:[NSDictionary class]]); | |
248 id handle0 = response_as_dict[@"handle0"]; | |
249 EXPECT_TRUE(handle0); | |
250 id handle1 = response_as_dict[@"handle1"]; | |
251 EXPECT_TRUE(handle1); | |
252 | 203 |
253 // Write to the other end of the pipe. | 204 // Write to the other end of the pipe. |
254 NSDictionary* write = @{ | 205 NSDictionary* write = @{ |
255 @"name" : @"core.writeMessage", | 206 @"name" : @"MojoHandle.writeMessage", |
256 @"args" : @{ | 207 @"args" : @{ |
257 @"handle" : handle1, | 208 @"handle" : @(handle1), |
258 @"handles" : @[], | 209 @"handles" : @[], |
259 @"flags" : @(MOJO_WRITE_MESSAGE_FLAG_NONE), | |
260 @"buffer" : @{@"0" : @9, @"1" : @2, @"2" : @2008} | 210 @"buffer" : @{@"0" : @9, @"1" : @2, @"2" : @2008} |
261 }, | 211 }, |
262 }; | 212 }; |
263 std::string result_as_string = facade()->HandleMojoMessage(GetJson(write)); | 213 std::string result_as_string = facade()->HandleMojoMessage(GetJson(write)); |
264 EXPECT_FALSE(result_as_string.empty()); | 214 EXPECT_FALSE(result_as_string.empty()); |
265 int result = 0; | 215 int result = 0; |
266 EXPECT_TRUE(base::StringToInt(result_as_string, &result)); | 216 EXPECT_TRUE(base::StringToInt(result_as_string, &result)); |
267 EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result)); | 217 EXPECT_EQ(MOJO_RESULT_OK, static_cast<MojoResult>(result)); |
268 | 218 |
269 // Read the message from the pipe. | 219 // Read the message from the pipe. |
270 NSDictionary* read = @{ | 220 NSDictionary* read = @{ |
271 @"name" : @"core.readMessage", | 221 @"name" : @"MojoHandle.readMessage", |
272 @"args" : @{ | 222 @"args" : @{ |
273 @"handle" : handle0, | 223 @"handle" : @(handle0), |
274 @"flags" : @(MOJO_READ_MESSAGE_FLAG_NONE), | |
275 }, | 224 }, |
276 }; | 225 }; |
277 NSDictionary* message = GetObject(facade()->HandleMojoMessage(GetJson(read))); | 226 NSDictionary* message = GetObject(facade()->HandleMojoMessage(GetJson(read))); |
278 EXPECT_TRUE([message isKindOfClass:[NSDictionary class]]); | 227 EXPECT_TRUE([message isKindOfClass:[NSDictionary class]]); |
279 EXPECT_TRUE(message); | 228 EXPECT_TRUE(message); |
280 NSArray* expected_message = @[ @9, @2, @216 ]; // 2008 does not fit 8-bit. | 229 NSArray* expected_message = @[ @9, @2, @216 ]; // 2008 does not fit 8-bit. |
281 EXPECT_NSEQ(expected_message, message[@"buffer"]); | 230 EXPECT_NSEQ(expected_message, message[@"buffer"]); |
282 EXPECT_FALSE([message[@"handles"] count]); | 231 EXPECT_FALSE([message[@"handles"] count]); |
283 EXPECT_EQ(MOJO_RESULT_OK, [message[@"result"] unsignedIntValue]); | 232 EXPECT_EQ(MOJO_RESULT_OK, [message[@"result"] unsignedIntValue]); |
233 | |
234 CloseHandle(handle0); | |
235 CloseHandle(handle1); | |
284 } | 236 } |
285 | 237 |
286 } // namespace web | 238 } // namespace web |
OLD | NEW |