summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuis Hector Chavez <lhchavez@google.com>2018-06-14 11:26:30 -0700
committerLuis Hector Chavez <lhchavez@google.com>2018-07-13 13:13:43 -0700
commit1fef1a678393e55d295f295a1d0e5fff89a5c725 (patch)
tree5d9a5d290782d5d70ca74b885f6e910a245e175b
parent1ec13ff8a419faa4bfa859400c6eee6d50ce2a7e (diff)
downloadlibchrome-1fef1a678393e55d295f295a1d0e5fff89a5c725.tar.gz
[mojo]: Add a way to handle unhandled RuntimeExceptionsandroid-n-iot-release-smart-display-r2
This change makes it possible to allow interfaces to globally handle unhandled RuntimeExceptions, in their bindings or in the callbacks. Bug: 28814913 Test: Android-on-Chrome OS has the same behavior as before Test: Android-on-Chrome OS, when setting the DefaultExceptionHandler's delegate can now forward the unhandled exceptions to the crash server. Change-Id: I2b7455a0344a109e1d2416a74ad4a0b98cd007f0 Reviewed-on: https://chromium-review.googlesource.com/1101898 Reviewed-by: Ken Rockot <rockot@chromium.org> Commit-Queue: Luis Hector Chavez <lhchavez@chromium.org> Cr-Commit-Position: refs/heads/master@{#568128}
-rw-r--r--libchrome_tools/patch/mojo-Add-a-way-to-handle-unhandled-RuntimeExceptions.patch129
-rw-r--r--mojo/public/java/BUILD.gn1
-rw-r--r--mojo/public/java/bindings/src/org/chromium/mojo/bindings/Connector.java15
-rw-r--r--mojo/public/java/bindings/src/org/chromium/mojo/bindings/ExceptionHandler.java59
4 files changed, 201 insertions, 3 deletions
diff --git a/libchrome_tools/patch/mojo-Add-a-way-to-handle-unhandled-RuntimeExceptions.patch b/libchrome_tools/patch/mojo-Add-a-way-to-handle-unhandled-RuntimeExceptions.patch
new file mode 100644
index 0000000000..f5ac205ce3
--- /dev/null
+++ b/libchrome_tools/patch/mojo-Add-a-way-to-handle-unhandled-RuntimeExceptions.patch
@@ -0,0 +1,129 @@
+From 4256ecec730fdf5a41f34e11c0641e072971cb8c Mon Sep 17 00:00:00 2001
+From: Luis Hector Chavez <lhchavez@google.com>
+Date: Mon, 18 Jun 2018 20:14:56 +0000
+Subject: [PATCH] [mojo] Add a way to handle unhandled RuntimeExceptions
+
+This change makes it possible to allow interfaces to globally handle
+unhandled RuntimeExceptions, in their bindings or in the callbacks.
+
+ delegate can now forward the unhandled exceptions to the crash
+ server.
+
+Bug: 810087
+Test: Android-on-Chrome OS has the same behavior as before
+Test: Android-on-Chrome OS, when setting the DefaultExceptionHandler's
+Change-Id: I2b7455a0344a109e1d2416a74ad4a0b98cd007f0
+Reviewed-on: https://chromium-review.googlesource.com/1101898
+Reviewed-by: Ken Rockot <rockot@chromium.org>
+Commit-Queue: Luis Hector Chavez <lhchavez@chromium.org>
+Cr-Commit-Position: refs/heads/master@{#568128}
+---
+ mojo/public/java/BUILD.gn | 1 +
+ .../org/chromium/mojo/bindings/Connector.java | 12 +++-
+ .../mojo/bindings/ExceptionHandler.java | 59 +++++++++++++++++++
+ 3 files changed, 70 insertions(+), 2 deletions(-)
+ create mode 100644 mojo/public/java/bindings/src/org/chromium/mojo/bindings/ExceptionHandler.java
+
+diff --git a/mojo/public/java/BUILD.gn b/mojo/public/java/BUILD.gn
+index 14951f4f0959..259e09cf7c07 100644
+--- a/mojo/public/java/BUILD.gn
++++ b/mojo/public/java/BUILD.gn
+@@ -41,6 +41,7 @@ android_library("bindings_java") {
+ "bindings/src/org/chromium/mojo/bindings/DelegatingConnectionErrorHandler.java",
+ "bindings/src/org/chromium/mojo/bindings/DeserializationException.java",
+ "bindings/src/org/chromium/mojo/bindings/Encoder.java",
++ "bindings/src/org/chromium/mojo/bindings/ExceptionHandler.java",
+ "bindings/src/org/chromium/mojo/bindings/ExecutorFactory.java",
+ "bindings/src/org/chromium/mojo/bindings/HandleOwner.java",
+ "bindings/src/org/chromium/mojo/bindings/InterfaceControlMessagesHelper.java",
+diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Connector.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Connector.java
+index 3a6d67112ce0..45f1fc7462e8 100644
+--- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Connector.java
++++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Connector.java
+@@ -201,8 +201,16 @@ public class Connector implements MessageReceiver, HandleOwner<MessagePipeHandle
+ ReadMessageResult readResult = result.getValue();
+ assert readResult != null;
+ if (receiver != null) {
+- boolean accepted = receiver.accept(
+- new Message(ByteBuffer.wrap(readResult.mData), readResult.mHandles));
++ boolean accepted;
++ try {
++ accepted = receiver.accept(
++ new Message(ByteBuffer.wrap(readResult.mData), readResult.mHandles));
++ } catch (RuntimeException e) {
++ // The DefaultExceptionHandler will decide whether any uncaught exception will
++ // close the connection or not.
++ accepted =
++ ExceptionHandler.DefaultExceptionHandler.getInstance().handleException(e);
++ }
+ return new ResultAnd<Boolean>(result.getMojoResult(), accepted);
+ }
+ return new ResultAnd<Boolean>(result.getMojoResult(), false);
+diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/ExceptionHandler.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/ExceptionHandler.java
+new file mode 100644
+index 000000000000..8961d22d3ee4
+--- /dev/null
++++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/ExceptionHandler.java
+@@ -0,0 +1,59 @@
++// Copyright 2018 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;
++
++/**
++ * An {@link ExceptionHandler} is notified of any {@link RuntimeException} happening in the
++ * bindings or any of the callbacks.
++ */
++public interface ExceptionHandler {
++ /**
++ * Receives a notification that an unhandled {@link RuntimeException} has been thrown in an
++ * {@link Interface} implementation or one of the {@link Callbacks} internal classes.
++ *
++ * Normal implementations should either throw the exception or return whether the connection
++ * should be kept alive or terminated.
++ */
++ public boolean handleException(RuntimeException e);
++
++ /**
++ * The default ExceptionHandler, which simply throws the exception upon receiving it. It can
++ * also delegate the handling of the exceptions to another instance of ExceptionHandler.
++ */
++ public static class DefaultExceptionHandler implements ExceptionHandler {
++ private ExceptionHandler mDelegate;
++
++ @Override
++ public boolean handleException(RuntimeException e) {
++ if (mDelegate != null) {
++ return mDelegate.handleException(e);
++ }
++ throw e;
++ }
++
++ private DefaultExceptionHandler() {}
++
++ /**
++ * Static class that implements the initialization-on-demand holder idiom.
++ */
++ private static class LazyHolder {
++ static final DefaultExceptionHandler INSTANCE = new DefaultExceptionHandler();
++ }
++
++ /**
++ * Gets the singleton instance for the DefaultExceptionHandler.
++ */
++ public static DefaultExceptionHandler getInstance() {
++ return LazyHolder.INSTANCE;
++ }
++
++ /**
++ * Sets a delegate ExceptionHandler, in case throwing an exception is not desirable.
++ */
++ public void setDelegate(ExceptionHandler exceptionHandler) {
++ mDelegate = exceptionHandler;
++ }
++ }
++}
+--
+2.18.0.203.gfac676dfb9-goog
+
diff --git a/mojo/public/java/BUILD.gn b/mojo/public/java/BUILD.gn
index 078064114e..850785aa2c 100644
--- a/mojo/public/java/BUILD.gn
+++ b/mojo/public/java/BUILD.gn
@@ -37,6 +37,7 @@ android_library("bindings_java") {
"bindings/src/org/chromium/mojo/bindings/DelegatingConnectionErrorHandler.java",
"bindings/src/org/chromium/mojo/bindings/DeserializationException.java",
"bindings/src/org/chromium/mojo/bindings/Encoder.java",
+ "bindings/src/org/chromium/mojo/bindings/ExceptionHandler.java",
"bindings/src/org/chromium/mojo/bindings/ExecutorFactory.java",
"bindings/src/org/chromium/mojo/bindings/HandleOwner.java",
"bindings/src/org/chromium/mojo/bindings/InterfaceControlMessagesHelper.java",
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Connector.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Connector.java
index 2aa5ea690c..d58602ab29 100644
--- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Connector.java
+++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/Connector.java
@@ -169,7 +169,9 @@ public class Connector implements MessageReceiver, HandleOwner<MessagePipeHandle
ResultAnd<Boolean> result;
do {
try {
- result = readAndDispatchMessage(mMessagePipeHandle, mIncomingMessageReceiver);
+ result = readAndDispatchMessage(
+ mMessagePipeHandle, mIncomingMessageReceiver,
+ ExceptionHandler.DefaultExceptionHandler.getInstance());
} catch (MojoException e) {
onError(e);
return;
@@ -191,9 +193,11 @@ public class Connector implements MessageReceiver, HandleOwner<MessagePipeHandle
*
* @param receiver The {@link MessageReceiver} that will receive the read {@link Message}. Can
* be <code>null</code>, in which case the message is discarded.
+ * @param exceptionHandler The {@link ExceptionHandler} that can decide whether any uncaught
+ * exception will close the connection or not.
*/
static ResultAnd<Boolean> readAndDispatchMessage(
- MessagePipeHandle handle, MessageReceiver receiver) {
+ MessagePipeHandle handle, MessageReceiver receiver, ExceptionHandler exceptionHandler) {
// TODO(qsr) Allow usage of a pool of pre-allocated buffer for performance.
ResultAnd<ReadMessageResult> result =
handle.readMessage(null, 0, MessagePipeHandle.ReadFlags.NONE);
@@ -206,7 +210,12 @@ public class Connector implements MessageReceiver, HandleOwner<MessagePipeHandle
result = handle.readMessage(
buffer, readResult.getHandlesCount(), MessagePipeHandle.ReadFlags.NONE);
if (receiver != null && result.getMojoResult() == MojoResult.OK) {
- boolean accepted = receiver.accept(new Message(buffer, result.getValue().getHandles()));
+ boolean accepted;
+ try {
+ accepted = receiver.accept(new Message(buffer, result.getValue().getHandles()));
+ } catch (RuntimeException e) {
+ accepted = exceptionHandler.handleException(e);
+ }
return new ResultAnd<Boolean>(result.getMojoResult(), accepted);
}
return new ResultAnd<Boolean>(result.getMojoResult(), false);
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/ExceptionHandler.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/ExceptionHandler.java
new file mode 100644
index 0000000000..8961d22d3e
--- /dev/null
+++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/ExceptionHandler.java
@@ -0,0 +1,59 @@
+// Copyright 2018 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;
+
+/**
+ * An {@link ExceptionHandler} is notified of any {@link RuntimeException} happening in the
+ * bindings or any of the callbacks.
+ */
+public interface ExceptionHandler {
+ /**
+ * Receives a notification that an unhandled {@link RuntimeException} has been thrown in an
+ * {@link Interface} implementation or one of the {@link Callbacks} internal classes.
+ *
+ * Normal implementations should either throw the exception or return whether the connection
+ * should be kept alive or terminated.
+ */
+ public boolean handleException(RuntimeException e);
+
+ /**
+ * The default ExceptionHandler, which simply throws the exception upon receiving it. It can
+ * also delegate the handling of the exceptions to another instance of ExceptionHandler.
+ */
+ public static class DefaultExceptionHandler implements ExceptionHandler {
+ private ExceptionHandler mDelegate;
+
+ @Override
+ public boolean handleException(RuntimeException e) {
+ if (mDelegate != null) {
+ return mDelegate.handleException(e);
+ }
+ throw e;
+ }
+
+ private DefaultExceptionHandler() {}
+
+ /**
+ * Static class that implements the initialization-on-demand holder idiom.
+ */
+ private static class LazyHolder {
+ static final DefaultExceptionHandler INSTANCE = new DefaultExceptionHandler();
+ }
+
+ /**
+ * Gets the singleton instance for the DefaultExceptionHandler.
+ */
+ public static DefaultExceptionHandler getInstance() {
+ return LazyHolder.INSTANCE;
+ }
+
+ /**
+ * Sets a delegate ExceptionHandler, in case throwing an exception is not desirable.
+ */
+ public void setDelegate(ExceptionHandler exceptionHandler) {
+ mDelegate = exceptionHandler;
+ }
+ }
+}