diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevServerHelper.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevServerHelper.java index b102002d8..ce934bc7b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevServerHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevServerHelper.java @@ -23,7 +23,6 @@ import java.util.regex.Pattern; import android.content.Context; import android.os.AsyncTask; import android.os.Handler; -import android.text.TextUtils; import com.facebook.common.logging.FLog; import com.facebook.infer.annotation.Assertions; @@ -34,6 +33,10 @@ import com.facebook.react.devsupport.interfaces.PackagerStatusCallback; import com.facebook.react.modules.systeminfo.AndroidInfoHelpers; import com.facebook.react.packagerconnection.FileIoHandler; import com.facebook.react.packagerconnection.JSPackagerClient; +import com.facebook.react.packagerconnection.RequestHandler; +import com.facebook.react.packagerconnection.NotificationOnlyHandler; +import com.facebook.react.packagerconnection.RequestOnlyHandler; +import com.facebook.react.packagerconnection.Responder; import org.json.JSONException; import org.json.JSONObject; @@ -95,8 +98,8 @@ public class DevServerHelper { public interface PackagerCommandListener { void onPackagerReloadCommand(); - void onCaptureHeapCommand(@Nullable final JSPackagerClient.Responder responder); - void onPokeSamplingProfilerCommand(@Nullable final JSPackagerClient.Responder responder); + void onCaptureHeapCommand(@Nullable final Responder responder); + void onPokeSamplingProfilerCommand(@Nullable final Responder responder); } private final DevInternalSettings mSettings; @@ -129,23 +132,23 @@ public class DevServerHelper { new AsyncTask() { @Override protected Void doInBackground(Void... backgroundParams) { - Map handlers = - new HashMap(); - handlers.put("reload", new JSPackagerClient.NotificationOnlyHandler() { + Map handlers = + new HashMap(); + handlers.put("reload", new NotificationOnlyHandler() { @Override public void onNotification(@Nullable Object params) { commandListener.onPackagerReloadCommand(); } }); - handlers.put("captureHeap", new JSPackagerClient.RequestOnlyHandler() { + handlers.put("captureHeap", new RequestOnlyHandler() { @Override - public void onRequest(@Nullable Object params, JSPackagerClient.Responder responder) { + public void onRequest(@Nullable Object params, Responder responder) { commandListener.onCaptureHeapCommand(responder); } }); - handlers.put("pokeSamplingProfiler", new JSPackagerClient.RequestOnlyHandler() { + handlers.put("pokeSamplingProfiler", new RequestOnlyHandler() { @Override - public void onRequest(@Nullable Object params, JSPackagerClient.Responder responder) { + public void onRequest(@Nullable Object params, Responder responder) { commandListener.onPokeSamplingProfilerCommand(responder); } }); diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerImpl.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerImpl.java index d141dc932..6d8e32448 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerImpl.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerImpl.java @@ -44,6 +44,7 @@ import com.facebook.react.devsupport.interfaces.PackagerStatusCallback; import com.facebook.react.devsupport.interfaces.StackFrame; import com.facebook.react.modules.debug.interfaces.DeveloperSettings; import com.facebook.react.packagerconnection.JSPackagerClient; +import com.facebook.react.packagerconnection.Responder; import java.io.File; import java.io.IOException; @@ -674,7 +675,7 @@ public class DevSupportManagerImpl implements } @Override - public void onCaptureHeapCommand(final JSPackagerClient.Responder responder) { + public void onCaptureHeapCommand(final Responder responder) { UiThreadUtil.runOnUiThread(new Runnable() { @Override public void run() { @@ -684,7 +685,7 @@ public class DevSupportManagerImpl implements } @Override - public void onPokeSamplingProfilerCommand(@Nullable final JSPackagerClient.Responder responder) { + public void onPokeSamplingProfilerCommand(@Nullable final Responder responder) { UiThreadUtil.runOnUiThread(new Runnable() { @Override public void run() { @@ -693,7 +694,7 @@ public class DevSupportManagerImpl implements }); } - private void handleCaptureHeap(final JSPackagerClient.Responder responder) { + private void handleCaptureHeap(final Responder responder) { if (mCurrentContext == null) { return; } @@ -713,7 +714,7 @@ public class DevSupportManagerImpl implements }); } - private void handlePokeSamplingProfiler(@Nullable final JSPackagerClient.Responder responder) { + private void handlePokeSamplingProfiler(@Nullable final Responder responder) { try { List pokeResults = JSCSamplingProfiler.poke(60000); for (String result : pokeResults) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/FileIoHandler.java b/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/FileIoHandler.java index 5a0adb1dd..5f55f03d8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/FileIoHandler.java +++ b/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/FileIoHandler.java @@ -62,17 +62,17 @@ public class FileIoHandler implements Runnable { private int mNextHandle; private final Handler mHandler; private final Map mOpenFiles; - private final Map mRequestHandlers; + private final Map mRequestHandlers; public FileIoHandler() { mNextHandle = 1; mHandler = new Handler(Looper.getMainLooper()); mOpenFiles = new HashMap<>(); mRequestHandlers = new HashMap<>(); - mRequestHandlers.put("fopen", new JSPackagerClient.RequestOnlyHandler() { + mRequestHandlers.put("fopen", new RequestOnlyHandler() { @Override public void onRequest( - @Nullable Object params, JSPackagerClient.Responder responder) { + @Nullable Object params, Responder responder) { synchronized (mOpenFiles) { try { JSONObject paramsObj = (JSONObject)params; @@ -98,10 +98,10 @@ public class FileIoHandler implements Runnable { } } }); - mRequestHandlers.put("fclose", new JSPackagerClient.RequestOnlyHandler() { + mRequestHandlers.put("fclose", new RequestOnlyHandler() { @Override public void onRequest( - @Nullable Object params, JSPackagerClient.Responder responder) { + @Nullable Object params, Responder responder) { synchronized (mOpenFiles) { try { if (!(params instanceof Number)) { @@ -121,10 +121,10 @@ public class FileIoHandler implements Runnable { } } }); - mRequestHandlers.put("fread", new JSPackagerClient.RequestOnlyHandler() { + mRequestHandlers.put("fread", new RequestOnlyHandler() { @Override public void onRequest( - @Nullable Object params, JSPackagerClient.Responder responder) { + @Nullable Object params, Responder responder) { synchronized (mOpenFiles) { try { JSONObject paramsObj = (JSONObject)params; @@ -153,7 +153,7 @@ public class FileIoHandler implements Runnable { }); } - public Map handlers() { + public Map handlers() { return mRequestHandlers; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/JSPackagerClient.java b/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/JSPackagerClient.java index 2568ca9ea..6160152b0 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/JSPackagerClient.java +++ b/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/JSPackagerClient.java @@ -8,9 +8,6 @@ package com.facebook.react.packagerconnection; -import javax.annotation.Nullable; - -import java.util.HashMap; import java.util.Map; import android.net.Uri; @@ -32,10 +29,10 @@ final public class JSPackagerClient implements ReconnectingWebSocket.MessageCall private static final String PACKAGER_CONNECTION_URL_FORMAT = "ws://%s/message?device=%s&app=%s&context=%s"; private static final int PROTOCOL_VERSION = 2; - public class Responder { + private class ResponderImpl implements Responder { private Object mId; - public Responder(Object id) { + public ResponderImpl(Object id) { mId = id; } @@ -64,26 +61,6 @@ final public class JSPackagerClient implements ReconnectingWebSocket.MessageCall } } - public interface RequestHandler { - public void onRequest(@Nullable Object params, Responder responder); - public void onNotification(@Nullable Object params); - } - - public static abstract class NotificationOnlyHandler implements RequestHandler { - final public void onRequest(@Nullable Object params, Responder responder) { - responder.error("Request is not supported"); - FLog.e(TAG, "Request is not supported"); - } - abstract public void onNotification(@Nullable Object params); - } - - public static abstract class RequestOnlyHandler implements RequestHandler { - abstract public void onRequest(@Nullable Object params, Responder responder); - final public void onNotification(@Nullable Object params) { - FLog.e(TAG, "Notification is not supported"); - } - } - private ReconnectingWebSocket mWebSocket; private Map mRequestHandlers; @@ -149,7 +126,7 @@ final public class JSPackagerClient implements ReconnectingWebSocket.MessageCall if (id == null) { handler.onNotification(params); } else { - handler.onRequest(params, new Responder(id)); + handler.onRequest(params, new ResponderImpl(id)); } } catch (Exception e) { FLog.e(TAG, "Handling the message failed", e); @@ -160,7 +137,7 @@ final public class JSPackagerClient implements ReconnectingWebSocket.MessageCall private void abortOnMessage(Object id, String reason) { if (id != null) { - (new Responder(id)).error(reason); + (new ResponderImpl(id)).error(reason); } FLog.e(TAG, "Handling the message failed with reason: " + reason); diff --git a/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/NotificationOnlyHandler.java b/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/NotificationOnlyHandler.java new file mode 100644 index 000000000..dc337019c --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/NotificationOnlyHandler.java @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the BSD-style license found in the LICENSE file in the root + * directory of this source tree. An additional grant of patent rights can be found in the PATENTS + * file in the same directory. + */ + +package com.facebook.react.packagerconnection; + +import javax.annotation.Nullable; + +import com.facebook.common.logging.FLog; + +public abstract class NotificationOnlyHandler implements RequestHandler { + private static final String TAG = JSPackagerClient.class.getSimpleName(); + + final public void onRequest(@Nullable Object params, Responder responder) { + responder.error("Request is not supported"); + FLog.e(TAG, "Request is not supported"); + } + abstract public void onNotification(@Nullable Object params); +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/RequestHandler.java b/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/RequestHandler.java new file mode 100644 index 000000000..4d7a25231 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/RequestHandler.java @@ -0,0 +1,16 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the BSD-style license found in the LICENSE file in the root + * directory of this source tree. An additional grant of patent rights can be found in the PATENTS + * file in the same directory. + */ + +package com.facebook.react.packagerconnection; + +import javax.annotation.Nullable; + +public interface RequestHandler { + void onRequest(@Nullable Object params, Responder responder); + void onNotification(@Nullable Object params); +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/RequestOnlyHandler.java b/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/RequestOnlyHandler.java new file mode 100644 index 000000000..9e617bee7 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/RequestOnlyHandler.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the BSD-style license found in the LICENSE file in the root + * directory of this source tree. An additional grant of patent rights can be found in the PATENTS + * file in the same directory. + */ + +package com.facebook.react.packagerconnection; + +import javax.annotation.Nullable; + +import com.facebook.common.logging.FLog; + +public abstract class RequestOnlyHandler implements RequestHandler { + private static final String TAG = JSPackagerClient.class.getSimpleName(); + + abstract public void onRequest(@Nullable Object params, Responder responder); + final public void onNotification(@Nullable Object params) { + FLog.e(TAG, "Notification is not supported"); + } +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/Responder.java b/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/Responder.java new file mode 100644 index 000000000..b91a0a7d1 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/Responder.java @@ -0,0 +1,14 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the BSD-style license found in the LICENSE file in the root + * directory of this source tree. An additional grant of patent rights can be found in the PATENTS + * file in the same directory. + */ + +package com.facebook.react.packagerconnection; + +public interface Responder { + void respond(Object result); + void error(Object error); +} diff --git a/ReactAndroid/src/test/java/com/facebook/react/packagerconnection/JSPackagerClientTest.java b/ReactAndroid/src/test/java/com/facebook/react/packagerconnection/JSPackagerClientTest.java index d930384a3..165ab5e82 100644 --- a/ReactAndroid/src/test/java/com/facebook/react/packagerconnection/JSPackagerClientTest.java +++ b/ReactAndroid/src/test/java/com/facebook/react/packagerconnection/JSPackagerClientTest.java @@ -25,10 +25,10 @@ import org.robolectric.RobolectricTestRunner; @RunWith(RobolectricTestRunner.class) public class JSPackagerClientTest { - private static Map createRH( - String action, JSPackagerClient.RequestHandler handler) { - Map m = - new HashMap(); + private static Map createRH( + String action, RequestHandler handler) { + Map m = + new HashMap(); m.put(action, handler); return m; } @@ -44,7 +44,7 @@ public class JSPackagerClientTest { @Test public void test_onMessage_ShouldTriggerNotification() throws IOException { - JSPackagerClient.RequestHandler handler = mock(JSPackagerClient.RequestHandler.class); + RequestHandler handler = mock(RequestHandler.class); final JSPackagerClient client = new JSPackagerClient("test_client", mSettings, createRH("methodValue", handler)); client.onMessage( @@ -52,12 +52,12 @@ public class JSPackagerClientTest { WebSocket.TEXT, "{\"version\": 2, \"method\": \"methodValue\", \"params\": \"paramsValue\"}")); verify(handler).onNotification(eq("paramsValue")); - verify(handler, never()).onRequest(any(), any(JSPackagerClient.Responder.class)); + verify(handler, never()).onRequest(any(), any(Responder.class)); } @Test public void test_onMessage_ShouldTriggerRequest() throws IOException { - JSPackagerClient.RequestHandler handler = mock(JSPackagerClient.RequestHandler.class); + RequestHandler handler = mock(RequestHandler.class); final JSPackagerClient client = new JSPackagerClient("test_client", mSettings, createRH("methodValue", handler)); client.onMessage( @@ -65,12 +65,12 @@ public class JSPackagerClientTest { WebSocket.TEXT, "{\"version\": 2, \"id\": \"idValue\", \"method\": \"methodValue\", \"params\": \"paramsValue\"}")); verify(handler, never()).onNotification(any()); - verify(handler).onRequest(eq("paramsValue"), any(JSPackagerClient.Responder.class)); + verify(handler).onRequest(eq("paramsValue"), any(Responder.class)); } @Test public void test_onMessage_WithoutParams_ShouldTriggerNotification() throws IOException { - JSPackagerClient.RequestHandler handler = mock(JSPackagerClient.RequestHandler.class); + RequestHandler handler = mock(RequestHandler.class); final JSPackagerClient client = new JSPackagerClient("test_client", mSettings, createRH("methodValue", handler)); client.onMessage( @@ -78,12 +78,12 @@ public class JSPackagerClientTest { WebSocket.TEXT, "{\"version\": 2, \"method\": \"methodValue\"}")); verify(handler).onNotification(eq(null)); - verify(handler, never()).onRequest(any(), any(JSPackagerClient.Responder.class)); + verify(handler, never()).onRequest(any(), any(Responder.class)); } @Test public void test_onMessage_WithInvalidContentType_ShouldNotTriggerCallback() throws IOException { - JSPackagerClient.RequestHandler handler = mock(JSPackagerClient.RequestHandler.class); + RequestHandler handler = mock(RequestHandler.class); final JSPackagerClient client = new JSPackagerClient("test_client", mSettings, createRH("methodValue", handler)); client.onMessage( @@ -91,12 +91,12 @@ public class JSPackagerClientTest { WebSocket.BINARY, "{\"version\": 2, \"method\": \"methodValue\"}")); verify(handler, never()).onNotification(any()); - verify(handler, never()).onRequest(any(), any(JSPackagerClient.Responder.class)); + verify(handler, never()).onRequest(any(), any(Responder.class)); } @Test public void test_onMessage_WithoutMethod_ShouldNotTriggerCallback() throws IOException { - JSPackagerClient.RequestHandler handler = mock(JSPackagerClient.RequestHandler.class); + RequestHandler handler = mock(RequestHandler.class); final JSPackagerClient client = new JSPackagerClient("test_client", mSettings, createRH("methodValue", handler)); client.onMessage( @@ -104,12 +104,12 @@ public class JSPackagerClientTest { WebSocket.TEXT, "{\"version\": 2}")); verify(handler, never()).onNotification(any()); - verify(handler, never()).onRequest(any(), any(JSPackagerClient.Responder.class)); + verify(handler, never()).onRequest(any(), any(Responder.class)); } @Test public void test_onMessage_With_Null_Action_ShouldNotTriggerCallback() throws IOException { - JSPackagerClient.RequestHandler handler = mock(JSPackagerClient.RequestHandler.class); + RequestHandler handler = mock(RequestHandler.class); final JSPackagerClient client = new JSPackagerClient("test_client", mSettings, createRH("methodValue", handler)); client.onMessage( @@ -117,12 +117,12 @@ public class JSPackagerClientTest { WebSocket.TEXT, "{\"version\": 2, \"method\": null}")); verify(handler, never()).onNotification(any()); - verify(handler, never()).onRequest(any(), any(JSPackagerClient.Responder.class)); + verify(handler, never()).onRequest(any(), any(Responder.class)); } @Test public void test_onMessage_WithInvalidMethod_ShouldNotTriggerCallback() throws IOException { - JSPackagerClient.RequestHandler handler = mock(JSPackagerClient.RequestHandler.class); + RequestHandler handler = mock(RequestHandler.class); final JSPackagerClient client = new JSPackagerClient("test_client", mSettings, createRH("methodValue", handler)); client.onMessage( @@ -130,12 +130,12 @@ public class JSPackagerClientTest { WebSocket.BINARY, "{\"version\": 2, \"method\": \"methodValue2\"}")); verify(handler, never()).onNotification(any()); - verify(handler, never()).onRequest(any(), any(JSPackagerClient.Responder.class)); + verify(handler, never()).onRequest(any(), any(Responder.class)); } @Test public void test_onMessage_WrongVersion_ShouldNotTriggerCallback() throws IOException { - JSPackagerClient.RequestHandler handler = mock(JSPackagerClient.RequestHandler.class); + RequestHandler handler = mock(RequestHandler.class); final JSPackagerClient client = new JSPackagerClient("test_client", mSettings, createRH("methodValue", handler)); client.onMessage( @@ -143,6 +143,6 @@ public class JSPackagerClientTest { WebSocket.TEXT, "{\"version\": 1, \"method\": \"methodValue\"}")); verify(handler, never()).onNotification(any()); - verify(handler, never()).onRequest(any(), any(JSPackagerClient.Responder.class)); + verify(handler, never()).onRequest(any(), any(Responder.class)); } }