diff --git a/ReactAndroid/src/main/java/com/facebook/react/BridgeCorePackage.java b/ReactAndroid/src/main/java/com/facebook/react/BridgeCorePackage.java new file mode 100644 index 000000000..c4698ffab --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/BridgeCorePackage.java @@ -0,0 +1,120 @@ +/** + * 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 javax.inject.Provider; + +import java.util.ArrayList; +import java.util.List; + +import com.facebook.react.bridge.ModuleSpec; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.module.annotations.ReactModuleList; +import com.facebook.react.module.model.ReactModuleInfoProvider; +import com.facebook.react.modules.core.HeadlessJsTaskSupportModule; +import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; +import com.facebook.react.modules.core.DeviceEventManagerModule; +import com.facebook.react.modules.core.ExceptionsManagerModule; +import com.facebook.react.modules.core.Timing; +import com.facebook.react.modules.debug.SourceCodeModule; +import com.facebook.react.modules.deviceinfo.DeviceInfoModule; +import com.facebook.react.modules.systeminfo.AndroidInfoModule; + +/** + * Package defining core framework modules for basic JS interop. + * It should be used for modules that are always necessary for interacting with + * JS, not for modules that provide RN specific functionality + */ +@ReactModuleList( + nativeModules = { + AndroidInfoModule.class, + DeviceEventManagerModule.class, + ExceptionsManagerModule.class, + HeadlessJsTaskSupportModule.class, + SourceCodeModule.class, + Timing.class, + DeviceInfoModule.class, + } +) +/* package */ class BridgeCorePackage extends LazyReactPackage { + + private final ReactInstanceManager mReactInstanceManager; + private final DefaultHardwareBackBtnHandler mHardwareBackBtnHandler; + + BridgeCorePackage( + ReactInstanceManager reactInstanceManager, + DefaultHardwareBackBtnHandler hardwareBackBtnHandler) { + mReactInstanceManager = reactInstanceManager; + mHardwareBackBtnHandler = hardwareBackBtnHandler; + } + + @Override + public List getNativeModules(final ReactApplicationContext reactContext) { + List moduleSpecList = new ArrayList<>(); + + moduleSpecList.add( + new ModuleSpec(AndroidInfoModule.class, new Provider() { + @Override + public NativeModule get() { + return new AndroidInfoModule(); + } + })); + moduleSpecList.add( + new ModuleSpec(DeviceEventManagerModule.class, new Provider() { + @Override + public NativeModule get() { + return new DeviceEventManagerModule(reactContext, mHardwareBackBtnHandler); + } + })); + moduleSpecList.add( + new ModuleSpec(ExceptionsManagerModule.class, new Provider() { + @Override + public NativeModule get() { + return new ExceptionsManagerModule(mReactInstanceManager.getDevSupportManager()); + } + })); + moduleSpecList + .add(new ModuleSpec(HeadlessJsTaskSupportModule.class, new Provider() { + @Override + public NativeModule get() { + return new HeadlessJsTaskSupportModule(reactContext); + } + })); + moduleSpecList.add( + new ModuleSpec(SourceCodeModule.class, new Provider() { + @Override + public NativeModule get() { + return new SourceCodeModule(reactContext); + } + })); + moduleSpecList.add( + new ModuleSpec(Timing.class, new Provider() { + @Override + public NativeModule get() { + return new Timing(reactContext, mReactInstanceManager.getDevSupportManager()); + } + })); + moduleSpecList.add( + new ModuleSpec(DeviceInfoModule.class, new Provider() { + @Override + public NativeModule get() { + return new DeviceInfoModule(reactContext); + } + })); + + return moduleSpecList; + } + + @Override + public ReactModuleInfoProvider getReactModuleInfoProvider() { + return LazyReactPackage.getReactModuleInfoProviderViaReflection(this); + } +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/CoreModulesPackage.java b/ReactAndroid/src/main/java/com/facebook/react/CoreModulesPackage.java index 5bafb73d0..617223cc2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/CoreModulesPackage.java +++ b/ReactAndroid/src/main/java/com/facebook/react/CoreModulesPackage.java @@ -42,8 +42,13 @@ import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_UI_MANAGER_M import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_UI_MANAGER_MODULE_START; import static com.facebook.react.bridge.ReactMarkerConstants.PROCESS_CORE_REACT_PACKAGE_END; import static com.facebook.react.bridge.ReactMarkerConstants.PROCESS_CORE_REACT_PACKAGE_START; - /** + * This module should be removed following the completion of an experiment into splitting this into + * three modules to allow for more light-weight instantiations of the bridge without UIManager + * The core modules are now in BridgeCorePackage + * The debug modules are now in DebugCorePackage + * The UI manager is in ReactNativeCorePackage + * * Package defining core framework modules (e.g. UIManager). It should be used for modules that * require special integration with other framework parts (e.g. with the list of packages to load * view managers from). diff --git a/ReactAndroid/src/main/java/com/facebook/react/DebugCorePackage.java b/ReactAndroid/src/main/java/com/facebook/react/DebugCorePackage.java new file mode 100644 index 000000000..92ffd1b21 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/DebugCorePackage.java @@ -0,0 +1,75 @@ +/** + * 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 javax.inject.Provider; + +import java.util.ArrayList; +import java.util.List; + +import com.facebook.react.bridge.ModuleSpec; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.devsupport.JSCHeapCapture; +import com.facebook.react.devsupport.JSCSamplingProfiler; +import com.facebook.react.module.annotations.ReactModuleList; +import com.facebook.react.module.model.ReactModuleInfoProvider; +import com.facebook.react.uimanager.debug.DebugComponentOwnershipModule; + +/** + * Package defining core framework modules (e.g. UIManager). It should be used for modules that + * require special integration with other framework parts (e.g. with the list of packages to load + * view managers from). + */ +@ReactModuleList( + nativeModules = { + DebugComponentOwnershipModule.class, + JSCHeapCapture.class, + JSCSamplingProfiler.class, + } +) +/* package */ class DebugCorePackage extends LazyReactPackage { + + DebugCorePackage() { + } + + @Override + public List getNativeModules(final ReactApplicationContext reactContext) { + List moduleSpecList = new ArrayList<>(); + + moduleSpecList.add( + new ModuleSpec(DebugComponentOwnershipModule.class, new Provider() { + @Override + public NativeModule get() { + return new DebugComponentOwnershipModule(reactContext); + } + })); + moduleSpecList.add( + new ModuleSpec(JSCHeapCapture.class, new Provider() { + @Override + public NativeModule get() { + return new JSCHeapCapture(reactContext); + } + })); + moduleSpecList.add( + new ModuleSpec(JSCSamplingProfiler.class, new Provider() { + @Override + public NativeModule get() { + return new JSCSamplingProfiler(reactContext); + } + })); + return moduleSpecList; + } + + @Override + public ReactModuleInfoProvider getReactModuleInfoProvider() { + return LazyReactPackage.getReactModuleInfoProviderViaReflection(this); + } +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java index 24bd7d282..30083fc71 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java @@ -35,8 +35,6 @@ import com.facebook.react.bridge.JSBundleLoader; import com.facebook.react.bridge.JSCJavaScriptExecutor; import com.facebook.react.bridge.JavaJSExecutor; import com.facebook.react.bridge.JavaScriptExecutor; -import com.facebook.react.bridge.JavaScriptModule; -import com.facebook.react.bridge.JavaScriptModuleRegistry; import com.facebook.react.bridge.NativeModuleCallExceptionHandler; import com.facebook.react.bridge.NativeModuleRegistry; import com.facebook.react.bridge.NotThreadSafeBridgeIdleDebugListener; @@ -236,7 +234,7 @@ public class ReactInstanceManager { mDefaultBackButtonImpl = defaultHardwareBackBtnHandler; mBundleLoader = bundleLoader; mJSMainModuleName = jsMainModuleName; - mPackages = packages; + mPackages = new ArrayList<>(); mUseDeveloperSupport = useDeveloperSupport; mDevSupportManager = DevSupportManagerFactory.create( applicationContext, @@ -258,13 +256,26 @@ public class ReactInstanceManager { mUseSeparateUIBackgroundThread = useSeparateUIBackgroundThread; mMinNumShakes = minNumShakes; - CoreModulesPackage coreModulesPackage = - new CoreModulesPackage( - this, - mBackBtnHandler, - mUIImplementationProvider, - mLazyViewManagersEnabled); - mPackages.add(0, coreModulesPackage); + if (true) { // TODO Change to a QE-determined experiment variable in separate commit + CoreModulesPackage coreModulesPackage = + new CoreModulesPackage( + this, + mBackBtnHandler, + mUIImplementationProvider, + mLazyViewManagersEnabled); + mPackages.add(coreModulesPackage); + } else { + mPackages.add(new BridgeCorePackage(this, mBackBtnHandler)); + if (mUseDeveloperSupport) { + mPackages.add(new DebugCorePackage()); + } + mPackages.add( + new ReactNativeCorePackage( + this, + mUIImplementationProvider, + mLazyViewManagersEnabled)); + } + mPackages.addAll(packages); // Instantiate ReactChoreographer in UI thread. ReactChoreographer.initialize(); @@ -788,8 +799,8 @@ public class ReactInstanceManager { try { Process.setThreadPriority(Process.THREAD_PRIORITY_DISPLAY); final ReactApplicationContext reactApplicationContext = createReactContext( - initParams.getJsExecutorFactory().create(), - initParams.getJsBundleLoader()); + initParams.getJsExecutorFactory().create(), + initParams.getJsBundleLoader()); if (mSetupReactContextInBackgroundEnabled) { mCreateReactContextThread = null; diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactNativeCorePackage.java b/ReactAndroid/src/main/java/com/facebook/react/ReactNativeCorePackage.java new file mode 100644 index 000000000..b345e2416 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactNativeCorePackage.java @@ -0,0 +1,95 @@ +/** + * 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 javax.inject.Provider; + +import java.util.ArrayList; +import java.util.List; + +import com.facebook.react.bridge.ModuleSpec; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactMarker; +import com.facebook.react.module.annotations.ReactModuleList; +import com.facebook.react.module.model.ReactModuleInfoProvider; +import com.facebook.react.uimanager.UIImplementationProvider; +import com.facebook.react.uimanager.UIManagerModule; +import com.facebook.react.uimanager.ViewManager; +import com.facebook.systrace.Systrace; + +import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_UI_MANAGER_MODULE_END; +import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_UI_MANAGER_MODULE_START; + +/** + * Package defining core framework modules for initializing ReactNative (e.g. UIManager). It should be used for modules that + * require special integration with other framework parts (e.g. with the list of packages to load + * view managers from). + */ +@ReactModuleList( + nativeModules = { + UIManagerModule.class, + } +) +public class ReactNativeCorePackage extends LazyReactPackage { + + private final ReactInstanceManager mReactInstanceManager; + private final UIImplementationProvider mUIImplementationProvider; + private final boolean mLazyViewManagersEnabled; + + public ReactNativeCorePackage( + ReactInstanceManager reactInstanceManager, + UIImplementationProvider uiImplementationProvider, + boolean lazyViewManagersEnabled) { + mReactInstanceManager = reactInstanceManager; + mUIImplementationProvider = uiImplementationProvider; + mLazyViewManagersEnabled = lazyViewManagersEnabled; + } + + @Override + public List getNativeModules(final ReactApplicationContext reactContext) { + List moduleSpecList = new ArrayList<>(); + + moduleSpecList.add( + new ModuleSpec(UIManagerModule.class, new Provider() { + @Override + public NativeModule get() { + return createUIManager(reactContext); + } + })); + + return moduleSpecList; + } + + @Override + public ReactModuleInfoProvider getReactModuleInfoProvider() { + // This has to be done via reflection or we break open source. + ReactModuleInfoProvider reactModuleInfoProvider = + LazyReactPackage.getReactModuleInfoProviderViaReflection(this); + return reactModuleInfoProvider; + } + + private UIManagerModule createUIManager(ReactApplicationContext reactContext) { + ReactMarker.logMarker(CREATE_UI_MANAGER_MODULE_START); + Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "createUIManagerModule"); + try { + List viewManagersList = mReactInstanceManager.createAllViewManagers( + reactContext); + return new UIManagerModule( + reactContext, + viewManagersList, + mUIImplementationProvider, + mLazyViewManagersEnabled); + } finally { + Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE); + ReactMarker.logMarker(CREATE_UI_MANAGER_MODULE_END); + } + } +}