diff --git a/lib/android/app/build.gradle b/lib/android/app/build.gradle index 417a34d65c1..85b6f09e3f1 100644 --- a/lib/android/app/build.gradle +++ b/lib/android/app/build.gradle @@ -57,6 +57,9 @@ android { reactNative56 { dimension "RNN.reactNativeVersion" } + reactNative57 { + dimension "RNN.reactNativeVersion" + } } } diff --git a/lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationReactNativeHost.java b/lib/android/app/src/reactNative51/java/com/reactnativenavigation/react/NavigationReactNativeHost.java similarity index 100% rename from lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationReactNativeHost.java rename to lib/android/app/src/reactNative51/java/com/reactnativenavigation/react/NavigationReactNativeHost.java diff --git a/lib/android/app/src/reactNative55/java/com/reactnativenavigation/react/NavigationReactNativeHost.java b/lib/android/app/src/reactNative55/java/com/reactnativenavigation/react/NavigationReactNativeHost.java new file mode 100644 index 00000000000..02cd1dc5bb8 --- /dev/null +++ b/lib/android/app/src/reactNative55/java/com/reactnativenavigation/react/NavigationReactNativeHost.java @@ -0,0 +1,108 @@ +package com.reactnativenavigation.react; + +import android.app.Application; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.facebook.infer.annotation.Assertions; +import com.facebook.react.ReactInstanceManager; +import com.facebook.react.ReactInstanceManagerBuilder; +import com.facebook.react.ReactNativeHost; +import com.facebook.react.ReactPackage; +import com.facebook.react.common.LifecycleState; +import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; +import com.facebook.react.shell.MainReactPackage; +import com.reactnativenavigation.NavigationApplication; + +import java.util.ArrayList; +import java.util.List; + +/** + * Default implementation of {@link ReactNativeHost} that includes {@link NavigationPackage} + * and user-defined additional packages. + */ +public class NavigationReactNativeHost extends ReactNativeHost implements BundleDownloadListenerProvider { + + private final boolean isDebug; + private final List additionalReactPackages; + private @Nullable NavigationDevBundleDownloadListener bundleListener; + private final DevBundleDownloadListener bundleListenerMediator = new DevBundleDownloadListenerAdapter() { + @Override + public void onSuccess() { + if (bundleListener != null) { + bundleListener.onSuccess(); + } + } + }; + + + public NavigationReactNativeHost(NavigationApplication application) { + this(application, application.isDebug(), application.createAdditionalReactPackages()); + } + + @SuppressWarnings("WeakerAccess") + public NavigationReactNativeHost(Application application, boolean isDebug, final List additionalReactPackages) { + super(application); + this.isDebug = isDebug; + this.additionalReactPackages = additionalReactPackages; + } + + @Override + public void setBundleLoaderListener(NavigationDevBundleDownloadListener listener) { + bundleListener = listener; + } + + @Override + public boolean getUseDeveloperSupport() { + return isDebug; + } + + @Override + protected List getPackages() { + List packages = new ArrayList<>(); + boolean hasMainReactPackage = false; + packages.add(new NavigationPackage(this)); + if (additionalReactPackages != null) { + for (ReactPackage p : additionalReactPackages) { + if (!(p instanceof NavigationPackage)) { + packages.add(p); + } + if (p instanceof MainReactPackage) hasMainReactPackage = true; + } + } + if (!hasMainReactPackage) { + packages.add(new MainReactPackage()); + } + return packages; + } + + protected ReactInstanceManager createReactInstanceManager() { + ReactInstanceManagerBuilder builder = ReactInstanceManager.builder() + .setApplication(getApplication()) + .setJSMainModulePath(getJSMainModuleName()) + .setUseDeveloperSupport(getUseDeveloperSupport()) + .setRedBoxHandler(getRedBoxHandler()) + .setJavaScriptExecutorFactory(getJavaScriptExecutorFactory()) + .setUIImplementationProvider(getUIImplementationProvider()) + .setInitialLifecycleState(LifecycleState.BEFORE_CREATE) + .setDevBundleDownloadListener(getDevBundleDownloadListener()); + + for (ReactPackage reactPackage : getPackages()) { + builder.addPackage(reactPackage); + } + + String jsBundleFile = getJSBundleFile(); + if (jsBundleFile != null) { + builder.setJSBundleFile(jsBundleFile); + } else { + builder.setBundleAssetName(Assertions.assertNotNull(getBundleAssetName())); + } + return builder.build(); + } + + @SuppressWarnings("WeakerAccess") + @NonNull + protected DevBundleDownloadListener getDevBundleDownloadListener() { + return bundleListenerMediator; + } +} diff --git a/lib/android/app/src/reactNative56/java/com/reactnativenavigation/react/NavigationReactNativeHost.java b/lib/android/app/src/reactNative56/java/com/reactnativenavigation/react/NavigationReactNativeHost.java new file mode 100644 index 00000000000..02cd1dc5bb8 --- /dev/null +++ b/lib/android/app/src/reactNative56/java/com/reactnativenavigation/react/NavigationReactNativeHost.java @@ -0,0 +1,108 @@ +package com.reactnativenavigation.react; + +import android.app.Application; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.facebook.infer.annotation.Assertions; +import com.facebook.react.ReactInstanceManager; +import com.facebook.react.ReactInstanceManagerBuilder; +import com.facebook.react.ReactNativeHost; +import com.facebook.react.ReactPackage; +import com.facebook.react.common.LifecycleState; +import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; +import com.facebook.react.shell.MainReactPackage; +import com.reactnativenavigation.NavigationApplication; + +import java.util.ArrayList; +import java.util.List; + +/** + * Default implementation of {@link ReactNativeHost} that includes {@link NavigationPackage} + * and user-defined additional packages. + */ +public class NavigationReactNativeHost extends ReactNativeHost implements BundleDownloadListenerProvider { + + private final boolean isDebug; + private final List additionalReactPackages; + private @Nullable NavigationDevBundleDownloadListener bundleListener; + private final DevBundleDownloadListener bundleListenerMediator = new DevBundleDownloadListenerAdapter() { + @Override + public void onSuccess() { + if (bundleListener != null) { + bundleListener.onSuccess(); + } + } + }; + + + public NavigationReactNativeHost(NavigationApplication application) { + this(application, application.isDebug(), application.createAdditionalReactPackages()); + } + + @SuppressWarnings("WeakerAccess") + public NavigationReactNativeHost(Application application, boolean isDebug, final List additionalReactPackages) { + super(application); + this.isDebug = isDebug; + this.additionalReactPackages = additionalReactPackages; + } + + @Override + public void setBundleLoaderListener(NavigationDevBundleDownloadListener listener) { + bundleListener = listener; + } + + @Override + public boolean getUseDeveloperSupport() { + return isDebug; + } + + @Override + protected List getPackages() { + List packages = new ArrayList<>(); + boolean hasMainReactPackage = false; + packages.add(new NavigationPackage(this)); + if (additionalReactPackages != null) { + for (ReactPackage p : additionalReactPackages) { + if (!(p instanceof NavigationPackage)) { + packages.add(p); + } + if (p instanceof MainReactPackage) hasMainReactPackage = true; + } + } + if (!hasMainReactPackage) { + packages.add(new MainReactPackage()); + } + return packages; + } + + protected ReactInstanceManager createReactInstanceManager() { + ReactInstanceManagerBuilder builder = ReactInstanceManager.builder() + .setApplication(getApplication()) + .setJSMainModulePath(getJSMainModuleName()) + .setUseDeveloperSupport(getUseDeveloperSupport()) + .setRedBoxHandler(getRedBoxHandler()) + .setJavaScriptExecutorFactory(getJavaScriptExecutorFactory()) + .setUIImplementationProvider(getUIImplementationProvider()) + .setInitialLifecycleState(LifecycleState.BEFORE_CREATE) + .setDevBundleDownloadListener(getDevBundleDownloadListener()); + + for (ReactPackage reactPackage : getPackages()) { + builder.addPackage(reactPackage); + } + + String jsBundleFile = getJSBundleFile(); + if (jsBundleFile != null) { + builder.setJSBundleFile(jsBundleFile); + } else { + builder.setBundleAssetName(Assertions.assertNotNull(getBundleAssetName())); + } + return builder.build(); + } + + @SuppressWarnings("WeakerAccess") + @NonNull + protected DevBundleDownloadListener getDevBundleDownloadListener() { + return bundleListenerMediator; + } +} diff --git a/lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/DevBundleDownloadListenerAdapter.java b/lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/DevBundleDownloadListenerAdapter.java new file mode 100644 index 00000000000..86af8ca5768 --- /dev/null +++ b/lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/DevBundleDownloadListenerAdapter.java @@ -0,0 +1,28 @@ +package com.reactnativenavigation.react; + +import com.facebook.react.bridge.NativeDeltaClient; +import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; + +import javax.annotation.Nullable; + +public class DevBundleDownloadListenerAdapter implements DevBundleDownloadListener, NavigationDevBundleDownloadListener { + @Override + public void onSuccess(@Nullable NativeDeltaClient nativeDeltaClient) { + onSuccess(); + } + + @Override + public void onSuccess() { + + } + + @Override + public void onProgress(@Nullable String status, @Nullable Integer done, @Nullable Integer total) { + + } + + @Override + public void onFailure(Exception cause) { + + } +} diff --git a/lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/JsDevReloadHandlerFacade.java b/lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/JsDevReloadHandlerFacade.java new file mode 100644 index 00000000000..919fe4af048 --- /dev/null +++ b/lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/JsDevReloadHandlerFacade.java @@ -0,0 +1,28 @@ +package com.reactnativenavigation.react; + +import com.facebook.react.bridge.NativeDeltaClient; +import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; + +import javax.annotation.Nullable; + +public class JsDevReloadHandlerFacade implements DevBundleDownloadListener, NavigationDevBundleDownloadListener { + @Override + public void onSuccess(@Nullable NativeDeltaClient nativeDeltaClient) { + onSuccess(); + } + + @Override + public void onProgress(@Nullable String status, @Nullable Integer done, @Nullable Integer total) { + + } + + @Override + public void onFailure(Exception cause) { + + } + + @Override + public void onSuccess() { + + } +} diff --git a/lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/NavigationReactNativeHost.java b/lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/NavigationReactNativeHost.java new file mode 100644 index 00000000000..48e498d1f3a --- /dev/null +++ b/lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/NavigationReactNativeHost.java @@ -0,0 +1,107 @@ +package com.reactnativenavigation.react; + +import android.app.Application; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.facebook.infer.annotation.Assertions; +import com.facebook.react.ReactInstanceManager; +import com.facebook.react.ReactInstanceManagerBuilder; +import com.facebook.react.ReactNativeHost; +import com.facebook.react.ReactPackage; +import com.facebook.react.common.LifecycleState; +import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; +import com.facebook.react.shell.MainReactPackage; +import com.reactnativenavigation.NavigationApplication; + +import java.util.ArrayList; +import java.util.List; + +/** + * Default implementation of {@link ReactNativeHost} that includes {@link NavigationPackage} + * and user-defined additional packages. + */ +public class NavigationReactNativeHost extends ReactNativeHost implements BundleDownloadListenerProvider { + + private final boolean isDebug; + private final List additionalReactPackages; + private @Nullable NavigationDevBundleDownloadListener bundleListener; + private final DevBundleDownloadListener bundleListenerMediator = new DevBundleDownloadListenerAdapter() { + @Override + public void onSuccess() { + if (bundleListener != null) { + bundleListener.onSuccess(); + } + } + }; + + + public NavigationReactNativeHost(NavigationApplication application) { + this(application, application.isDebug(), application.createAdditionalReactPackages()); + } + + @SuppressWarnings("WeakerAccess") + public NavigationReactNativeHost(Application application, boolean isDebug, final List additionalReactPackages) { + super(application); + this.isDebug = isDebug; + this.additionalReactPackages = additionalReactPackages; + } + + @Override + public void setBundleLoaderListener(NavigationDevBundleDownloadListener listener) { + bundleListener = listener; + } + + @Override + public boolean getUseDeveloperSupport() { + return isDebug; + } + + @Override + protected List getPackages() { + List packages = new ArrayList<>(); + boolean hasMainReactPackage = false; + packages.add(new NavigationPackage(this)); + if (additionalReactPackages != null) { + for (ReactPackage p : additionalReactPackages) { + if (!(p instanceof NavigationPackage)) { + packages.add(p); + } + if (p instanceof MainReactPackage) hasMainReactPackage = true; + } + } + if (!hasMainReactPackage) { + packages.add(new MainReactPackage()); + } + return packages; + } + + protected ReactInstanceManager createReactInstanceManager() { + ReactInstanceManagerBuilder builder = ReactInstanceManager.builder() + .setApplication(getApplication()) + .setJSMainModulePath(getJSMainModuleName()) + .setUseDeveloperSupport(getUseDeveloperSupport()) + .setRedBoxHandler(getRedBoxHandler()) + .setJavaScriptExecutorFactory(getJavaScriptExecutorFactory()) + .setInitialLifecycleState(LifecycleState.BEFORE_CREATE) + .setDevBundleDownloadListener(getDevBundleDownloadListener()); + + for (ReactPackage reactPackage : getPackages()) { + builder.addPackage(reactPackage); + } + + String jsBundleFile = getJSBundleFile(); + if (jsBundleFile != null) { + builder.setJSBundleFile(jsBundleFile); + } else { + builder.setBundleAssetName(Assertions.assertNotNull(getBundleAssetName())); + } + return builder.build(); + } + + @SuppressWarnings("WeakerAccess") + @NonNull + protected DevBundleDownloadListener getDevBundleDownloadListener() { + return bundleListenerMediator; + } +} diff --git a/lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/ReloadHandlerFacade.java b/lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/ReloadHandlerFacade.java new file mode 100644 index 00000000000..697ea43e48a --- /dev/null +++ b/lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/ReloadHandlerFacade.java @@ -0,0 +1,25 @@ +package com.reactnativenavigation.react; + +import com.facebook.react.bridge.NativeDeltaClient; +import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; + +import javax.annotation.Nullable; + +public abstract class ReloadHandlerFacade implements DevBundleDownloadListener { + @Override + public void onSuccess(@Nullable NativeDeltaClient nativeDeltaClient) { + + } + + @Override + public void onProgress(@Nullable String status, @Nullable Integer done, @Nullable Integer total) { + + } + + @Override + public void onFailure(Exception cause) { + + } + + protected abstract void onSuccess(); +} diff --git a/lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/SyncUiImplementation.java b/lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/SyncUiImplementation.java new file mode 100644 index 00000000000..a4dd2a188f6 --- /dev/null +++ b/lib/android/app/src/reactNative57/java/com/reactnativenavigation/react/SyncUiImplementation.java @@ -0,0 +1,70 @@ +package com.reactnativenavigation.react; + +import android.support.annotation.Nullable; + +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.react.uimanager.UIImplementation; +import com.facebook.react.uimanager.UIManagerModule; +import com.facebook.react.uimanager.ViewManager; +import com.facebook.react.uimanager.common.MeasureSpecProvider; +import com.facebook.react.uimanager.common.SizeMonitoringFrameLayout; +import com.facebook.react.uimanager.events.EventDispatcher; + +import java.util.List; + +@SuppressWarnings("WeakerAccess") +public class SyncUiImplementation extends UIImplementation { + private static final Object lock = new Object(); + + public SyncUiImplementation(ReactApplicationContext reactContext, List viewManagerList, EventDispatcher eventDispatcher, int minTimeLeftInFrameForNonBatchedOperationMs) { + super(reactContext, viewManagerList, eventDispatcher, minTimeLeftInFrameForNonBatchedOperationMs); + } + + public SyncUiImplementation(ReactApplicationContext reactContext, UIManagerModule.ViewManagerResolver viewManagerResolver, EventDispatcher eventDispatcher, int minTimeLeftInFrameForNonBatchedOperationMs) { + super(reactContext, viewManagerResolver, eventDispatcher, minTimeLeftInFrameForNonBatchedOperationMs); + } + + @Override + public void manageChildren( + int viewTag, + @Nullable ReadableArray moveFrom, + @Nullable ReadableArray moveTo, + @Nullable ReadableArray addChildTags, + @Nullable ReadableArray addAtIndices, + @Nullable ReadableArray removeFrom) { + synchronized (lock) { + super.manageChildren(viewTag, moveFrom, moveTo, addChildTags, addAtIndices, removeFrom); + } + } + + @Override + public void setChildren(int viewTag, ReadableArray childrenTags) { + synchronized (lock) { + super.setChildren(viewTag, childrenTags); + } + } + + @Override + public void createView(int tag, String className, int rootViewTag, ReadableMap props) { + synchronized (lock) { + super.createView(tag, className, rootViewTag, props); + } + } + + @Override + public void removeRootShadowNode(int rootViewTag) { + synchronized (lock) { + super.removeRootShadowNode(rootViewTag); + } + } + + @Override + public void registerRootView(T rootView, int tag, ThemedReactContext context) { + synchronized (lock) { + super.registerRootView(rootView, tag, context); + } + } +}