1*635a8641SAndroid Build Coastguard WorkerFrom 225f21f660b943ff9ade13b0d114e8ba3b3036d5 Mon Sep 17 00:00:00 2001
2*635a8641SAndroid Build Coastguard WorkerFrom: Luis Hector Chavez <lhchavez@google.com>
3*635a8641SAndroid Build Coastguard WorkerDate: Fri, 20 Jul 2018 09:39:22 -0700
4*635a8641SAndroid Build Coastguard WorkerSubject: [PATCH] Mojo: Add a way to create thread-safe interfaces in Java
5*635a8641SAndroid Build Coastguard Worker
6*635a8641SAndroid Build Coastguard WorkerThis change adds Interface.Manager.buildThreadSafeProxy(), which is
7*635a8641SAndroid Build Coastguard Workerroughly analogous to mojo::ThreadSafeInterfacePtr<T>. Given that Java
8*635a8641SAndroid Build Coastguard Workerdoes not have move-only semantics, the Proxy object that is passed is
9*635a8641SAndroid Build Coastguard Workerunbound and a new object is returned.
10*635a8641SAndroid Build Coastguard Worker
11*635a8641SAndroid Build Coastguard WorkerBug: 810084
12*635a8641SAndroid Build Coastguard WorkerTest: cheets_ContainerSmokeTest in Chrome OS
13*635a8641SAndroid Build Coastguard WorkerChange-Id: I6565f9e526e3fa8f8cb222cb8cd11e95bb57f7d3
14*635a8641SAndroid Build Coastguard WorkerReviewed-on: https://chromium-review.googlesource.com/1147320
15*635a8641SAndroid Build Coastguard WorkerReviewed-by: Ken Rockot <rockot@chromium.org>
16*635a8641SAndroid Build Coastguard WorkerCommit-Queue: Luis Hector Chavez <lhchavez@chromium.org>
17*635a8641SAndroid Build Coastguard WorkerCr-Commit-Position: refs/heads/master@{#577429}
18*635a8641SAndroid Build Coastguard Worker---
19*635a8641SAndroid Build Coastguard Worker .../org/chromium/mojo/bindings/Interface.java | 88 +++++++++++++++++++
20*635a8641SAndroid Build Coastguard Worker 1 file changed, 88 insertions(+)
21*635a8641SAndroid Build Coastguard Worker
22*635a8641SAndroid Build Coastguard Workerdiff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java
23*635a8641SAndroid Build Coastguard Workerindex e3be8b3..f7d3f80 100644
24*635a8641SAndroid Build Coastguard Worker--- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java
25*635a8641SAndroid Build Coastguard Worker+++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Interface.java
26*635a8641SAndroid Build Coastguard Worker@@ -20,6 +20,7 @@ import org.chromium.mojo.system.MojoException;
27*635a8641SAndroid Build Coastguard Worker import org.chromium.mojo.system.Pair;
28*635a8641SAndroid Build Coastguard Worker
29*635a8641SAndroid Build Coastguard Worker import java.io.Closeable;
30*635a8641SAndroid Build Coastguard Worker+import java.util.concurrent.Executor;
31*635a8641SAndroid Build Coastguard Worker
32*635a8641SAndroid Build Coastguard Worker /**
33*635a8641SAndroid Build Coastguard Worker  * Base class for mojo generated interfaces.
34*635a8641SAndroid Build Coastguard Worker@@ -317,6 +318,67 @@ public interface Interface extends ConnectionErrorHandler, Closeable {
35*635a8641SAndroid Build Coastguard Worker
36*635a8641SAndroid Build Coastguard Worker     }
37*635a8641SAndroid Build Coastguard Worker
38*635a8641SAndroid Build Coastguard Worker+    /**
39*635a8641SAndroid Build Coastguard Worker+     * A {@link MessageReceiverWithResponder} implementation that forwards all calls to the thread
40*635a8641SAndroid Build Coastguard Worker+     * the ThreadSafeForwarder was created.
41*635a8641SAndroid Build Coastguard Worker+     */
42*635a8641SAndroid Build Coastguard Worker+    class ThreadSafeForwarder implements MessageReceiverWithResponder {
43*635a8641SAndroid Build Coastguard Worker+
44*635a8641SAndroid Build Coastguard Worker+        /**
45*635a8641SAndroid Build Coastguard Worker+         * The {@link MessageReceiverWithResponder} that will receive a serialized message for
46*635a8641SAndroid Build Coastguard Worker+         * each method call.
47*635a8641SAndroid Build Coastguard Worker+         */
48*635a8641SAndroid Build Coastguard Worker+        private final MessageReceiverWithResponder mMessageReceiver;
49*635a8641SAndroid Build Coastguard Worker+
50*635a8641SAndroid Build Coastguard Worker+        /**
51*635a8641SAndroid Build Coastguard Worker+         * The {@link Executor} to forward all tasks to.
52*635a8641SAndroid Build Coastguard Worker+         */
53*635a8641SAndroid Build Coastguard Worker+        private final Executor mExecutor;
54*635a8641SAndroid Build Coastguard Worker+
55*635a8641SAndroid Build Coastguard Worker+        /**
56*635a8641SAndroid Build Coastguard Worker+         * Constructor.
57*635a8641SAndroid Build Coastguard Worker+         *
58*635a8641SAndroid Build Coastguard Worker+         * @param core the Core implementation used to create pipes and access the async waiter.
59*635a8641SAndroid Build Coastguard Worker+         * @param messageReceiver the message receiver to send message to.
60*635a8641SAndroid Build Coastguard Worker+         */
61*635a8641SAndroid Build Coastguard Worker+        public ThreadSafeForwarder(Core core, MessageReceiverWithResponder messageReceiver) {
62*635a8641SAndroid Build Coastguard Worker+            mMessageReceiver = messageReceiver;
63*635a8641SAndroid Build Coastguard Worker+            mExecutor = ExecutorFactory.getExecutorForCurrentThread(core);
64*635a8641SAndroid Build Coastguard Worker+        }
65*635a8641SAndroid Build Coastguard Worker+
66*635a8641SAndroid Build Coastguard Worker+        /**
67*635a8641SAndroid Build Coastguard Worker+         * @see org.chromium.mojo.bindings.MessageReceiver#close()
68*635a8641SAndroid Build Coastguard Worker+         */
69*635a8641SAndroid Build Coastguard Worker+        @Override
70*635a8641SAndroid Build Coastguard Worker+        public void close() {
71*635a8641SAndroid Build Coastguard Worker+            mExecutor.execute(() -> {
72*635a8641SAndroid Build Coastguard Worker+                mMessageReceiver.close();
73*635a8641SAndroid Build Coastguard Worker+            });
74*635a8641SAndroid Build Coastguard Worker+        }
75*635a8641SAndroid Build Coastguard Worker+
76*635a8641SAndroid Build Coastguard Worker+        /**
77*635a8641SAndroid Build Coastguard Worker+         * @see org.chromium.mojo.bindings.MessageReceiver#accept()
78*635a8641SAndroid Build Coastguard Worker+         */
79*635a8641SAndroid Build Coastguard Worker+        @Override
80*635a8641SAndroid Build Coastguard Worker+        public boolean accept(Message message) {
81*635a8641SAndroid Build Coastguard Worker+            mExecutor.execute(() -> {
82*635a8641SAndroid Build Coastguard Worker+                mMessageReceiver.accept(message);
83*635a8641SAndroid Build Coastguard Worker+            });
84*635a8641SAndroid Build Coastguard Worker+            return true;
85*635a8641SAndroid Build Coastguard Worker+        }
86*635a8641SAndroid Build Coastguard Worker+
87*635a8641SAndroid Build Coastguard Worker+        /**
88*635a8641SAndroid Build Coastguard Worker+         * @see org.chromium.mojo.bindings.MessageReceiverWithResponder#acceptWithResponder()
89*635a8641SAndroid Build Coastguard Worker+         */
90*635a8641SAndroid Build Coastguard Worker+        @Override
91*635a8641SAndroid Build Coastguard Worker+        public boolean acceptWithResponder(Message message, MessageReceiver responder) {
92*635a8641SAndroid Build Coastguard Worker+            mExecutor.execute(() -> {
93*635a8641SAndroid Build Coastguard Worker+                mMessageReceiver.acceptWithResponder(message, responder);
94*635a8641SAndroid Build Coastguard Worker+            });
95*635a8641SAndroid Build Coastguard Worker+            return true;
96*635a8641SAndroid Build Coastguard Worker+        }
97*635a8641SAndroid Build Coastguard Worker+    }
98*635a8641SAndroid Build Coastguard Worker+
99*635a8641SAndroid Build Coastguard Worker     /**
100*635a8641SAndroid Build Coastguard Worker      * The |Manager| object enables building of proxies and stubs for a given interface.
101*635a8641SAndroid Build Coastguard Worker      *
102*635a8641SAndroid Build Coastguard Worker@@ -385,6 +447,32 @@ public interface Interface extends ConnectionErrorHandler, Closeable {
103*635a8641SAndroid Build Coastguard Worker             return new InterfaceRequest<I>(handle);
104*635a8641SAndroid Build Coastguard Worker         }
105*635a8641SAndroid Build Coastguard Worker
106*635a8641SAndroid Build Coastguard Worker+        /**
107*635a8641SAndroid Build Coastguard Worker+         * Constructs a thread-safe Proxy forwarding the calls to the given message receiver.
108*635a8641SAndroid Build Coastguard Worker+         * All calls can be performed from any thread and are posted to the {@link Executor} that
109*635a8641SAndroid Build Coastguard Worker+         * is associated with the thread on which this method was called on.
110*635a8641SAndroid Build Coastguard Worker+         *
111*635a8641SAndroid Build Coastguard Worker+         * The original Proxy object is unbound.
112*635a8641SAndroid Build Coastguard Worker+         */
113*635a8641SAndroid Build Coastguard Worker+        public final P buildThreadSafeProxy(P proxy) {
114*635a8641SAndroid Build Coastguard Worker+            HandlerImpl handlerImpl = (HandlerImpl) proxy.getProxyHandler();
115*635a8641SAndroid Build Coastguard Worker+            Core core = handlerImpl.getCore();
116*635a8641SAndroid Build Coastguard Worker+            int version = handlerImpl.getVersion();
117*635a8641SAndroid Build Coastguard Worker+
118*635a8641SAndroid Build Coastguard Worker+            Router router = new RouterImpl(handlerImpl.passHandle());
119*635a8641SAndroid Build Coastguard Worker+            // Close the original proxy now that its handle has been passed.
120*635a8641SAndroid Build Coastguard Worker+            proxy.close();
121*635a8641SAndroid Build Coastguard Worker+
122*635a8641SAndroid Build Coastguard Worker+            proxy = buildProxy(
123*635a8641SAndroid Build Coastguard Worker+                core, new ThreadSafeForwarder(core, new AutoCloseableRouter(core, router)));
124*635a8641SAndroid Build Coastguard Worker+            DelegatingConnectionErrorHandler handlers = new DelegatingConnectionErrorHandler();
125*635a8641SAndroid Build Coastguard Worker+            handlers.addConnectionErrorHandler(proxy);
126*635a8641SAndroid Build Coastguard Worker+            router.setErrorHandler(handlers);
127*635a8641SAndroid Build Coastguard Worker+            router.start();
128*635a8641SAndroid Build Coastguard Worker+            ((HandlerImpl) proxy.getProxyHandler()).setVersion(version);
129*635a8641SAndroid Build Coastguard Worker+            return proxy;
130*635a8641SAndroid Build Coastguard Worker+        }
131*635a8641SAndroid Build Coastguard Worker+
132*635a8641SAndroid Build Coastguard Worker         /**
133*635a8641SAndroid Build Coastguard Worker          * Binds the implementation to the given |router|.
134*635a8641SAndroid Build Coastguard Worker          */
135*635a8641SAndroid Build Coastguard Worker--
136*635a8641SAndroid Build Coastguard Worker2.19.0.605.g01d371f741-goog
137*635a8641SAndroid Build Coastguard Worker
138