Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(380)

Unified Diff: mojo/bindings/java/src/org/chromium/mojo/bindings/RouterImpl.java

Issue 371603003: Adding a router class to handle messages that expect responses. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix rebasing Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: mojo/bindings/java/src/org/chromium/mojo/bindings/RouterImpl.java
diff --git a/mojo/bindings/java/src/org/chromium/mojo/bindings/RouterImpl.java b/mojo/bindings/java/src/org/chromium/mojo/bindings/RouterImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..3f8457868b6fafbbe5872edfb1e1dd0c2d6e07e2
--- /dev/null
+++ b/mojo/bindings/java/src/org/chromium/mojo/bindings/RouterImpl.java
@@ -0,0 +1,171 @@
+// 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 org.chromium.mojo.system.AsyncWaiter;
+import org.chromium.mojo.system.MessagePipeHandle;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Implementation of Router.
rmcilroy 2014/07/10 19:03:59 {@link Router}
qsr 2014/07/11 11:42:08 Done.
+ */
+public class RouterImpl implements Router {
+
+ /**
+ * {@link MessageReceiver} used as the {@link Connector} callback.
+ */
+ private class Thunk implements MessageReceiver {
rmcilroy 2014/07/10 19:03:59 Thunk is not a very clear name for what the class
qsr 2014/07/11 11:42:08 It is the name the C++ implementation use. I'd lik
+
+ /**
+ * @see MessageReceiver#accept(Message)
+ */
+ @Override
+ public boolean accept(Message message) {
+ return handleIncomingMessage(message);
+ }
+
+ }
+
+ /**
+ * The {@link Connector} connected to the handle.
rmcilroy 2014/07/10 19:03:59 /s/connected/which is connected
qsr 2014/07/11 11:42:08 Done.
+ */
+ private final Connector mConnector;
+
+ /**
+ * The {@link MessageReceiverWithResponder} that will deserialize and use the message received
rmcilroy 2014/07/10 19:03:59 /s/deserialize and use/consume /s/message/messages
qsr 2014/07/11 11:42:08 Done.
+ * from the pipe.
+ */
+ private MessageReceiverWithResponder mIncomingMessageReceiver;
+
+ /**
+ * The id of the next request that needs a response. It is auto-incremented.
rmcilroy 2014/07/10 19:03:59 The next id to use for a request id which needs a
qsr 2014/07/11 11:42:09 Done.
+ */
+ private long mNextRequestId = 1;
+
+ /**
+ * The map from request ids to {@link MessageReceiver} of request currently in flight.
+ */
+ private Map<Long, MessageReceiver> mResponders = new HashMap<Long, MessageReceiver>();
+
+ /**
+ * Constructor.
rmcilroy 2014/07/10 19:03:59 Detail parameters and that it uses the default asy
qsr 2014/07/11 11:42:09 Done.
+ */
+ public RouterImpl(MessagePipeHandle messagePipeHandle) {
+ this(messagePipeHandle, BindingsHelper.getDefaultAsyncWaiterForHandle(messagePipeHandle));
+ }
+
+ /**
+ * Constructor.
rmcilroy 2014/07/10 19:03:59 Detail parameters
qsr 2014/07/11 11:42:08 Done.
+ */
+ public RouterImpl(MessagePipeHandle messagePipeHandle, AsyncWaiter asyncWaiter) {
+ mConnector = new Connector(messagePipeHandle, asyncWaiter);
+ mConnector.setIncomingMessageReceiver(new Thunk());
+ }
+
+ /**
+ * @see org.chromium.mojo.bindings.Router#start()
+ */
+ @Override
+ public void start() {
+ mConnector.start();
+ }
+
+ /**
+ * @see Router#setIncomingMessageReceiver(MessageReceiverWithResponder)
+ */
+ @Override
+ public void setIncomingMessageReceiver(MessageReceiverWithResponder incomingMessageReceiver) {
+ this.mIncomingMessageReceiver = incomingMessageReceiver;
+ }
+
+ /**
+ * @see MessageReceiver#accept(Message)
+ */
+ @Override
+ public boolean accept(Message message) {
+ // A message without receiver is directly forwarded to the connector.
rmcilroy 2014/07/10 19:03:59 /s/receiever/a responder
qsr 2014/07/11 11:42:08 Done.
+ return mConnector.accept(message);
+ }
+
+ /**
+ * @see MessageReceiverWithResponder#acceptWithResponder(Message, MessageReceiver)
+ */
+ @Override
+ public boolean acceptWithResponder(Message message, MessageReceiver receiver) {
rmcilroy 2014/07/10 19:03:59 /s/receiver/responder
qsr 2014/07/11 11:42:09 Done.
+ // Checking the message expects a response.
+ assert message.getHeader().hasFlag(MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG);
+
+ // Compute a request id for being able to route the response.
+ long requestId = mNextRequestId++;
+ // Reserve 0 in case we want it to convey special meaning in the future.
+ if (requestId == 0) {
+ requestId = mNextRequestId++;
+ }
+ assert !mResponders.containsKey(requestId);
rmcilroy 2014/07/10 19:03:59 I don't think it's enough to just assert this - ev
qsr 2014/07/11 11:42:09 Done. I don't think (famous last words) that it is
+ MessageHeader.setRequestId(message, requestId);
+ if (!mConnector.accept(message)) {
+ return false;
+ }
+ // Only keep the receiver is the message has been accepted.
rmcilroy 2014/07/10 19:03:59 /s/receiever/responder
qsr 2014/07/11 11:42:09 Done.
+ mResponders.put(requestId, receiver);
+ return true;
+ }
+
+ /**
+ * @see org.chromium.mojo.bindings.HandleOwner#passHandle()
+ */
+ @Override
+ public MessagePipeHandle passHandle() {
+ return mConnector.passHandle();
+ }
+
+ /**
+ * @see java.io.Closeable#close()
+ */
+ @Override
+ public void close() {
+ mConnector.close();
+ }
+
+ /**
+ * @see Router#setErrorHandler(ConnectionErrorHandler)
+ */
+ @Override
+ public void setErrorHandler(ConnectionErrorHandler errorHandler) {
+ mConnector.setErrorHandler(errorHandler);
+ }
+
+ /**
+ * Receive a message from the connector.
rmcilroy 2014/07/10 19:03:59 describe what's returned
qsr 2014/07/11 11:42:08 Done.
+ */
+ private boolean handleIncomingMessage(Message message) {
+ MessageHeader header = message.getHeader();
+ if (header.hasFlag(MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG)) {
+ if (mIncomingMessageReceiver != null) {
+ return mIncomingMessageReceiver.acceptWithResponder(message, this);
+ }
+ // If we receive a request expecting a response when the client is not
+ // listening, then we have no choice but to tear down the pipe.
+ close();
+ return false;
+ } else if (header.hasFlag(MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
+ long requestId = header.getRequestId();
+ MessageReceiver responder = mResponders.get(requestId);
+ if (responder == null) {
+ return false;
rmcilroy 2014/07/10 19:03:59 should we teardown here too?
qsr 2014/07/11 11:42:08 Not really. The message is routed, but the problem
+ }
+ return responder.accept(message);
+ } else {
+ if (mIncomingMessageReceiver != null) {
+ return mIncomingMessageReceiver.accept(message);
+ }
+ // OK to drop the message.
+ }
+ return false;
+ }
+
+}

Powered by Google App Engine
This is Rietveld 408576698