• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 package org.chromium.mojo.bindings;
6 
7 import android.support.test.filters.SmallTest;
8 
9 import org.junit.After;
10 import org.junit.Assert;
11 import org.junit.Rule;
12 import org.junit.Test;
13 import org.junit.runner.RunWith;
14 
15 import org.chromium.base.test.BaseJUnit4ClassRunner;
16 import org.chromium.mojo.MojoTestRule;
17 import org.chromium.mojo.bindings.BindingsTestUtils.CapturingErrorHandler;
18 import org.chromium.mojo.bindings.test.mojom.imported.ImportedInterface;
19 import org.chromium.mojo.bindings.test.mojom.sample.Factory;
20 import org.chromium.mojo.bindings.test.mojom.sample.NamedObject;
21 import org.chromium.mojo.bindings.test.mojom.sample.NamedObject.GetNameResponse;
22 import org.chromium.mojo.bindings.test.mojom.sample.Request;
23 import org.chromium.mojo.bindings.test.mojom.sample.Response;
24 import org.chromium.mojo.system.DataPipe.ConsumerHandle;
25 import org.chromium.mojo.system.MessagePipeHandle;
26 import org.chromium.mojo.system.Pair;
27 import org.chromium.mojo.system.impl.CoreImpl;
28 
29 import java.io.Closeable;
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.List;
33 
34 /**
35  * Tests for interfaces / proxies / stubs generated for sample_factory.mojom.
36  */
37 @RunWith(BaseJUnit4ClassRunner.class)
38 public class InterfacesTest {
39     @Rule
40     public MojoTestRule mTestRule = new MojoTestRule();
41 
42     private static final String OBJECT_NAME = "hello world";
43 
44     private final List<Closeable> mCloseablesToClose = new ArrayList<Closeable>();
45 
46     /**
47      * Basic implementation of {@link NamedObject}.
48      */
49     public static class MockNamedObjectImpl extends CapturingErrorHandler implements NamedObject {
50         private String mName = "";
51 
52         /**
53          * @see org.chromium.mojo.bindings.Interface#close()
54          */
55         @Override
close()56         public void close() {}
57 
58         @Override
setName(String name)59         public void setName(String name) {
60             mName = name;
61         }
62 
63         @Override
getName(GetNameResponse callback)64         public void getName(GetNameResponse callback) {
65             callback.call(mName);
66         }
67 
getNameSynchronously()68         public String getNameSynchronously() {
69             return mName;
70         }
71     }
72 
73     /**
74      * Implementation of {@link GetNameResponse} keeping track of usage.
75      */
76     public static class RecordingGetNameResponse implements GetNameResponse {
77         private String mName;
78         private boolean mCalled;
79 
RecordingGetNameResponse()80         public RecordingGetNameResponse() {
81             reset();
82         }
83 
84         @Override
call(String name)85         public void call(String name) {
86             mName = name;
87             mCalled = true;
88         }
89 
getName()90         public String getName() {
91             return mName;
92         }
93 
wasCalled()94         public boolean wasCalled() {
95             return mCalled;
96         }
97 
reset()98         public void reset() {
99             mName = null;
100             mCalled = false;
101         }
102     }
103 
104     /**
105      * Basic implementation of {@link Factory}.
106      */
107     public class MockFactoryImpl extends CapturingErrorHandler implements Factory {
108         private boolean mClosed = false;
109 
isClosed()110         public boolean isClosed() {
111             return mClosed;
112         }
113 
114         /**
115          * @see org.chromium.mojo.bindings.Interface#close()
116          */
117         @Override
close()118         public void close() {
119             mClosed = true;
120         }
121 
122         @Override
doStuff(Request request, MessagePipeHandle pipe, DoStuffResponse callback)123         public void doStuff(Request request, MessagePipeHandle pipe, DoStuffResponse callback) {
124             if (pipe != null) {
125                 pipe.close();
126             }
127             Response response = new Response();
128             response.x = 42;
129             callback.call(response, "Hello");
130         }
131 
132         @Override
doStuff2(ConsumerHandle pipe, DoStuff2Response callback)133         public void doStuff2(ConsumerHandle pipe, DoStuff2Response callback) {
134             callback.call("World");
135         }
136 
137         @Override
createNamedObject(InterfaceRequest<NamedObject> obj)138         public void createNamedObject(InterfaceRequest<NamedObject> obj) {
139             NamedObject.MANAGER.bind(new MockNamedObjectImpl(), obj);
140         }
141 
142         @Override
requestImportedInterface(InterfaceRequest<ImportedInterface> obj, RequestImportedInterfaceResponse callback)143         public void requestImportedInterface(InterfaceRequest<ImportedInterface> obj,
144                 RequestImportedInterfaceResponse callback) {
145             throw new UnsupportedOperationException("Not implemented.");
146         }
147 
148         @Override
takeImportedInterface( ImportedInterface obj, TakeImportedInterfaceResponse callback)149         public void takeImportedInterface(
150                 ImportedInterface obj, TakeImportedInterfaceResponse callback) {
151             throw new UnsupportedOperationException("Not implemented.");
152         }
153     }
154 
155     /**
156      * Implementation of DoStuffResponse that keeps track of if the response is called.
157      */
158     public static class DoStuffResponseImpl implements Factory.DoStuffResponse {
159         private boolean mResponseCalled = false;
160 
wasResponseCalled()161         public boolean wasResponseCalled() {
162             return mResponseCalled;
163         }
164 
165         @Override
call(Response response, String string)166         public void call(Response response, String string) {
167             mResponseCalled = true;
168         }
169     }
170 
171     /**
172      * @see MojoTestCase#tearDown()
173      */
174     @After
tearDown()175     public void tearDown() throws Exception {
176         // Close the elements in the reverse order they were added. This is needed because it is an
177         // error to close the handle of a proxy without closing the proxy first.
178         Collections.reverse(mCloseablesToClose);
179         for (Closeable c : mCloseablesToClose) {
180             c.close();
181         }
182     }
183 
184     /**
185      * Check that the given proxy receives the calls. If |impl| is not null, also check that the
186      * calls are forwared to |impl|.
187      */
checkProxy(NamedObject.Proxy proxy, MockNamedObjectImpl impl)188     private void checkProxy(NamedObject.Proxy proxy, MockNamedObjectImpl impl) {
189         RecordingGetNameResponse callback = new RecordingGetNameResponse();
190         CapturingErrorHandler errorHandler = new CapturingErrorHandler();
191         proxy.getProxyHandler().setErrorHandler(errorHandler);
192 
193         if (impl != null) {
194             Assert.assertNull(impl.getLastMojoException());
195             Assert.assertEquals("", impl.getNameSynchronously());
196         }
197 
198         proxy.getName(callback);
199         mTestRule.runLoopUntilIdle();
200 
201         Assert.assertNull(errorHandler.getLastMojoException());
202         Assert.assertTrue(callback.wasCalled());
203         Assert.assertEquals("", callback.getName());
204 
205         callback.reset();
206         proxy.setName(OBJECT_NAME);
207         mTestRule.runLoopUntilIdle();
208 
209         Assert.assertNull(errorHandler.getLastMojoException());
210         if (impl != null) {
211             Assert.assertNull(impl.getLastMojoException());
212             Assert.assertEquals(OBJECT_NAME, impl.getNameSynchronously());
213         }
214 
215         proxy.getName(callback);
216         mTestRule.runLoopUntilIdle();
217 
218         Assert.assertNull(errorHandler.getLastMojoException());
219         Assert.assertTrue(callback.wasCalled());
220         Assert.assertEquals(OBJECT_NAME, callback.getName());
221     }
222 
223     @Test
224     @SmallTest
testName()225     public void testName() {
226         Assert.assertEquals("sample.NamedObject", NamedObject.MANAGER.getName());
227     }
228 
229     @Test
230     @SmallTest
testProxyAndStub()231     public void testProxyAndStub() {
232         MockNamedObjectImpl impl = new MockNamedObjectImpl();
233         NamedObject.Proxy proxy =
234                 NamedObject.MANAGER.buildProxy(null, NamedObject.MANAGER.buildStub(null, impl));
235 
236         checkProxy(proxy, impl);
237     }
238 
239     @Test
240     @SmallTest
testProxyAndStubOverPipe()241     public void testProxyAndStubOverPipe() {
242         MockNamedObjectImpl impl = new MockNamedObjectImpl();
243         NamedObject.Proxy proxy =
244                 BindingsTestUtils.newProxyOverPipe(NamedObject.MANAGER, impl, mCloseablesToClose);
245 
246         checkProxy(proxy, impl);
247     }
248 
249     @Test
250     @SmallTest
testFactoryOverPipe()251     public void testFactoryOverPipe() {
252         Factory.Proxy proxy = BindingsTestUtils.newProxyOverPipe(
253                 Factory.MANAGER, new MockFactoryImpl(), mCloseablesToClose);
254         Pair<NamedObject.Proxy, InterfaceRequest<NamedObject>> request =
255                 NamedObject.MANAGER.getInterfaceRequest(CoreImpl.getInstance());
256         mCloseablesToClose.add(request.first);
257         proxy.createNamedObject(request.second);
258 
259         checkProxy(request.first, null);
260     }
261 
262     @Test
263     @SmallTest
testInterfaceClosing()264     public void testInterfaceClosing() {
265         MockFactoryImpl impl = new MockFactoryImpl();
266         Factory.Proxy proxy =
267                 BindingsTestUtils.newProxyOverPipe(Factory.MANAGER, impl, mCloseablesToClose);
268 
269         Assert.assertFalse(impl.isClosed());
270 
271         proxy.close();
272         mTestRule.runLoopUntilIdle();
273 
274         Assert.assertTrue(impl.isClosed());
275     }
276 
277     @Test
278     @SmallTest
testResponse()279     public void testResponse() {
280         MockFactoryImpl impl = new MockFactoryImpl();
281         Factory.Proxy proxy =
282                 BindingsTestUtils.newProxyOverPipe(Factory.MANAGER, impl, mCloseablesToClose);
283         Request request = new Request();
284         request.x = 42;
285         Pair<MessagePipeHandle, MessagePipeHandle> handles =
286                 CoreImpl.getInstance().createMessagePipe(null);
287         DoStuffResponseImpl response = new DoStuffResponseImpl();
288         proxy.doStuff(request, handles.first, response);
289 
290         Assert.assertFalse(response.wasResponseCalled());
291 
292         mTestRule.runLoopUntilIdle();
293 
294         Assert.assertTrue(response.wasResponseCalled());
295     }
296 }
297