From 7acf74122d8438c201af99ab85cad9f156d083a3 Mon Sep 17 00:00:00 2001 From: Kevin Gozali Date: Mon, 6 Mar 2017 15:15:15 -0800 Subject: [PATCH] android: add ReactInstancePackage abstract class to pass down ReactInstanceManager to create modules Summary: At times, ReactPackage needs to get information from the ReactInstanceManager, e.g. to get the DevSupportManager for debugging purpose. This allows passing down the instance manager to create the native modules, in addition to just ReactApplicationContext. It is then up to the Package to use it or not. To use this, you must make your package class extends ReactInstancePackage, instead of just implementing ReactPackage interface. Reviewed By: mmmulani Differential Revision: D4641997 fbshipit-source-id: 497c4408a7d2b773c49f08bff7c1bf8f9d372edb --- .../react/testing/ReactTestHelper.java | 2 +- .../facebook/react/CompositeReactPackage.java | 28 ++++++++++++++- .../react/NativeModuleRegistryBuilder.java | 14 +++++++- .../facebook/react/ReactInstanceManager.java | 1 + .../facebook/react/ReactInstancePackage.java | 34 +++++++++++++++++++ 5 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 ReactAndroid/src/main/java/com/facebook/react/ReactInstancePackage.java diff --git a/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactTestHelper.java b/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactTestHelper.java index 11c7bc230..a4d770e94 100644 --- a/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactTestHelper.java +++ b/ReactAndroid/src/androidTest/java/com/facebook/react/testing/ReactTestHelper.java @@ -37,7 +37,7 @@ public class ReactTestHelper { private static class ReactInstanceEasyBuilderImpl implements ReactInstanceEasyBuilder { private final NativeModuleRegistryBuilder mNativeModuleRegistryBuilder = - new NativeModuleRegistryBuilder(null, false); + new NativeModuleRegistryBuilder(null, null, false); private final JavaScriptModuleRegistry.Builder mJSModuleRegistryBuilder = new JavaScriptModuleRegistry.Builder(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/CompositeReactPackage.java b/ReactAndroid/src/main/java/com/facebook/react/CompositeReactPackage.java index 8f7856913..f2d6e7776 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/CompositeReactPackage.java +++ b/ReactAndroid/src/main/java/com/facebook/react/CompositeReactPackage.java @@ -25,7 +25,7 @@ import com.facebook.react.uimanager.ViewManager; * {@code CompositeReactPackage} allows to create a single package composed of views and modules * from several other packages. */ -public class CompositeReactPackage implements ReactPackage { +public class CompositeReactPackage extends ReactInstancePackage { private final List mChildReactPackages = new ArrayList<>(); @@ -49,6 +49,7 @@ public class CompositeReactPackage implements ReactPackage { */ @Override public List createNativeModules(ReactApplicationContext reactContext) { + // This is for backward compatibility. final Map moduleMap = new HashMap<>(); for (ReactPackage reactPackage: mChildReactPackages) { for (NativeModule nativeModule: reactPackage.createNativeModules(reactContext)) { @@ -58,6 +59,31 @@ public class CompositeReactPackage implements ReactPackage { return new ArrayList(moduleMap.values()); } + /** + * {@inheritDoc} + */ + @Override + public List createNativeModules( + ReactApplicationContext reactContext, + ReactInstanceManager reactInstanceManager) { + final Map moduleMap = new HashMap<>(); + for (ReactPackage reactPackage: mChildReactPackages) { + List nativeModules; + if (reactPackage instanceof ReactInstancePackage) { + ReactInstancePackage reactInstancePackage = (ReactInstancePackage) reactPackage; + nativeModules = reactInstancePackage.createNativeModules( + reactContext, + reactInstanceManager); + } else { + nativeModules = reactPackage.createNativeModules(reactContext); + } + for (NativeModule nativeModule: nativeModules) { + moduleMap.put(nativeModule.getName(), nativeModule); + } + } + return new ArrayList(moduleMap.values()); + } + /** * {@inheritDoc} */ diff --git a/ReactAndroid/src/main/java/com/facebook/react/NativeModuleRegistryBuilder.java b/ReactAndroid/src/main/java/com/facebook/react/NativeModuleRegistryBuilder.java index d7a6e3f08..4977d60d9 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/NativeModuleRegistryBuilder.java +++ b/ReactAndroid/src/main/java/com/facebook/react/NativeModuleRegistryBuilder.java @@ -26,6 +26,7 @@ import com.facebook.react.module.model.ReactModuleInfo; public class NativeModuleRegistryBuilder { private final ReactApplicationContext mReactApplicationContext; + private final ReactInstanceManager mReactInstanceManager; private final boolean mLazyNativeModulesEnabled; private final Map, ModuleHolder> mModules = new HashMap<>(); @@ -33,8 +34,10 @@ public class NativeModuleRegistryBuilder { public NativeModuleRegistryBuilder( ReactApplicationContext reactApplicationContext, + ReactInstanceManager reactInstanceManager, boolean lazyNativeModulesEnabled) { mReactApplicationContext = reactApplicationContext; + mReactInstanceManager = reactInstanceManager; mLazyNativeModulesEnabled = lazyNativeModulesEnabled; } @@ -94,7 +97,16 @@ public class NativeModuleRegistryBuilder { ReactConstants.TAG, reactPackage.getClass().getSimpleName() + " is not a LazyReactPackage, falling back to old version."); - for (NativeModule nativeModule : reactPackage.createNativeModules(mReactApplicationContext)) { + List nativeModules; + if (reactPackage instanceof ReactInstancePackage) { + ReactInstancePackage reactInstancePackage = (ReactInstancePackage) reactPackage; + nativeModules = reactInstancePackage.createNativeModules( + mReactApplicationContext, + mReactInstanceManager); + } else { + nativeModules = reactPackage.createNativeModules(mReactApplicationContext); + } + for (NativeModule nativeModule : nativeModules) { addNativeModule(nativeModule); } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java index c44678cee..b6a885013 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java @@ -860,6 +860,7 @@ public class ReactInstanceManager { final ReactApplicationContext reactContext = new ReactApplicationContext(mApplicationContext); NativeModuleRegistryBuilder nativeModuleRegistryBuilder = new NativeModuleRegistryBuilder( reactContext, + this, mLazyNativeModulesEnabled); JavaScriptModuleRegistry.Builder jsModulesBuilder = new JavaScriptModuleRegistry.Builder(); if (mUseDeveloperSupport) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstancePackage.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstancePackage.java new file mode 100644 index 000000000..24de64936 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstancePackage.java @@ -0,0 +1,34 @@ +/** + * 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; + +import java.util.List; + +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; + +/** + * A simple wrapper for ReactPackage to make it aware of its {@link ReactInstanceManager} + * when creating native modules. This is useful when the package needs to ask + * the instance manager for more information, like {@link DevSupportManager}. + * + * TODO(t11394819): Consolidate this with LazyReactPackage + */ +public abstract class ReactInstancePackage implements ReactPackage { + + public abstract List createNativeModules( + ReactApplicationContext reactContext, + ReactInstanceManager reactInstanceManager); + + @Override + public List createNativeModules(ReactApplicationContext reactContext) { + throw new RuntimeException("ReactInstancePackage must be passed in the ReactInstanceManager."); + } +}