Skip to content

Commit

Permalink
Do not use InteractionManager to wait for Activity (#35289)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #35289

This was originally added in D15258046 (c802d0b) but seems to be the wrong solution to the problem from my perspective. InteractionManager does not provide timing information on the activity being available, but ReactContext's LifecycleEventListener does.

This should also address some of the issues raised in #25675

Changelog: [Android][Fixed] Linking.getInitialUrl should not wait for InteractionManager

Reviewed By: mdvacca

Differential Revision: D41157646

fbshipit-source-id: 6e23969212570204a7e076b6d4d9db004412da09
  • Loading branch information
javache authored and facebook-github-bot committed Nov 14, 2022
1 parent 9125ff0 commit 3921f05
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 14 deletions.
5 changes: 1 addition & 4 deletions Libraries/Linking/Linking.js
Expand Up @@ -11,7 +11,6 @@
import type {EventSubscription} from '../vendor/emitter/EventEmitter';

import NativeEventEmitter from '../EventEmitter/NativeEventEmitter';
import InteractionManager from '../Interaction/InteractionManager';
import Platform from '../Utilities/Platform';
import NativeIntentAndroid from './NativeIntentAndroid';
import NativeLinkingManager from './NativeLinkingManager';
Expand Down Expand Up @@ -96,9 +95,7 @@ class Linking extends NativeEventEmitter<LinkingEventDefinitions> {
*/
getInitialURL(): Promise<?string> {
return Platform.OS === 'android'
? InteractionManager.runAfterInteractions().then(() =>
nullthrows(NativeIntentAndroid).getInitialURL(),
)
? nullthrows(NativeIntentAndroid).getInitialURL()
: nullthrows(NativeLinkingManager).getInitialURL();
}

Expand Down
Expand Up @@ -17,6 +17,7 @@
import androidx.annotation.Nullable;
import com.facebook.fbreact.specs.NativeIntentAndroidSpec;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReadableArray;
Expand All @@ -30,6 +31,8 @@ public class IntentModule extends NativeIntentAndroidSpec {

public static final String NAME = "IntentAndroid";

private @Nullable LifecycleEventListener mInitialURLListener = null;

private static final String EXTRA_MAP_KEY_FOR_VALUE = "value";

public IntentModule(ReactApplicationContext reactContext) {
Expand All @@ -41,6 +44,15 @@ public String getName() {
return NAME;
}

@Override
public void invalidate() {
if (mInitialURLListener != null) {
getReactApplicationContext().removeLifecycleEventListener(mInitialURLListener);
mInitialURLListener = null;
}
super.invalidate();
}

/**
* Return the URL the activity was started with
*
Expand All @@ -50,18 +62,20 @@ public String getName() {
public void getInitialURL(Promise promise) {
try {
Activity currentActivity = getCurrentActivity();
String initialURL = null;
if (currentActivity == null) {
waitForActivityAndGetInitialURL(promise);
return;
}

if (currentActivity != null) {
Intent intent = currentActivity.getIntent();
String action = intent.getAction();
Uri uri = intent.getData();
Intent intent = currentActivity.getIntent();
String action = intent.getAction();
Uri uri = intent.getData();

if (uri != null
&& (Intent.ACTION_VIEW.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action))) {
initialURL = uri.toString();
}
String initialURL = null;
if (uri != null
&& (Intent.ACTION_VIEW.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action))) {
initialURL = uri.toString();
}

promise.resolve(initialURL);
Expand All @@ -72,6 +86,33 @@ public void getInitialURL(Promise promise) {
}
}

private void waitForActivityAndGetInitialURL(final Promise promise) {
if (mInitialURLListener != null) {
promise.reject(
new IllegalStateException(
"Cannot await activity from more than one call to getInitialURL"));
return;
}

mInitialURLListener =
new LifecycleEventListener() {
@Override
public void onHostResume() {
getInitialURL(promise);

getReactApplicationContext().removeLifecycleEventListener(this);
mInitialURLListener = null;
}

@Override
public void onHostPause() {}

@Override
public void onHostDestroy() {}
};
getReactApplicationContext().addLifecycleEventListener(mInitialURLListener);
}

/**
* Starts a corresponding external activity for the given URL.
*
Expand Down

0 comments on commit 3921f05

Please sign in to comment.