Index: mojo/android/javatests/src/org/chromium/mojo/bindings/InterfacesTest.java |
diff --git a/mojo/android/javatests/src/org/chromium/mojo/bindings/InterfacesTest.java b/mojo/android/javatests/src/org/chromium/mojo/bindings/InterfacesTest.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..79f74723b9a2baba672f55df4e63c33da71f67aa |
--- /dev/null |
+++ b/mojo/android/javatests/src/org/chromium/mojo/bindings/InterfacesTest.java |
@@ -0,0 +1,230 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.mojo.bindings; |
+ |
+import android.test.suitebuilder.annotation.SmallTest; |
+ |
+import org.chromium.mojo.MojoTestCase; |
+import org.chromium.mojo.bindings.BindingsTestUtils.CapturingErrorHandler; |
+import org.chromium.mojo.bindings.test.mojom.imported.ImportedInterface; |
+import org.chromium.mojo.bindings.test.mojom.sample.Factory; |
+import org.chromium.mojo.bindings.test.mojom.sample.FactoryClient; |
+import org.chromium.mojo.bindings.test.mojom.sample.NamedObject; |
+import org.chromium.mojo.bindings.test.mojom.sample.NamedObject.GetNameResponse; |
+import org.chromium.mojo.bindings.test.mojom.sample.Request; |
+import org.chromium.mojo.system.DataPipe.ConsumerHandle; |
+import org.chromium.mojo.system.MessagePipeHandle; |
+import org.chromium.mojo.system.Pair; |
+import org.chromium.mojo.system.impl.CoreImpl; |
+ |
+import java.io.Closeable; |
+import java.util.ArrayList; |
+import java.util.Collections; |
+import java.util.List; |
+ |
+/** |
+ * Tests for interfaces / proxies / stubs generated for sample_factory.mojom. |
+ */ |
+public class InterfacesTest extends MojoTestCase { |
+ |
+ private static final long RUN_LOOP_TIMEOUT_MS = 25; |
+ |
+ private final List<Closeable> mCloseablesToClose = new ArrayList<Closeable>(); |
+ |
+ /** |
+ * Basic implementation of {@link NamedObject}. |
+ */ |
+ public static class MockNamedObjectImpl extends CapturingErrorHandler implements NamedObject { |
+ |
+ private String mName; |
+ |
+ @Override |
+ public void setName(String name) { |
+ mName = name; |
+ } |
+ |
+ @Override |
+ public void getName(GetNameResponse callback) { |
+ callback.call(mName); |
+ } |
+ |
+ public String getNameSynchronously() { |
+ return mName; |
+ } |
+ } |
+ |
+ /** |
+ * Implementation of {@link GetNameResponse} keeping track of usage. |
+ */ |
+ public static class RecordingGetNameResponse implements GetNameResponse { |
+ private String mName; |
+ private boolean mCalled; |
+ |
+ public RecordingGetNameResponse() { |
+ reset(); |
+ } |
+ |
+ @Override |
+ public void call(String name) { |
+ mName = name; |
+ mCalled = true; |
+ } |
+ |
+ public String getName() { |
+ return mName; |
+ } |
+ |
+ public boolean wasCalled() { |
+ return mCalled; |
+ } |
+ |
+ public void reset() { |
+ mName = null; |
+ mCalled = false; |
+ } |
+ } |
+ |
+ /** |
+ * Basic implementation of {@link Factory}. |
+ */ |
+ public class MockFactoryImpl extends CapturingErrorHandler implements Factory { |
+ |
+ @Override |
+ public void setClient(FactoryClient client) { |
+ if (client instanceof Closeable) { |
+ mCloseablesToClose.add((Closeable) client); |
+ } |
+ } |
+ |
+ @Override |
+ public void doStuff(Request request, MessagePipeHandle pipe) { |
+ throw new UnsupportedOperationException("Not implemented."); |
+ } |
+ |
+ @Override |
+ public void doStuff2(ConsumerHandle pipe) { |
+ throw new UnsupportedOperationException("Not implemented."); |
+ } |
+ |
+ @Override |
+ public void createNamedObject(InterfaceRequest<NamedObject> obj) { |
+ NamedObject.MANAGER.bind(new MockNamedObjectImpl(), obj); |
+ } |
+ |
+ @Override |
+ public void requestImportedInterface(InterfaceRequest<ImportedInterface> obj, |
+ RequestImportedInterfaceResponse callback) { |
+ throw new UnsupportedOperationException("Not implemented."); |
+ } |
+ |
+ @Override |
+ public void takeImportedInterface(ImportedInterface obj, |
+ TakeImportedInterfaceResponse callback) { |
+ throw new UnsupportedOperationException("Not implemented."); |
+ } |
+ } |
+ |
+ /** |
+ * @see org.chromium.mojo.MojoTestCase#tearDown() |
+ */ |
+ @Override |
+ protected void tearDown() throws Exception { |
+ // Close the elements in the reverse order they were added. This is needed because it is an |
+ // error to close the handle of a proxy without closing the proxy first. |
+ Collections.reverse(mCloseablesToClose); |
+ for (Closeable c : mCloseablesToClose) { |
+ c.close(); |
+ } |
+ } |
+ |
+ private void addCloseables(Pair<? extends Closeable, ? extends Closeable> pair) { |
+ mCloseablesToClose.add(pair.first); |
+ mCloseablesToClose.add(pair.second); |
+ } |
+ |
+ private Pair<MessagePipeHandle, MessagePipeHandle> newHandles() { |
+ Pair<MessagePipeHandle, MessagePipeHandle> result = |
+ CoreImpl.getInstance().createMessagePipe(null); |
+ addCloseables(result); |
+ return result; |
+ } |
+ |
+ private <I extends Interface, P extends Interface.Proxy> P newProxyOverPipe( |
+ Interface.Manager<I, P> manager, I impl) { |
+ Pair<MessagePipeHandle, MessagePipeHandle> handles = newHandles(); |
+ P proxy = manager.attachProxy(handles.first); |
+ mCloseablesToClose.add(proxy); |
+ manager.bind(impl, handles.second); |
+ return proxy; |
+ } |
+ |
+ /** |
+ * Check that the given proxy receives the calls. If |impl| is not null, also check that the |
+ * calls are forwared to |impl|. |
+ */ |
+ private void checkProxy(NamedObject.Proxy proxy, MockNamedObjectImpl impl) { |
+ final String NAME = "hello world"; |
+ RecordingGetNameResponse callback = new RecordingGetNameResponse(); |
+ CapturingErrorHandler errorHandler = new CapturingErrorHandler(); |
+ proxy.setErrorHandler(errorHandler); |
+ |
+ if (impl != null) { |
+ assertNull(impl.getLastMojoException()); |
+ assertNull(impl.getNameSynchronously()); |
+ } |
+ |
+ proxy.getName(callback); |
+ nativeRunLoop(RUN_LOOP_TIMEOUT_MS); |
+ |
+ assertNull(errorHandler.getLastMojoException()); |
+ assertTrue(callback.wasCalled()); |
+ assertNull(callback.getName()); |
+ |
+ callback.reset(); |
+ proxy.setName(NAME); |
+ nativeRunLoop(RUN_LOOP_TIMEOUT_MS); |
+ |
+ assertNull(errorHandler.getLastMojoException()); |
+ if (impl != null) { |
+ assertNull(impl.getLastMojoException()); |
+ assertEquals(NAME, impl.getNameSynchronously()); |
+ } |
+ |
+ proxy.getName(callback); |
+ nativeRunLoop(RUN_LOOP_TIMEOUT_MS); |
+ |
+ assertNull(errorHandler.getLastMojoException()); |
+ assertTrue(callback.wasCalled()); |
+ assertEquals(NAME, callback.getName()); |
+ } |
+ |
+ @SmallTest |
+ public void testProxyAndStub() { |
+ MockNamedObjectImpl impl = new MockNamedObjectImpl(); |
+ NamedObject.Proxy proxy = |
+ NamedObject.MANAGER.buildProxy(null, NamedObject.MANAGER.buildStub(null, impl)); |
+ |
+ checkProxy(proxy, impl); |
+ } |
+ |
+ @SmallTest |
+ public void testProxyAndStubOverPipe() { |
+ MockNamedObjectImpl impl = new MockNamedObjectImpl(); |
+ NamedObject.Proxy proxy = newProxyOverPipe(NamedObject.MANAGER, impl); |
+ |
+ checkProxy(proxy, impl); |
+ } |
+ |
+ @SmallTest |
+ public void testFactoryOverPipe() { |
+ Factory.Proxy proxy = newProxyOverPipe(Factory.MANAGER, new MockFactoryImpl()); |
+ Pair<NamedObject.Proxy, InterfaceRequest<NamedObject>> request = |
+ NamedObject.MANAGER.getInterfaceRequest(CoreImpl.getInstance()); |
+ addCloseables(request); |
+ proxy.createNamedObject(request.second); |
+ |
+ checkProxy(request.first, null); |
+ } |
+} |