Use emitDeviceEvent in core ReactAndroid code (#36280)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36280

[Changelog][Internal]

As a follow-up to adding `ReactContext.emitDeviceEvent` (D43534174 (a8f0a4dc62)) this makes it used in the OSS part of RN.

Reviewed By: NickGerleman

Differential Revision: D43494167

fbshipit-source-id: c3d56bde53fb1ce1297a48597b97470ff10f4dc0
This commit is contained in:
Ruslan Shestopalyuk 2023-02-27 07:34:15 -08:00 коммит произвёл Facebook GitHub Bot
Родитель ad686b0ce1
Коммит b108cbbff8
17 изменённых файлов: 144 добавлений и 187 удалений

Просмотреть файл

@ -18,7 +18,6 @@ import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule;
/** /**
* Mock Networking module that records last request received by {@link #sendRequest} method and * Mock Networking module that records last request received by {@link #sendRequest} method and
@ -36,6 +35,7 @@ public class NetworkRecordingModuleMock extends ReactContextBaseJavaModule {
public boolean mAbortedRequest; public boolean mAbortedRequest;
private boolean mCompleteRequest; private boolean mCompleteRequest;
private ReactApplicationContext mContext;
public NetworkRecordingModuleMock(ReactApplicationContext reactContext) { public NetworkRecordingModuleMock(ReactApplicationContext reactContext) {
this(reactContext, true); this(reactContext, true);
@ -44,6 +44,7 @@ public class NetworkRecordingModuleMock extends ReactContextBaseJavaModule {
public NetworkRecordingModuleMock(ReactApplicationContext reactContext, boolean completeRequest) { public NetworkRecordingModuleMock(ReactApplicationContext reactContext, boolean completeRequest) {
super(reactContext); super(reactContext);
mCompleteRequest = completeRequest; mCompleteRequest = completeRequest;
mContext = reactContext;
} }
public interface RequestListener { public interface RequestListener {
@ -120,7 +121,7 @@ public class NetworkRecordingModuleMock extends ReactContextBaseJavaModule {
args.pushInt(requestId); args.pushInt(requestId);
args.pushString(data); args.pushString(data);
getEventEmitter().emit("didReceiveNetworkData", args); mContext.emitDeviceEvent("didReceiveNetworkData", args);
} }
private void onRequestComplete(int requestId, @Nullable String error) { private void onRequestComplete(int requestId, @Nullable String error) {
@ -128,7 +129,7 @@ public class NetworkRecordingModuleMock extends ReactContextBaseJavaModule {
args.pushInt(requestId); args.pushInt(requestId);
args.pushString(error); args.pushString(error);
getEventEmitter().emit("didCompleteNetworkResponse", args); mContext.emitDeviceEvent("didCompleteNetworkResponse", args);
} }
private void onResponseReceived(int requestId, int code, WritableMap headers) { private void onResponseReceived(int requestId, int code, WritableMap headers) {
@ -137,11 +138,6 @@ public class NetworkRecordingModuleMock extends ReactContextBaseJavaModule {
args.pushInt(code); args.pushInt(code);
args.pushMap(headers); args.pushMap(headers);
getEventEmitter().emit("didReceiveNetworkResponse", args); mContext.emitDeviceEvent("didReceiveNetworkResponse", args);
}
private DeviceEventManagerModule.RCTDeviceEventEmitter getEventEmitter() {
return getReactApplicationContext()
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
} }
} }

Просмотреть файл

@ -554,9 +554,7 @@ public class ReactInstanceManager {
private void toggleElementInspector() { private void toggleElementInspector() {
ReactContext currentContext = getCurrentReactContext(); ReactContext currentContext = getCurrentReactContext();
if (currentContext != null && currentContext.hasActiveReactInstance()) { if (currentContext != null && currentContext.hasActiveReactInstance()) {
currentContext currentContext.emitDeviceEvent("toggleElementInspector");
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("toggleElementInspector", null);
} else { } else {
ReactSoftExceptionLogger.logSoftException( ReactSoftExceptionLogger.logSoftException(
TAG, TAG,

Просмотреть файл

@ -52,7 +52,6 @@ import com.facebook.react.bridge.WritableNativeMap;
import com.facebook.react.common.annotations.VisibleForTesting; import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.config.ReactFeatureFlags; import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.modules.appregistry.AppRegistry; import com.facebook.react.modules.appregistry.AppRegistry;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.modules.deviceinfo.DeviceInfoModule; import com.facebook.react.modules.deviceinfo.DeviceInfoModule;
import com.facebook.react.surface.ReactStage; import com.facebook.react.surface.ReactStage;
import com.facebook.react.uimanager.DisplayMetricsHolder; import com.facebook.react.uimanager.DisplayMetricsHolder;
@ -866,9 +865,7 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
/* package */ void sendEvent(String eventName, @Nullable WritableMap params) { /* package */ void sendEvent(String eventName, @Nullable WritableMap params) {
if (hasActiveReactInstance()) { if (hasActiveReactInstance()) {
getCurrentReactContext() getCurrentReactContext().emitDeviceEvent(eventName, params);
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
} }
} }

Просмотреть файл

@ -26,7 +26,6 @@ import com.facebook.react.bridge.UIManagerListener;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.annotations.VisibleForTesting; import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.modules.core.ReactChoreographer; import com.facebook.react.modules.core.ReactChoreographer;
import com.facebook.react.uimanager.GuardedFrameCallback; import com.facebook.react.uimanager.GuardedFrameCallback;
import com.facebook.react.uimanager.NativeViewHierarchyManager; import com.facebook.react.uimanager.NativeViewHierarchyManager;
@ -566,9 +565,7 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
ReactApplicationContext reactApplicationContext = ReactApplicationContext reactApplicationContext =
getReactApplicationContextIfActiveOrWarn(); getReactApplicationContextIfActiveOrWarn();
if (reactApplicationContext != null) { if (reactApplicationContext != null) {
reactApplicationContext reactApplicationContext.emitDeviceEvent("onAnimatedValueUpdate", onAnimatedValueData);
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("onAnimatedValueUpdate", onAnimatedValueData);
} }
} }
}; };
@ -1090,9 +1087,8 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
ReactApplicationContext reactApplicationContext = ReactApplicationContext reactApplicationContext =
getReactApplicationContextIfActiveOrWarn(); getReactApplicationContextIfActiveOrWarn();
if (reactApplicationContext != null) { if (reactApplicationContext != null) {
reactApplicationContext reactApplicationContext.emitDeviceEvent(
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) "onAnimatedValueUpdate", onAnimatedValueData);
.emit("onAnimatedValueUpdate", onAnimatedValueData);
} }
} }
}; };

Просмотреть файл

@ -23,7 +23,6 @@ import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.UIManager; import com.facebook.react.bridge.UIManager;
import com.facebook.react.bridge.UiThreadUtil; import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.uimanager.UIManagerHelper; import com.facebook.react.uimanager.UIManagerHelper;
import com.facebook.react.uimanager.common.UIManagerType; import com.facebook.react.uimanager.common.UIManagerType;
import com.facebook.react.uimanager.events.Event; import com.facebook.react.uimanager.events.Event;
@ -308,9 +307,8 @@ public class NativeAnimatedNodesManager implements EventDispatcherListener {
WritableMap params = Arguments.createMap(); WritableMap params = Arguments.createMap();
params.putInt("animationId", animation.mId); params.putInt("animationId", animation.mId);
params.putBoolean("finished", false); params.putBoolean("finished", false);
mReactApplicationContext mReactApplicationContext.emitDeviceEvent(
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) "onNativeAnimatedModuleAnimationFinished", params);
.emit("onNativeAnimatedModuleAnimationFinished", params);
} }
mActiveAnimations.removeAt(i); mActiveAnimations.removeAt(i);
i--; i--;
@ -339,9 +337,8 @@ public class NativeAnimatedNodesManager implements EventDispatcherListener {
WritableMap params = Arguments.createMap(); WritableMap params = Arguments.createMap();
params.putInt("animationId", animation.mId); params.putInt("animationId", animation.mId);
params.putBoolean("finished", false); params.putBoolean("finished", false);
mReactApplicationContext mReactApplicationContext.emitDeviceEvent(
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) "onNativeAnimatedModuleAnimationFinished", params);
.emit("onNativeAnimatedModuleAnimationFinished", params);
} }
mActiveAnimations.removeAt(i); mActiveAnimations.removeAt(i);
return; return;
@ -474,9 +471,7 @@ public class NativeAnimatedNodesManager implements EventDispatcherListener {
WritableMap params = Arguments.createMap(); WritableMap params = Arguments.createMap();
params.putInt("tag", tag); params.putInt("tag", tag);
params.putDouble("value", value); params.putDouble("value", value);
mReactApplicationContext mReactApplicationContext.emitDeviceEvent("onNativeAnimatedModuleGetValue", params);
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("onNativeAnimatedModuleGetValue", params);
} }
@UiThread @UiThread
@ -653,12 +648,8 @@ public class NativeAnimatedNodesManager implements EventDispatcherListener {
WritableMap params = Arguments.createMap(); WritableMap params = Arguments.createMap();
params.putInt("animationId", animation.mId); params.putInt("animationId", animation.mId);
params.putBoolean("finished", true); params.putBoolean("finished", true);
DeviceEventManagerModule.RCTDeviceEventEmitter eventEmitter = mReactApplicationContext.emitDeviceEvent(
mReactApplicationContext.getJSModule( "onNativeAnimatedModuleAnimationFinished", params);
DeviceEventManagerModule.RCTDeviceEventEmitter.class);
if (eventEmitter != null) {
eventEmitter.emit("onNativeAnimatedModuleAnimationFinished", params);
}
} }
mActiveAnimations.removeAt(i); mActiveAnimations.removeAt(i);
} }

Просмотреть файл

@ -24,7 +24,6 @@ import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule;
/** /**
* Module that monitors and provides information about the state of Touch Exploration service on the * Module that monitors and provides information about the state of Touch Exploration service on the
@ -130,9 +129,7 @@ public class AccessibilityInfoModule extends NativeAccessibilityInfoSpec
ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn(); ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn();
if (reactApplicationContext != null) { if (reactApplicationContext != null) {
reactApplicationContext reactApplicationContext.emitDeviceEvent(REDUCE_MOTION_EVENT_NAME, mReduceMotionEnabled);
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(REDUCE_MOTION_EVENT_NAME, mReduceMotionEnabled);
} }
} }
} }
@ -144,8 +141,7 @@ public class AccessibilityInfoModule extends NativeAccessibilityInfoSpec
ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn(); ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn();
if (reactApplicationContext != null) { if (reactApplicationContext != null) {
getReactApplicationContext() getReactApplicationContext()
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emitDeviceEvent(TOUCH_EXPLORATION_EVENT_NAME, mTouchExplorationEnabled);
.emit(TOUCH_EXPLORATION_EVENT_NAME, mTouchExplorationEnabled);
} }
} }
} }
@ -157,8 +153,7 @@ public class AccessibilityInfoModule extends NativeAccessibilityInfoSpec
ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn(); ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn();
if (reactApplicationContext != null) { if (reactApplicationContext != null) {
getReactApplicationContext() getReactApplicationContext()
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emitDeviceEvent(ACCESSIBILITY_SERVICE_EVENT_NAME, mAccessibilityServiceEnabled);
.emit(ACCESSIBILITY_SERVICE_EVENT_NAME, mAccessibilityServiceEnabled);
} }
} }
} }

Просмотреть файл

@ -16,7 +16,6 @@ import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;
/** Module that exposes the user's preferred color scheme. */ /** Module that exposes the user's preferred color scheme. */
@ReactModule(name = NativeAppearanceSpec.NAME) @ReactModule(name = NativeAppearanceSpec.NAME)
@ -108,9 +107,7 @@ public class AppearanceModule extends NativeAppearanceSpec {
ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn(); ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn();
if (reactApplicationContext != null) { if (reactApplicationContext != null) {
reactApplicationContext reactApplicationContext.emitDeviceEvent(APPEARANCE_CHANGED_EVENT_NAME, appearancePreferences);
.getJSModule(RCTDeviceEventEmitter.class)
.emit(APPEARANCE_CHANGED_EVENT_NAME, appearancePreferences);
} }
} }
} }

Просмотреть файл

@ -16,7 +16,6 @@ import com.facebook.react.bridge.WindowFocusChangeListener;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.LifecycleState; import com.facebook.react.common.LifecycleState;
import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -96,7 +95,7 @@ public class AppStateModule extends NativeAppStateSpec
if (!reactApplicationContext.hasActiveReactInstance()) { if (!reactApplicationContext.hasActiveReactInstance()) {
return; return;
} }
reactApplicationContext.getJSModule(RCTDeviceEventEmitter.class).emit(eventName, data); reactApplicationContext.emitDeviceEvent(eventName, data);
} }
private void sendAppStateChangeEvent() { private void sendAppStateChangeEvent() {

Просмотреть файл

@ -47,9 +47,7 @@ public class DeviceEventManagerModule extends NativeDeviceEventManagerSpec {
ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn(); ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn();
if (reactApplicationContext != null) { if (reactApplicationContext != null) {
reactApplicationContext reactApplicationContext.emitDeviceEvent("hardwareBackPress", null);
.getJSModule(RCTDeviceEventEmitter.class)
.emit("hardwareBackPress", null);
} }
} }
@ -60,7 +58,7 @@ public class DeviceEventManagerModule extends NativeDeviceEventManagerSpec {
if (reactApplicationContext != null) { if (reactApplicationContext != null) {
WritableMap map = Arguments.createMap(); WritableMap map = Arguments.createMap();
map.putString("url", uri.toString()); map.putString("url", uri.toString());
reactApplicationContext.getJSModule(RCTDeviceEventEmitter.class).emit("url", map); reactApplicationContext.emitDeviceEvent("url", map);
} }
} }

Просмотреть файл

@ -15,7 +15,6 @@ import com.facebook.react.bridge.WritableMap;
import com.facebook.react.devsupport.interfaces.DevOptionHandler; import com.facebook.react.devsupport.interfaces.DevOptionHandler;
import com.facebook.react.devsupport.interfaces.DevSupportManager; import com.facebook.react.devsupport.interfaces.DevSupportManager;
import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;
/** /**
* Module that exposes the URL to the source code map (used for exception stack trace parsing) to JS * Module that exposes the URL to the source code map (used for exception stack trace parsing) to JS
@ -89,9 +88,7 @@ public class DevSettingsModule extends NativeDevSettingsSpec {
getReactApplicationContextIfActiveOrWarn(); getReactApplicationContextIfActiveOrWarn();
if (reactApplicationContext != null) { if (reactApplicationContext != null) {
reactApplicationContext reactApplicationContext.emitDeviceEvent("didPressMenuItem", data);
.getJSModule(RCTDeviceEventEmitter.class)
.emit("didPressMenuItem", data);
} }
} }
}); });

Просмотреть файл

@ -17,7 +17,6 @@ import com.facebook.react.bridge.ReactSoftExceptionLogger;
import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.uimanager.DisplayMetricsHolder; import com.facebook.react.uimanager.DisplayMetricsHolder;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -89,9 +88,7 @@ public class DeviceInfoModule extends NativeDeviceInfoSpec implements LifecycleE
mPreviousDisplayMetrics = displayMetrics.copy(); mPreviousDisplayMetrics = displayMetrics.copy();
} else if (!displayMetrics.equals(mPreviousDisplayMetrics)) { } else if (!displayMetrics.equals(mPreviousDisplayMetrics)) {
mPreviousDisplayMetrics = displayMetrics.copy(); mPreviousDisplayMetrics = displayMetrics.copy();
mReactApplicationContext mReactApplicationContext.emitDeviceEvent("didUpdateDimensions", displayMetrics);
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("didUpdateDimensions", displayMetrics);
} }
} else { } else {
ReactSoftExceptionLogger.logSoftException( ReactSoftExceptionLogger.logSoftException(

Просмотреть файл

@ -23,7 +23,6 @@ import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.StandardCharsets; import com.facebook.react.common.StandardCharsets;
import com.facebook.react.common.network.OkHttpCallUtil; import com.facebook.react.common.network.OkHttpCallUtil;
import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset; import java.nio.charset.Charset;
@ -246,10 +245,9 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
withCredentials); withCredentials);
} catch (Throwable th) { } catch (Throwable th) {
FLog.e(TAG, "Failed to send url request: " + url, th); FLog.e(TAG, "Failed to send url request: " + url, th);
final RCTDeviceEventEmitter eventEmitter = getEventEmitter("sendRequest error");
if (eventEmitter != null) { ResponseUtil.onRequestError(
ResponseUtil.onRequestError(eventEmitter, requestId, th.getMessage(), th); getReactApplicationContextIfActiveOrWarn(), requestId, th.getMessage(), th);
}
} }
} }
@ -264,8 +262,8 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
final boolean useIncrementalUpdates, final boolean useIncrementalUpdates,
int timeout, int timeout,
boolean withCredentials) { boolean withCredentials) {
final RCTDeviceEventEmitter eventEmitter = getEventEmitter("sendRequestInternal"); final ReactApplicationContext reactApplicationContext =
getReactApplicationContextIfActiveOrWarn();
try { try {
Uri uri = Uri.parse(url); Uri uri = Uri.parse(url);
@ -273,13 +271,13 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
for (UriHandler handler : mUriHandlers) { for (UriHandler handler : mUriHandlers) {
if (handler.supports(uri, responseType)) { if (handler.supports(uri, responseType)) {
WritableMap res = handler.fetch(uri); WritableMap res = handler.fetch(uri);
ResponseUtil.onDataReceived(eventEmitter, requestId, res); ResponseUtil.onDataReceived(reactApplicationContext, requestId, res);
ResponseUtil.onRequestSuccess(eventEmitter, requestId); ResponseUtil.onRequestSuccess(reactApplicationContext, requestId);
return; return;
} }
} }
} catch (IOException e) { } catch (IOException e) {
ResponseUtil.onRequestError(eventEmitter, requestId, e.getMessage(), e); ResponseUtil.onRequestError(reactApplicationContext, requestId, e.getMessage(), e);
return; return;
} }
@ -287,7 +285,7 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
try { try {
requestBuilder = new Request.Builder().url(url); requestBuilder = new Request.Builder().url(url);
} catch (Exception e) { } catch (Exception e) {
ResponseUtil.onRequestError(eventEmitter, requestId, e.getMessage(), null); ResponseUtil.onRequestError(reactApplicationContext, requestId, e.getMessage(), null);
return; return;
} }
@ -331,7 +329,7 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
return; return;
} }
ResponseUtil.onDataReceivedProgress( ResponseUtil.onDataReceivedProgress(
eventEmitter, requestId, bytesWritten, contentLength); reactApplicationContext, requestId, bytesWritten, contentLength);
last = now; last = now;
} }
}); });
@ -351,7 +349,8 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
Headers requestHeaders = extractHeaders(headers, data); Headers requestHeaders = extractHeaders(headers, data);
if (requestHeaders == null) { if (requestHeaders == null) {
ResponseUtil.onRequestError(eventEmitter, requestId, "Unrecognized headers format", null); ResponseUtil.onRequestError(
reactApplicationContext, requestId, "Unrecognized headers format", null);
return; return;
} }
String contentType = requestHeaders.get(CONTENT_TYPE_HEADER_NAME); String contentType = requestHeaders.get(CONTENT_TYPE_HEADER_NAME);
@ -379,7 +378,10 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
} else if (data.hasKey(REQUEST_BODY_KEY_STRING)) { } else if (data.hasKey(REQUEST_BODY_KEY_STRING)) {
if (contentType == null) { if (contentType == null) {
ResponseUtil.onRequestError( ResponseUtil.onRequestError(
eventEmitter, requestId, "Payload is set but no content-type header specified", null); reactApplicationContext,
requestId,
"Payload is set but no content-type header specified",
null);
return; return;
} }
String body = data.getString(REQUEST_BODY_KEY_STRING); String body = data.getString(REQUEST_BODY_KEY_STRING);
@ -387,7 +389,8 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
if (RequestBodyUtil.isGzipEncoding(contentEncoding)) { if (RequestBodyUtil.isGzipEncoding(contentEncoding)) {
requestBody = RequestBodyUtil.createGzip(contentMediaType, body); requestBody = RequestBodyUtil.createGzip(contentMediaType, body);
if (requestBody == null) { if (requestBody == null) {
ResponseUtil.onRequestError(eventEmitter, requestId, "Failed to gzip request body", null); ResponseUtil.onRequestError(
reactApplicationContext, requestId, "Failed to gzip request body", null);
return; return;
} }
} else { } else {
@ -403,7 +406,10 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
} else if (data.hasKey(REQUEST_BODY_KEY_BASE64)) { } else if (data.hasKey(REQUEST_BODY_KEY_BASE64)) {
if (contentType == null) { if (contentType == null) {
ResponseUtil.onRequestError( ResponseUtil.onRequestError(
eventEmitter, requestId, "Payload is set but no content-type header specified", null); reactApplicationContext,
requestId,
"Payload is set but no content-type header specified",
null);
return; return;
} }
String base64String = data.getString(REQUEST_BODY_KEY_BASE64); String base64String = data.getString(REQUEST_BODY_KEY_BASE64);
@ -412,7 +418,10 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
} else if (data.hasKey(REQUEST_BODY_KEY_URI)) { } else if (data.hasKey(REQUEST_BODY_KEY_URI)) {
if (contentType == null) { if (contentType == null) {
ResponseUtil.onRequestError( ResponseUtil.onRequestError(
eventEmitter, requestId, "Payload is set but no content-type header specified", null); reactApplicationContext,
requestId,
"Payload is set but no content-type header specified",
null);
return; return;
} }
String uri = data.getString(REQUEST_BODY_KEY_URI); String uri = data.getString(REQUEST_BODY_KEY_URI);
@ -420,7 +429,7 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
RequestBodyUtil.getFileInputStream(getReactApplicationContext(), uri); RequestBodyUtil.getFileInputStream(getReactApplicationContext(), uri);
if (fileInputStream == null) { if (fileInputStream == null) {
ResponseUtil.onRequestError( ResponseUtil.onRequestError(
eventEmitter, requestId, "Could not retrieve file for uri " + uri, null); reactApplicationContext, requestId, "Could not retrieve file for uri " + uri, null);
return; return;
} }
requestBody = RequestBodyUtil.create(MediaType.parse(contentType), fileInputStream); requestBody = RequestBodyUtil.create(MediaType.parse(contentType), fileInputStream);
@ -440,8 +449,7 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
requestBody = RequestBodyUtil.getEmptyBody(method); requestBody = RequestBodyUtil.getEmptyBody(method);
} }
requestBuilder.method( requestBuilder.method(method, wrapRequestBodyWithProgressEmitter(requestBody, requestId));
method, wrapRequestBodyWithProgressEmitter(requestBody, eventEmitter, requestId));
addRequest(requestId); addRequest(requestId);
client client
@ -458,7 +466,7 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
e.getMessage() != null e.getMessage() != null
? e.getMessage() ? e.getMessage()
: "Error while executing request: " + e.getClass().getSimpleName(); : "Error while executing request: " + e.getClass().getSimpleName();
ResponseUtil.onRequestError(eventEmitter, requestId, errorMessage, e); ResponseUtil.onRequestError(reactApplicationContext, requestId, errorMessage, e);
} }
@Override @Override
@ -469,7 +477,7 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
removeRequest(requestId); removeRequest(requestId);
// Before we touch the body send headers to JS // Before we touch the body send headers to JS
ResponseUtil.onResponseReceived( ResponseUtil.onResponseReceived(
eventEmitter, reactApplicationContext,
requestId, requestId,
response.code(), response.code(),
translateHeaders(response.headers()), translateHeaders(response.headers()),
@ -506,8 +514,8 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
for (ResponseHandler handler : mResponseHandlers) { for (ResponseHandler handler : mResponseHandlers) {
if (handler.supports(responseType)) { if (handler.supports(responseType)) {
WritableMap res = handler.toResponseData(responseBody); WritableMap res = handler.toResponseData(responseBody);
ResponseUtil.onDataReceived(eventEmitter, requestId, res); ResponseUtil.onDataReceived(reactApplicationContext, requestId, res);
ResponseUtil.onRequestSuccess(eventEmitter, requestId); ResponseUtil.onRequestSuccess(reactApplicationContext, requestId);
return; return;
} }
} }
@ -516,8 +524,8 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
// response, // response,
// periodically send response data updates to JS. // periodically send response data updates to JS.
if (useIncrementalUpdates && responseType.equals("text")) { if (useIncrementalUpdates && responseType.equals("text")) {
readWithProgress(eventEmitter, requestId, responseBody); readWithProgress(requestId, responseBody);
ResponseUtil.onRequestSuccess(eventEmitter, requestId); ResponseUtil.onRequestSuccess(reactApplicationContext, requestId);
return; return;
} }
@ -534,28 +542,30 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
// Javascript layer. // Javascript layer.
// Introduced to fix issue #7463. // Introduced to fix issue #7463.
} else { } else {
ResponseUtil.onRequestError(eventEmitter, requestId, e.getMessage(), e); ResponseUtil.onRequestError(
reactApplicationContext, requestId, e.getMessage(), e);
} }
} }
} else if (responseType.equals("base64")) { } else if (responseType.equals("base64")) {
responseString = Base64.encodeToString(responseBody.bytes(), Base64.NO_WRAP); responseString = Base64.encodeToString(responseBody.bytes(), Base64.NO_WRAP);
} }
ResponseUtil.onDataReceived(eventEmitter, requestId, responseString); ResponseUtil.onDataReceived(reactApplicationContext, requestId, responseString);
ResponseUtil.onRequestSuccess(eventEmitter, requestId); ResponseUtil.onRequestSuccess(reactApplicationContext, requestId);
} catch (IOException e) { } catch (IOException e) {
ResponseUtil.onRequestError(eventEmitter, requestId, e.getMessage(), e); ResponseUtil.onRequestError(
reactApplicationContext, requestId, e.getMessage(), e);
} }
} }
}); });
} }
private RequestBody wrapRequestBodyWithProgressEmitter( private RequestBody wrapRequestBodyWithProgressEmitter(
final RequestBody requestBody, final RequestBody requestBody, final int requestId) {
final RCTDeviceEventEmitter eventEmitter,
final int requestId) {
if (requestBody == null) { if (requestBody == null) {
return null; return null;
} }
final ReactApplicationContext reactApplicationContext =
getReactApplicationContextIfActiveOrWarn();
return RequestBodyUtil.createProgressRequest( return RequestBodyUtil.createProgressRequest(
requestBody, requestBody,
new ProgressListener() { new ProgressListener() {
@ -565,16 +575,15 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
public void onProgress(long bytesWritten, long contentLength, boolean done) { public void onProgress(long bytesWritten, long contentLength, boolean done) {
long now = System.nanoTime(); long now = System.nanoTime();
if (done || shouldDispatch(now, last)) { if (done || shouldDispatch(now, last)) {
ResponseUtil.onDataSend(eventEmitter, requestId, bytesWritten, contentLength); ResponseUtil.onDataSend(
reactApplicationContext, requestId, bytesWritten, contentLength);
last = now; last = now;
} }
} }
}); });
} }
private void readWithProgress( private void readWithProgress(int requestId, ResponseBody responseBody) throws IOException {
RCTDeviceEventEmitter eventEmitter, int requestId, ResponseBody responseBody)
throws IOException {
long totalBytesRead = -1; long totalBytesRead = -1;
long contentLength = -1; long contentLength = -1;
try { try {
@ -595,9 +604,11 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
try { try {
byte[] buffer = new byte[MAX_CHUNK_SIZE_BETWEEN_FLUSHES]; byte[] buffer = new byte[MAX_CHUNK_SIZE_BETWEEN_FLUSHES];
int read; int read;
final ReactApplicationContext reactApplicationContext =
getReactApplicationContextIfActiveOrWarn();
while ((read = inputStream.read(buffer)) != -1) { while ((read = inputStream.read(buffer)) != -1) {
ResponseUtil.onIncrementalDataReceived( ResponseUtil.onIncrementalDataReceived(
eventEmitter, reactApplicationContext,
requestId, requestId,
streamDecoder.decodeNext(buffer, read), streamDecoder.decodeNext(buffer, read),
totalBytesRead, totalBytesRead,
@ -673,10 +684,12 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
private @Nullable MultipartBody.Builder constructMultipartBody( private @Nullable MultipartBody.Builder constructMultipartBody(
ReadableArray body, String contentType, int requestId) { ReadableArray body, String contentType, int requestId) {
RCTDeviceEventEmitter eventEmitter = getEventEmitter("constructMultipartBody");
MultipartBody.Builder multipartBuilder = new MultipartBody.Builder(); MultipartBody.Builder multipartBuilder = new MultipartBody.Builder();
multipartBuilder.setType(MediaType.parse(contentType)); multipartBuilder.setType(MediaType.parse(contentType));
final ReactApplicationContext reactApplicationContext =
getReactApplicationContextIfActiveOrWarn();
for (int i = 0, size = body.size(); i < size; i++) { for (int i = 0, size = body.size(); i < size; i++) {
ReadableMap bodyPart = body.getMap(i); ReadableMap bodyPart = body.getMap(i);
@ -685,7 +698,10 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
Headers headers = extractHeaders(headersArray, null); Headers headers = extractHeaders(headersArray, null);
if (headers == null) { if (headers == null) {
ResponseUtil.onRequestError( ResponseUtil.onRequestError(
eventEmitter, requestId, "Missing or invalid header format for FormData part.", null); reactApplicationContext,
requestId,
"Missing or invalid header format for FormData part.",
null);
return null; return null;
} }
MediaType partContentType = null; MediaType partContentType = null;
@ -703,7 +719,10 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
} else if (bodyPart.hasKey(REQUEST_BODY_KEY_URI)) { } else if (bodyPart.hasKey(REQUEST_BODY_KEY_URI)) {
if (partContentType == null) { if (partContentType == null) {
ResponseUtil.onRequestError( ResponseUtil.onRequestError(
eventEmitter, requestId, "Binary FormData part needs a content-type header.", null); reactApplicationContext,
requestId,
"Binary FormData part needs a content-type header.",
null);
return null; return null;
} }
String fileContentUriStr = bodyPart.getString(REQUEST_BODY_KEY_URI); String fileContentUriStr = bodyPart.getString(REQUEST_BODY_KEY_URI);
@ -711,7 +730,7 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
RequestBodyUtil.getFileInputStream(getReactApplicationContext(), fileContentUriStr); RequestBodyUtil.getFileInputStream(getReactApplicationContext(), fileContentUriStr);
if (fileInputStream == null) { if (fileInputStream == null) {
ResponseUtil.onRequestError( ResponseUtil.onRequestError(
eventEmitter, reactApplicationContext,
requestId, requestId,
"Could not retrieve file for uri " + fileContentUriStr, "Could not retrieve file for uri " + fileContentUriStr,
null); null);
@ -719,7 +738,8 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
} }
multipartBuilder.addPart(headers, RequestBodyUtil.create(partContentType, fileInputStream)); multipartBuilder.addPart(headers, RequestBodyUtil.create(partContentType, fileInputStream));
} else { } else {
ResponseUtil.onRequestError(eventEmitter, requestId, "Unrecognized FormData part.", null); ResponseUtil.onRequestError(
reactApplicationContext, requestId, "Unrecognized FormData part.", null);
} }
} }
return multipartBuilder; return multipartBuilder;
@ -758,14 +778,4 @@ public final class NetworkingModule extends NativeNetworkingAndroidSpec {
return headersBuilder.build(); return headersBuilder.build();
} }
private RCTDeviceEventEmitter getEventEmitter(String reason) {
ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn();
if (reactApplicationContext != null) {
return getReactApplicationContext().getJSModule(RCTDeviceEventEmitter.class);
}
return null;
}
} }

Просмотреть файл

@ -9,26 +9,26 @@ package com.facebook.react.modules.network;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
/** Util methods to send network responses to JS. */ /** Util methods to send network responses to JS. */
public class ResponseUtil { public class ResponseUtil {
public static void onDataSend( public static void onDataSend(
@Nullable RCTDeviceEventEmitter eventEmitter, int requestId, long progress, long total) { @Nullable ReactApplicationContext reactContext, int requestId, long progress, long total) {
WritableArray args = Arguments.createArray(); WritableArray args = Arguments.createArray();
args.pushInt(requestId); args.pushInt(requestId);
args.pushInt((int) progress); args.pushInt((int) progress);
args.pushInt((int) total); args.pushInt((int) total);
if (eventEmitter != null) { if (reactContext != null) {
eventEmitter.emit("didSendNetworkData", args); reactContext.emitDeviceEvent("didSendNetworkData", args);
} }
} }
public static void onIncrementalDataReceived( public static void onIncrementalDataReceived(
@Nullable RCTDeviceEventEmitter eventEmitter, @Nullable ReactApplicationContext reactContext,
int requestId, int requestId,
String data, String data,
long progress, long progress,
@ -39,47 +39,47 @@ public class ResponseUtil {
args.pushInt((int) progress); args.pushInt((int) progress);
args.pushInt((int) total); args.pushInt((int) total);
if (eventEmitter != null) { if (reactContext != null) {
eventEmitter.emit("didReceiveNetworkIncrementalData", args); reactContext.emitDeviceEvent("didReceiveNetworkIncrementalData", args);
} }
} }
public static void onDataReceivedProgress( public static void onDataReceivedProgress(
@Nullable RCTDeviceEventEmitter eventEmitter, int requestId, long progress, long total) { @Nullable ReactApplicationContext reactContext, int requestId, long progress, long total) {
WritableArray args = Arguments.createArray(); WritableArray args = Arguments.createArray();
args.pushInt(requestId); args.pushInt(requestId);
args.pushInt((int) progress); args.pushInt((int) progress);
args.pushInt((int) total); args.pushInt((int) total);
if (eventEmitter != null) { if (reactContext != null) {
eventEmitter.emit("didReceiveNetworkDataProgress", args); reactContext.emitDeviceEvent("didReceiveNetworkDataProgress", args);
} }
} }
public static void onDataReceived( public static void onDataReceived(
@Nullable RCTDeviceEventEmitter eventEmitter, int requestId, String data) { @Nullable ReactApplicationContext reactContext, int requestId, String data) {
WritableArray args = Arguments.createArray(); WritableArray args = Arguments.createArray();
args.pushInt(requestId); args.pushInt(requestId);
args.pushString(data); args.pushString(data);
if (eventEmitter != null) { if (reactContext != null) {
eventEmitter.emit("didReceiveNetworkData", args); reactContext.emitDeviceEvent("didReceiveNetworkData", args);
} }
} }
public static void onDataReceived( public static void onDataReceived(
@Nullable RCTDeviceEventEmitter eventEmitter, int requestId, WritableMap data) { @Nullable ReactApplicationContext reactContext, int requestId, WritableMap data) {
WritableArray args = Arguments.createArray(); WritableArray args = Arguments.createArray();
args.pushInt(requestId); args.pushInt(requestId);
args.pushMap(data); args.pushMap(data);
if (eventEmitter != null) { if (reactContext != null) {
eventEmitter.emit("didReceiveNetworkData", args); reactContext.emitDeviceEvent("didReceiveNetworkData", args);
} }
} }
public static void onRequestError( public static void onRequestError(
@Nullable RCTDeviceEventEmitter eventEmitter, int requestId, String error, Throwable e) { @Nullable ReactApplicationContext reactContext, int requestId, String error, Throwable e) {
WritableArray args = Arguments.createArray(); WritableArray args = Arguments.createArray();
args.pushInt(requestId); args.pushInt(requestId);
args.pushString(error); args.pushString(error);
@ -88,23 +88,24 @@ public class ResponseUtil {
args.pushBoolean(true); // last argument is a time out boolean args.pushBoolean(true); // last argument is a time out boolean
} }
if (eventEmitter != null) { if (reactContext != null) {
eventEmitter.emit("didCompleteNetworkResponse", args); reactContext.emitDeviceEvent("didCompleteNetworkResponse", args);
} }
} }
public static void onRequestSuccess(@Nullable RCTDeviceEventEmitter eventEmitter, int requestId) { public static void onRequestSuccess(
@Nullable ReactApplicationContext reactContext, int requestId) {
WritableArray args = Arguments.createArray(); WritableArray args = Arguments.createArray();
args.pushInt(requestId); args.pushInt(requestId);
args.pushNull(); args.pushNull();
if (eventEmitter != null) { if (reactContext != null) {
eventEmitter.emit("didCompleteNetworkResponse", args); reactContext.emitDeviceEvent("didCompleteNetworkResponse", args);
} }
} }
public static void onResponseReceived( public static void onResponseReceived(
@Nullable RCTDeviceEventEmitter eventEmitter, @Nullable ReactApplicationContext reactContext,
int requestId, int requestId,
int statusCode, int statusCode,
WritableMap headers, WritableMap headers,
@ -115,8 +116,8 @@ public class ResponseUtil {
args.pushMap(headers); args.pushMap(headers);
args.pushString(url); args.pushString(url);
if (eventEmitter != null) { if (reactContext != null) {
eventEmitter.emit("didReceiveNetworkResponse", args); reactContext.emitDeviceEvent("didReceiveNetworkResponse", args);
} }
} }
} }

Просмотреть файл

@ -19,7 +19,6 @@ import com.facebook.react.bridge.ReadableType;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.ReactConstants; import com.facebook.react.common.ReactConstants;
import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.modules.network.ForwardingCookieHandler; import com.facebook.react.modules.network.ForwardingCookieHandler;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
@ -66,9 +65,7 @@ public final class WebSocketModule extends NativeWebSocketModuleSpec {
private void sendEvent(String eventName, WritableMap params) { private void sendEvent(String eventName, WritableMap params) {
ReactApplicationContext reactApplicationContext = getReactApplicationContext(); ReactApplicationContext reactApplicationContext = getReactApplicationContext();
if (reactApplicationContext.hasActiveReactInstance()) { if (reactApplicationContext.hasActiveReactInstance()) {
reactApplicationContext reactApplicationContext.emitDeviceEvent(eventName, params);
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
} }
} }

Просмотреть файл

@ -12,6 +12,7 @@ import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq; import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset; import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ -28,7 +29,6 @@ import com.facebook.react.bridge.ReactTestHelper;
import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.SystemClock; import com.facebook.react.common.SystemClock;
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;
import com.facebook.react.uimanager.DisplayMetricsHolder; import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.events.Event; import com.facebook.react.uimanager.events.Event;
@ -91,7 +91,7 @@ public class RootViewTest {
}); });
mCatalystInstanceMock = ReactTestHelper.createMockCatalystInstance(); mCatalystInstanceMock = ReactTestHelper.createMockCatalystInstance();
mReactContext = new ReactApplicationContext(RuntimeEnvironment.application); mReactContext = spy(new ReactApplicationContext(RuntimeEnvironment.application));
mReactContext.initializeWithInstance(mCatalystInstanceMock); mReactContext.initializeWithInstance(mCatalystInstanceMock);
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(mReactContext); DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(mReactContext);
@ -217,11 +217,8 @@ public class RootViewTest {
@Test @Test
public void testCheckForKeyboardEvents() { public void testCheckForKeyboardEvents() {
ReactInstanceManager instanceManager = mock(ReactInstanceManager.class); ReactInstanceManager instanceManager = mock(ReactInstanceManager.class);
RCTDeviceEventEmitter eventEmitterModuleMock = mock(RCTDeviceEventEmitter.class);
when(instanceManager.getCurrentReactContext()).thenReturn(mReactContext); when(instanceManager.getCurrentReactContext()).thenReturn(mReactContext);
when(mReactContext.getJSModule(RCTDeviceEventEmitter.class)).thenReturn(eventEmitterModuleMock);
ReactRootView rootView = ReactRootView rootView =
new ReactRootView(mReactContext) { new ReactRootView(mReactContext) {
@Override @Override
@ -250,6 +247,6 @@ public class RootViewTest {
params.putMap("endCoordinates", endCoordinates); params.putMap("endCoordinates", endCoordinates);
params.putString("easing", "keyboard"); params.putString("easing", "keyboard");
verify(eventEmitterModuleMock, Mockito.times(1)).emit("keyboardDidShow", params); verify(mReactContext, Mockito.times(1)).emitDeviceEvent("keyboardDidShow", params);
} }
} }

Просмотреть файл

@ -9,11 +9,11 @@ package com.facebook.react.modules.deviceinfo;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock; import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.mockStatic;
@ -23,7 +23,6 @@ import com.facebook.react.bridge.JavaOnlyMap;
import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactTestHelper; import com.facebook.react.bridge.ReactTestHelper;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.uimanager.DisplayMetricsHolder; import com.facebook.react.uimanager.DisplayMetricsHolder;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -50,27 +49,22 @@ public class DeviceInfoModuleTest extends TestCase {
@Rule public PowerMockRule rule = new PowerMockRule(); @Rule public PowerMockRule rule = new PowerMockRule();
private DeviceInfoModule mDeviceInfoModule; private DeviceInfoModule mDeviceInfoModule;
private DeviceEventManagerModule.RCTDeviceEventEmitter mRCTDeviceEventEmitterMock;
private WritableMap fakePortraitDisplayMetrics; private WritableMap fakePortraitDisplayMetrics;
private WritableMap fakeLandscapeDisplayMetrics; private WritableMap fakeLandscapeDisplayMetrics;
private ReactApplicationContext mContext;
@Before @Before
public void setUp() { public void setUp() {
initTestData(); initTestData();
mockStatic(DisplayMetricsHolder.class); mockStatic(DisplayMetricsHolder.class);
mContext = spy(new ReactApplicationContext(RuntimeEnvironment.application));
mRCTDeviceEventEmitterMock = mock(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
final ReactApplicationContext context =
spy(new ReactApplicationContext(RuntimeEnvironment.application));
CatalystInstance catalystInstanceMock = ReactTestHelper.createMockCatalystInstance(); CatalystInstance catalystInstanceMock = ReactTestHelper.createMockCatalystInstance();
context.initializeWithInstance(catalystInstanceMock); mContext.initializeWithInstance(catalystInstanceMock);
when(context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class))
.thenReturn(mRCTDeviceEventEmitterMock);
mDeviceInfoModule = new DeviceInfoModule(context); mDeviceInfoModule = new DeviceInfoModule(mContext);
} }
@After @After
@ -86,7 +80,7 @@ public class DeviceInfoModuleTest extends TestCase {
mDeviceInfoModule.getTypedExportedConstants(); mDeviceInfoModule.getTypedExportedConstants();
mDeviceInfoModule.emitUpdateDimensionsEvent(); mDeviceInfoModule.emitUpdateDimensionsEvent();
verifyNoMoreInteractions(mRCTDeviceEventEmitterMock); verify(mContext, times(0)).emitDeviceEvent(anyString(), anyObject());
} }
@Test @Test
@ -97,7 +91,7 @@ public class DeviceInfoModuleTest extends TestCase {
givenDisplayMetricsHolderContains(fakeLandscapeDisplayMetrics); givenDisplayMetricsHolderContains(fakeLandscapeDisplayMetrics);
mDeviceInfoModule.emitUpdateDimensionsEvent(); mDeviceInfoModule.emitUpdateDimensionsEvent();
verifyUpdateDimensionsEventsEmitted(mRCTDeviceEventEmitterMock, fakeLandscapeDisplayMetrics); verifyUpdateDimensionsEventsEmitted(mContext, fakeLandscapeDisplayMetrics);
} }
@Test @Test
@ -108,7 +102,7 @@ public class DeviceInfoModuleTest extends TestCase {
mDeviceInfoModule.emitUpdateDimensionsEvent(); mDeviceInfoModule.emitUpdateDimensionsEvent();
mDeviceInfoModule.emitUpdateDimensionsEvent(); mDeviceInfoModule.emitUpdateDimensionsEvent();
verifyUpdateDimensionsEventsEmitted(mRCTDeviceEventEmitterMock, fakeLandscapeDisplayMetrics); verifyUpdateDimensionsEventsEmitted(mContext, fakeLandscapeDisplayMetrics);
} }
@Test @Test
@ -125,7 +119,7 @@ public class DeviceInfoModuleTest extends TestCase {
mDeviceInfoModule.emitUpdateDimensionsEvent(); mDeviceInfoModule.emitUpdateDimensionsEvent();
verifyUpdateDimensionsEventsEmitted( verifyUpdateDimensionsEventsEmitted(
mRCTDeviceEventEmitterMock, mContext,
fakeLandscapeDisplayMetrics, fakeLandscapeDisplayMetrics,
fakePortraitDisplayMetrics, fakePortraitDisplayMetrics,
fakeLandscapeDisplayMetrics); fakeLandscapeDisplayMetrics);
@ -136,11 +130,11 @@ public class DeviceInfoModuleTest extends TestCase {
} }
private static void verifyUpdateDimensionsEventsEmitted( private static void verifyUpdateDimensionsEventsEmitted(
DeviceEventManagerModule.RCTDeviceEventEmitter emitter, WritableMap... expectedEvents) { ReactApplicationContext context, WritableMap... expectedEvents) {
List<WritableMap> expectedEventList = Arrays.asList(expectedEvents); List<WritableMap> expectedEventList = Arrays.asList(expectedEvents);
ArgumentCaptor<WritableMap> captor = ArgumentCaptor.forClass(WritableMap.class); ArgumentCaptor<WritableMap> captor = ArgumentCaptor.forClass(WritableMap.class);
verify(emitter, times(expectedEventList.size())) verify(context, times(expectedEventList.size()))
.emit(eq("didUpdateDimensions"), captor.capture()); .emitDeviceEvent(eq("didUpdateDimensions"), captor.capture());
List<WritableMap> actualEvents = captor.getAllValues(); List<WritableMap> actualEvents = captor.getAllValues();
assertThat(actualEvents).isEqualTo(expectedEventList); assertThat(actualEvents).isEqualTo(expectedEventList);

Просмотреть файл

@ -25,7 +25,6 @@ import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.StandardCharsets; import com.facebook.react.common.StandardCharsets;
import com.facebook.react.common.network.OkHttpCallUtil; import com.facebook.react.common.network.OkHttpCallUtil;
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;
import java.io.InputStream; import java.io.InputStream;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -70,7 +69,7 @@ import org.robolectric.RobolectricTestRunner;
public class NetworkingModuleTest { public class NetworkingModuleTest {
private NetworkingModule mNetworkingModule; private NetworkingModule mNetworkingModule;
private OkHttpClient mHttpClient; private OkHttpClient mHttpClient;
private RCTDeviceEventEmitter mEmitter; private ReactApplicationContext mContext;
@Rule public PowerMockRule rule = new PowerMockRule(); @Rule public PowerMockRule rule = new PowerMockRule();
@ -91,14 +90,12 @@ public class NetworkingModuleTest {
PowerMockito.when(clientBuilder.build()).thenReturn(mHttpClient); PowerMockito.when(clientBuilder.build()).thenReturn(mHttpClient);
when(mHttpClient.newBuilder()).thenReturn(clientBuilder); when(mHttpClient.newBuilder()).thenReturn(clientBuilder);
mEmitter = mock(RCTDeviceEventEmitter.class);
CatalystInstance reactInstance = mock(CatalystInstance.class); CatalystInstance reactInstance = mock(CatalystInstance.class);
ReactApplicationContext reactContext = mock(ReactApplicationContext.class);
when(reactContext.getCatalystInstance()).thenReturn(reactInstance); mContext = mock(ReactApplicationContext.class);
when(reactContext.hasActiveReactInstance()).thenReturn(true); when(mContext.getCatalystInstance()).thenReturn(reactInstance);
when(reactContext.getJSModule(any(Class.class))).thenReturn(mEmitter); when(mContext.hasActiveReactInstance()).thenReturn(true);
mNetworkingModule = new NetworkingModule(reactContext, "", mHttpClient); mNetworkingModule = new NetworkingModule(mContext, "", mHttpClient);
} }
@Test @Test
@ -139,7 +136,7 @@ public class NetworkingModuleTest {
/* timeout */ 0, /* timeout */ 0,
/* withCredentials */ false); /* withCredentials */ false);
verifyErrorEmit(mEmitter, 0); verifyErrorEmit(mContext, 0);
} }
@Test @Test
@ -160,7 +157,7 @@ public class NetworkingModuleTest {
/* timeout */ 0, /* timeout */ 0,
/* withCredentials */ false); /* withCredentials */ false);
verifyErrorEmit(mEmitter, 0); verifyErrorEmit(mContext, 0);
} }
@Test @Test
@ -178,12 +175,12 @@ public class NetworkingModuleTest {
/* timeout */ 0, /* timeout */ 0,
/* withCredentials */ false); /* withCredentials */ false);
verifyErrorEmit(mEmitter, 0); verifyErrorEmit(mContext, 0);
} }
private static void verifyErrorEmit(RCTDeviceEventEmitter emitter, int requestId) { private static void verifyErrorEmit(ReactApplicationContext context, int requestId) {
ArgumentCaptor<WritableArray> captor = ArgumentCaptor.forClass(WritableArray.class); ArgumentCaptor<WritableArray> captor = ArgumentCaptor.forClass(WritableArray.class);
verify(emitter).emit(eq("didCompleteNetworkResponse"), captor.capture()); verify(context).emitDeviceEvent(eq("didCompleteNetworkResponse"), captor.capture());
WritableArray array = captor.getValue(); WritableArray array = captor.getValue();
assertThat(array.getInt(0)).isEqualTo(requestId); assertThat(array.getInt(0)).isEqualTo(requestId);