From edf750049f619414d1845e51d11d5babc4ddab4a Mon Sep 17 00:00:00 2001 From: Ruslan Shestopalyuk Date: Sun, 31 Mar 2024 15:51:52 -0700 Subject: [PATCH] Migrate react/devsupport/LogBox*.java to Kotlin (#43730) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/43730 # Changelog: [Internal] - As in the title, converts corresponding type declarations in `react/devsupport/LogBox*.java` to Kotlin. Differential Revision: https://internalfb.com/D55574528 --- .../ReactAndroid/api/ReactAndroid.api | 6 +- .../react/devsupport/LogBoxDialog.java | 26 ------ .../facebook/react/devsupport/LogBoxDialog.kt | 25 +++++ .../LogBoxDialogSurfaceDelegate.java | 93 ------------------- .../devsupport/LogBoxDialogSurfaceDelegate.kt | 71 ++++++++++++++ .../react/devsupport/LogBoxModule.java | 90 ------------------ .../facebook/react/devsupport/LogBoxModule.kt | 53 +++++++++++ 7 files changed, 154 insertions(+), 210 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialog.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialog.kt delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialogSurfaceDelegate.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialogSurfaceDelegate.kt delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxModule.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxModule.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 2ba2be2ff4c636..e20ed7a3fd7715 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -2212,7 +2212,8 @@ public abstract interface class com/facebook/react/devsupport/JSDebuggerWebSocke public abstract fun onSuccess (Ljava/lang/String;)V } -public class com/facebook/react/devsupport/LogBoxModule : com/facebook/fbreact/specs/NativeLogBoxSpec { +public final class com/facebook/react/devsupport/LogBoxModule : com/facebook/fbreact/specs/NativeLogBoxSpec { + public static final field Companion Lcom/facebook/react/devsupport/LogBoxModule$Companion; public static final field NAME Ljava/lang/String; public fun (Lcom/facebook/react/bridge/ReactApplicationContext;Lcom/facebook/react/devsupport/interfaces/DevSupportManager;)V public fun hide ()V @@ -2220,6 +2221,9 @@ public class com/facebook/react/devsupport/LogBoxModule : com/facebook/fbreact/s public fun show ()V } +public final class com/facebook/react/devsupport/LogBoxModule$Companion { +} + public class com/facebook/react/devsupport/PackagerStatusCheck { public fun ()V public fun (Lokhttp3/OkHttpClient;)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialog.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialog.java deleted file mode 100644 index 990b1455880241..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialog.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.devsupport; - -import android.app.Activity; -import android.app.Dialog; -import android.view.View; -import android.view.Window; -import com.facebook.infer.annotation.Nullsafe; -import com.facebook.react.R; - -/** Dialog for displaying JS errors in LogBox. */ -@Nullsafe(Nullsafe.Mode.LOCAL) -class LogBoxDialog extends Dialog { - public LogBoxDialog(Activity context, View reactRootView) { - super(context, R.style.Theme_Catalyst_LogBox); - - requestWindowFeature(Window.FEATURE_NO_TITLE); - setContentView(reactRootView); - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialog.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialog.kt new file mode 100644 index 00000000000000..60bd25c7ef9977 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialog.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.devsupport + +import android.app.Activity +import android.app.Dialog +import android.view.View +import android.view.Window +import com.facebook.react.R + +/** Dialog for displaying JS errors in LogBox. */ +internal class LogBoxDialog(context: Activity, reactRootView: View?) : + Dialog(context, R.style.Theme_Catalyst_LogBox) { + init { + requestWindowFeature(Window.FEATURE_NO_TITLE) + if (reactRootView != null) { + setContentView(reactRootView) + } + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialogSurfaceDelegate.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialogSurfaceDelegate.java deleted file mode 100644 index a4ec930f5e4bee..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialogSurfaceDelegate.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.devsupport; - -import android.app.Activity; -import android.view.View; -import android.view.ViewGroup; -import androidx.annotation.Nullable; -import com.facebook.infer.annotation.Assertions; -import com.facebook.react.common.SurfaceDelegate; -import com.facebook.react.devsupport.interfaces.DevSupportManager; -import com.facebook.react.util.RNLog; - -/** - * The implementation of SurfaceDelegate with {@link Activity}. This is the default SurfaceDelegate - * for Mobile. - */ -class LogBoxDialogSurfaceDelegate implements SurfaceDelegate { - - private @Nullable View mReactRootView; - private @Nullable LogBoxDialog mDialog; - private final DevSupportManager mDevSupportManager; - - LogBoxDialogSurfaceDelegate(DevSupportManager devSupportManager) { - mDevSupportManager = devSupportManager; - } - - @Override - public void createContentView(String appKey) { - Assertions.assertCondition( - appKey.equals("LogBox"), "This surface manager can only create LogBox React application"); - mReactRootView = mDevSupportManager.createRootView("LogBox"); - if (mReactRootView == null) { - RNLog.e("Unable to launch logbox because react was unable to create the root view"); - } - } - - @Override - public boolean isContentViewReady() { - return mReactRootView != null; - } - - @Override - public void destroyContentView() { - if (mReactRootView != null) { - mDevSupportManager.destroyRootView(mReactRootView); - mReactRootView = null; - } - } - - @Override - public void show() { - if (isShowing() || !isContentViewReady()) { - return; - } - - final @Nullable Activity context = mDevSupportManager.getCurrentActivity(); - if (context == null || context.isFinishing()) { - RNLog.e( - "Unable to launch logbox because react activity " - + "is not available, here is the error that logbox would've displayed: "); - return; - } - - mDialog = new LogBoxDialog(context, mReactRootView); - mDialog.setCancelable(false); - mDialog.show(); - } - - @Override - public void hide() { - if (!isShowing()) { - return; - } - - if (mReactRootView != null && mReactRootView.getParent() != null) { - ((ViewGroup) mReactRootView.getParent()).removeView(mReactRootView); - } - - mDialog.dismiss(); - mDialog = null; - } - - @Override - public boolean isShowing() { - return mDialog != null && mDialog.isShowing(); - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialogSurfaceDelegate.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialogSurfaceDelegate.kt new file mode 100644 index 00000000000000..c45894c4494c90 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxDialogSurfaceDelegate.kt @@ -0,0 +1,71 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.devsupport + +import android.app.Activity +import android.view.View +import android.view.ViewGroup +import com.facebook.infer.annotation.Assertions +import com.facebook.react.common.SurfaceDelegate +import com.facebook.react.devsupport.interfaces.DevSupportManager +import com.facebook.react.util.RNLog.e + +/** + * The implementation of SurfaceDelegate with [Activity]. This is the default SurfaceDelegate for + * Mobile. + */ +internal class LogBoxDialogSurfaceDelegate(private val devSupportManager: DevSupportManager) : + SurfaceDelegate { + private var reactRootView: View? = null + private var dialog: LogBoxDialog? = null + + override fun createContentView(appKey: String) { + Assertions.assertCondition( + appKey == "LogBox", "This surface manager can only create LogBox React application") + reactRootView = devSupportManager.createRootView("LogBox") + if (reactRootView == null) { + e("Unable to launch logbox because react was unable to create the root view") + } + } + + override fun isContentViewReady(): Boolean = reactRootView != null + + override fun destroyContentView() { + if (reactRootView != null) { + devSupportManager.destroyRootView(reactRootView) + reactRootView = null + } + } + + override fun show() { + if (isShowing || !isContentViewReady) { + return + } + val context = devSupportManager.currentActivity + if (context == null || context.isFinishing) { + e( + "Unable to launch logbox because react activity " + + "is not available, here is the error that logbox would've displayed: ") + return + } + dialog = LogBoxDialog(context, reactRootView) + dialog.setCancelable(false) + dialog.show() + } + + override fun hide() { + if (!isShowing) { + return + } + (reactRootView?.parent as ViewGroup)?.removeView(reactRootView) + dialog?.dismiss() + dialog = null + } + + override fun isShowing(): Boolean = dialog?.isShowing ?: false +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxModule.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxModule.java deleted file mode 100644 index dccfd3279725cb..00000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxModule.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.devsupport; - -import androidx.annotation.Nullable; -import com.facebook.fbreact.specs.NativeLogBoxSpec; -import com.facebook.infer.annotation.Nullsafe; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.UiThreadUtil; -import com.facebook.react.common.SurfaceDelegate; -import com.facebook.react.devsupport.interfaces.DevSupportManager; -import com.facebook.react.module.annotations.ReactModule; - -@Nullsafe(Nullsafe.Mode.LOCAL) -@ReactModule(name = NativeLogBoxSpec.NAME) -public class LogBoxModule extends NativeLogBoxSpec { - - public static final String NAME = "LogBox"; - - private final DevSupportManager mDevSupportManager; - private final SurfaceDelegate mSurfaceDelegate; - - /** - * LogBoxModule can be rendered in different surface. By default, it will use LogBoxDialog to wrap - * the content of logs. In other platform (for example VR), a surfaceDelegate can be provided so - * that the content can be wrapped in custom surface. - */ - public LogBoxModule(ReactApplicationContext reactContext, DevSupportManager devSupportManager) { - super(reactContext); - - mDevSupportManager = devSupportManager; - - @Nullable SurfaceDelegate surfaceDelegate = devSupportManager.createSurfaceDelegate(NAME); - if (surfaceDelegate != null) { - mSurfaceDelegate = surfaceDelegate; - } else { - mSurfaceDelegate = new LogBoxDialogSurfaceDelegate(devSupportManager); - } - - UiThreadUtil.runOnUiThread( - new Runnable() { - @Override - public void run() { - mSurfaceDelegate.createContentView("LogBox"); - } - }); - } - - @Override - public void show() { - if (!mSurfaceDelegate.isContentViewReady()) { - return; - } - - UiThreadUtil.runOnUiThread( - new Runnable() { - @Override - public void run() { - mSurfaceDelegate.show(); - } - }); - } - - @Override - public void hide() { - UiThreadUtil.runOnUiThread( - new Runnable() { - @Override - public void run() { - mSurfaceDelegate.hide(); - } - }); - } - - @Override - public void invalidate() { - UiThreadUtil.runOnUiThread( - new Runnable() { - @Override - public void run() { - mSurfaceDelegate.destroyContentView(); - } - }); - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxModule.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxModule.kt new file mode 100644 index 00000000000000..325a8645bce935 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/LogBoxModule.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.devsupport + +import com.facebook.fbreact.specs.NativeLogBoxSpec +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.bridge.UiThreadUtil +import com.facebook.react.common.SurfaceDelegate +import com.facebook.react.devsupport.interfaces.DevSupportManager +import com.facebook.react.module.annotations.ReactModule + +@ReactModule(name = NativeLogBoxSpec.NAME) +public class LogBoxModule( + reactContext: ReactApplicationContext?, + private val devSupportManager: DevSupportManager +) : NativeLogBoxSpec(reactContext) { + private val surfaceDelegate: SurfaceDelegate = + devSupportManager.createSurfaceDelegate(NAME) + ?: LogBoxDialogSurfaceDelegate(devSupportManager) + + /** + * LogBoxModule can be rendered in different surface. By default, it will use LogBoxDialog to wrap + * the content of logs. In other platform (for example VR), a surfaceDelegate can be provided so + * that the content can be wrapped in custom surface. + */ + init { + UiThreadUtil.runOnUiThread { surfaceDelegate.createContentView("LogBox") } + } + + override fun show() { + if (!surfaceDelegate.isContentViewReady) { + return + } + UiThreadUtil.runOnUiThread { surfaceDelegate.show() } + } + + override fun hide() { + UiThreadUtil.runOnUiThread { surfaceDelegate.hide() } + } + + override fun invalidate() { + UiThreadUtil.runOnUiThread { surfaceDelegate.destroyContentView() } + } + + public companion object { + public const val NAME: String = "LogBox" + } +}