From 5d711f83b5f1e8053b5b19d0a864a1d8fc27a235 Mon Sep 17 00:00:00 2001 From: Arushi Kesarwani Date: Tue, 12 Mar 2024 19:00:35 -0700 Subject: [PATCH] Support onNewIntent in Bridgeless (#43401) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/43401 Implement `onNewIntent` in Bridgeless by adding it to ReactHostImpl Changelog: [Android][Breaking] Implement `onNewIntent` in Bridgeless Reviewed By: fkgozali, RSNara Differential Revision: D54703159 fbshipit-source-id: fd8589d8131f4fa57188d493331dc68fb38c4520 --- .../ReactAndroid/api/ReactAndroid.api | 3 ++ .../facebook/react/ReactActivityDelegate.java | 10 +----- .../com/facebook/react/ReactDelegate.java | 13 ++++++++ .../main/java/com/facebook/react/ReactHost.kt | 3 ++ .../facebook/react/runtime/ReactHostImpl.java | 32 +++++++++++++++++++ 5 files changed, 52 insertions(+), 9 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 774ca78dc3c2ed..dd22a0e67474bf 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -153,6 +153,7 @@ public class com/facebook/react/ReactDelegate { public fun onHostDestroy ()V public fun onHostPause ()V public fun onHostResume ()V + public fun onNewIntent (Landroid/content/Intent;)Z public fun onWindowFocusChanged (Z)V public fun shouldShowDevMenuOrReload (ILandroid/view/KeyEvent;)Z } @@ -204,6 +205,7 @@ public abstract interface class com/facebook/react/ReactHost { public abstract fun onHostPause (Landroid/app/Activity;)V public abstract fun onHostResume (Landroid/app/Activity;)V public abstract fun onHostResume (Landroid/app/Activity;Lcom/facebook/react/modules/core/DefaultHardwareBackBtnHandler;)V + public abstract fun onNewIntent (Landroid/content/Intent;)V public abstract fun onWindowFocusChange (Z)V public abstract fun reload (Ljava/lang/String;)Lcom/facebook/react/interfaces/TaskInterface; public abstract fun removeBeforeDestroyListener (Lkotlin/jvm/functions/Function0;)V @@ -3643,6 +3645,7 @@ public class com/facebook/react/runtime/ReactHostImpl : com/facebook/react/React public fun onHostPause (Landroid/app/Activity;)V public fun onHostResume (Landroid/app/Activity;)V public fun onHostResume (Landroid/app/Activity;Lcom/facebook/react/modules/core/DefaultHardwareBackBtnHandler;)V + public fun onNewIntent (Landroid/content/Intent;)V public fun onWindowFocusChange (Z)V public fun reload (Ljava/lang/String;)Lcom/facebook/react/interfaces/TaskInterface; public fun removeBeforeDestroyListener (Lkotlin/jvm/functions/Function0;)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java index ca95a2615060f3..a54238c801447a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java @@ -183,15 +183,7 @@ public boolean onBackPressed() { } public boolean onNewIntent(Intent intent) { - if (ReactFeatureFlags.enableBridgelessArchitecture) { - // TODO T156475655: support onNewIntent - } else { - if (getReactNativeHost().hasInstance()) { - getReactNativeHost().getReactInstanceManager().onNewIntent(intent); - return true; - } - } - return false; + return mReactDelegate.onNewIntent(intent); } public void onWindowFocusChanged(boolean hasFocus) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactDelegate.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactDelegate.java index bb0cb136e30994..1880f66362679e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactDelegate.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactDelegate.java @@ -135,6 +135,19 @@ public boolean onBackPressed() { return false; } + public boolean onNewIntent(Intent intent) { + if (ReactFeatureFlags.enableBridgelessArchitecture) { + mReactHost.onNewIntent(intent); + return true; + } else { + if (getReactNativeHost().hasInstance()) { + getReactNativeHost().getReactInstanceManager().onNewIntent(intent); + return true; + } + } + return false; + } + public void onActivityResult( int requestCode, int resultCode, Intent data, boolean shouldForwardToReactInstance) { if (ReactFeatureFlags.enableBridgelessArchitecture) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt index 1183e792138518..11a7826437179f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt @@ -123,6 +123,9 @@ public interface ReactHost { /* To be called when focus has changed for the hosting window. */ public fun onWindowFocusChange(hasFocus: Boolean) + /* This method will give JS the opportunity to receive intents via Linking. */ + public fun onNewIntent(intent: Intent) + public fun addBeforeDestroyListener(onBeforeDestroy: () -> Unit) public fun removeBeforeDestroyListener(onBeforeDestroy: () -> Unit) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java index 4ca0483914dc49..bf28ed8a8fa2ea 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java @@ -16,6 +16,8 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.net.Uri; +import android.nfc.NfcAdapter; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -667,6 +669,36 @@ public void onWindowFocusChange(boolean hasFocus) { "Tried to access onWindowFocusChange while context is not ready")); } + /* This method will give JS the opportunity to receive intents via Linking. + * + * @param intent The incoming intent + */ + @ThreadConfined(UI) + @Override + public void onNewIntent(Intent intent) { + log("onNewIntent()"); + + ReactContext currentContext = getCurrentReactContext(); + if (currentContext != null) { + String action = intent.getAction(); + Uri uri = intent.getData(); + + if (uri != null + && (Intent.ACTION_VIEW.equals(action) + || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action))) { + DeviceEventManagerModule deviceEventManagerModule = + currentContext.getNativeModule(DeviceEventManagerModule.class); + if (deviceEventManagerModule != null) { + deviceEventManagerModule.emitNewIntentReceived(uri); + } + } + currentContext.onNewIntent(getCurrentActivity(), intent); + } + ReactSoftExceptionLogger.logSoftException( + TAG, + new ReactNoCrashSoftException("Tried to access onNewIntent while context is not ready")); + } + @Nullable JavaScriptContextHolder getJavaScriptContextHolder() { final ReactInstance reactInstance = mReactInstanceTaskRef.get().getResult();