|
| 1 | +/* |
| 2 | + * Copyright (c) Meta Platforms, Inc. and affiliates. |
| 3 | + * |
| 4 | + * This source code is licensed under the MIT license found in the |
| 5 | + * LICENSE file in the root directory of this source tree. |
| 6 | + */ |
| 7 | + |
| 8 | +package com.facebook.react.devsupport |
| 9 | + |
| 10 | +import android.content.Context |
| 11 | +import com.facebook.debug.holder.PrinterHolder.printer |
| 12 | +import com.facebook.debug.tags.ReactDebugOverlayTags |
| 13 | +import com.facebook.infer.annotation.Assertions |
| 14 | +import com.facebook.react.bridge.JSBundleLoader |
| 15 | +import com.facebook.react.bridge.ReactMarker |
| 16 | +import com.facebook.react.bridge.ReactMarkerConstants |
| 17 | +import com.facebook.react.bridge.UiThreadUtil |
| 18 | +import com.facebook.react.common.SurfaceDelegateFactory |
| 19 | +import com.facebook.react.common.annotations.internal.LegacyArchitecture |
| 20 | +import com.facebook.react.common.annotations.internal.LegacyArchitectureLogLevel |
| 21 | +import com.facebook.react.common.annotations.internal.LegacyArchitectureLogger.assertWhenLegacyArchitectureMinifyingEnabled |
| 22 | +import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener |
| 23 | +import com.facebook.react.devsupport.interfaces.DevLoadingViewManager |
| 24 | +import com.facebook.react.devsupport.interfaces.DevSplitBundleCallback |
| 25 | +import com.facebook.react.devsupport.interfaces.PausedInDebuggerOverlayManager |
| 26 | +import com.facebook.react.devsupport.interfaces.RedBoxHandler |
| 27 | +import com.facebook.react.packagerconnection.RequestHandler |
| 28 | + |
| 29 | +/** |
| 30 | + * Interface for accessing and interacting with development features. Following features are |
| 31 | + * supported through this manager class: |
| 32 | + * 1) Displaying JS errors (aka RedBox) |
| 33 | + * 2) Displaying developers menu (Reload JS, Debug JS) |
| 34 | + * 3) Communication with developer server in order to download updated JS bundle |
| 35 | + * 4) Starting/stopping broadcast receiver for js reload signals |
| 36 | + * 5) Starting/stopping motion sensor listener that recognize shake gestures which in turn may |
| 37 | + * trigger developers menu. |
| 38 | + * 6) Launching developers settings view |
| 39 | + * |
| 40 | + * This class automatically monitors the state of registered views and activities to which they are |
| 41 | + * bound to make sure that we don't display overlay or that we we don't listen for sensor events |
| 42 | + * when app is backgrounded. |
| 43 | + * |
| 44 | + * [com.facebook.react.ReactInstanceManager] implementation is responsible for instantiating this |
| 45 | + * class as well as for populating with a reference to [com.facebook.react.bridge.CatalystInstance] |
| 46 | + * whenever instance manager recreates it (through [onNewReactContextCreated]). Also, instance |
| 47 | + * manager is responsible for enabling/disabling dev support in case when app is backgrounded or |
| 48 | + * when all the views has been detached from the instance (through `setDevSupportEnabled` method). |
| 49 | + */ |
| 50 | +@LegacyArchitecture |
| 51 | +public class BridgeDevSupportManager( |
| 52 | + applicationContext: Context, |
| 53 | + reactInstanceManagerHelper: ReactInstanceDevHelper, |
| 54 | + packagerPathForJSBundleName: String?, |
| 55 | + enableOnCreate: Boolean, |
| 56 | + redBoxHandler: RedBoxHandler?, |
| 57 | + devBundleDownloadListener: DevBundleDownloadListener?, |
| 58 | + minNumShakes: Int, |
| 59 | + customPackagerCommandHandlers: Map<String?, RequestHandler?>?, |
| 60 | + surfaceDelegateFactory: SurfaceDelegateFactory?, |
| 61 | + devLoadingViewManager: DevLoadingViewManager?, |
| 62 | + pausedInDebuggerOverlayManager: PausedInDebuggerOverlayManager? |
| 63 | +) : |
| 64 | + DevSupportManagerBase( |
| 65 | + applicationContext, |
| 66 | + reactInstanceManagerHelper, |
| 67 | + packagerPathForJSBundleName, |
| 68 | + enableOnCreate, |
| 69 | + redBoxHandler, |
| 70 | + devBundleDownloadListener, |
| 71 | + minNumShakes, |
| 72 | + customPackagerCommandHandlers, |
| 73 | + surfaceDelegateFactory, |
| 74 | + devLoadingViewManager, |
| 75 | + pausedInDebuggerOverlayManager) { |
| 76 | + |
| 77 | + override fun getUniqueTag(): String = "Bridge" |
| 78 | + |
| 79 | + override fun loadSplitBundleFromServer(bundlePath: String, callback: DevSplitBundleCallback) { |
| 80 | + fetchSplitBundleAndCreateBundleLoader( |
| 81 | + bundlePath, |
| 82 | + object : CallbackWithBundleLoader { |
| 83 | + override fun onSuccess(bundleLoader: JSBundleLoader) { |
| 84 | + val context = |
| 85 | + requireNotNull(currentReactContext) { |
| 86 | + "Failed to load split bundle from server due to DevSupportManager.currentReactContext being null" |
| 87 | + } |
| 88 | + bundleLoader.loadScript(context.catalystInstance) |
| 89 | + context |
| 90 | + .getJSModule(HMRClient::class.java) |
| 91 | + .registerBundle(devServerHelper.getDevServerSplitBundleURL(bundlePath)) |
| 92 | + callback.onSuccess() |
| 93 | + } |
| 94 | + |
| 95 | + override fun onError(url: String, cause: Throwable) = callback.onError(url, cause) |
| 96 | + }) |
| 97 | + } |
| 98 | + |
| 99 | + override fun handleReloadJS() { |
| 100 | + UiThreadUtil.assertOnUiThread() |
| 101 | + ReactMarker.logMarker( |
| 102 | + ReactMarkerConstants.RELOAD, devSettings.packagerConnectionSettings.debugServerHost) |
| 103 | + |
| 104 | + // dismiss redbox if exists |
| 105 | + hideRedboxDialog() |
| 106 | + |
| 107 | + printer.logMessage(ReactDebugOverlayTags.RN_CORE, "RNCore: load from Server") |
| 108 | + val bundleURL = devServerHelper.getDevServerBundleURL(Assertions.assertNotNull(jsAppBundleName)) |
| 109 | + reloadJSFromServer(bundleURL) { |
| 110 | + UiThreadUtil.runOnUiThread { reactInstanceDevHelper.onJSBundleLoadedFromServer() } |
| 111 | + } |
| 112 | + } |
| 113 | + |
| 114 | + private companion object { |
| 115 | + init { |
| 116 | + assertLegacyArchitecture( |
| 117 | + "BridgeDevSupportManager", LegacyArchitectureLogLevel.WARNING) |
| 118 | + } |
| 119 | + } |
| 120 | +} |
0 commit comments