GoogleChrome / android-browser-helper

The Android Browser Helper library helps developers use Custom Tabs and Trusted Web Activities on top of the AndroidX browser support library.
Apache License 2.0
695 stars 289 forks source link

Make LauncherActivity more extensible to support third-party integrations #417

Open SergeyPoznyakAkvelon opened 1 year ago

SergeyPoznyakAkvelon commented 1 year ago

Is your feature request related to a problem? Please describe. I'm trying to integrate Branch SDK to support deep linking into the app, which can redirect to Play Store and preserve deep link after app is installed. It's a must have feature for our TWA Android app, because it's tied to our auth flow.

Describe the solution you'd like Branch SDK is opinionated about when it initializes and retrieves the deep link. There is some logic in LauncherActivity that prevents that from happening when app is already running. That logic will finish the activity inside onCreate if app is already running, but I need the activity to at least get to onStart to initialize Branch SDK and parse deep link info.

Basically I need a way to override that default behaviour without any hacks. Currently all of that logic is hidden in a private method restartInNewTask(), which is called from onCreate().

Describe alternatives you've considered I tried working around that by adding custom logic before super.onCreate() call which alters the intent to basically force relaunch the app, but I'm afraid that doing that might break compatibility with future versions of android-browser-helper.

Additional context This is the code of my current workaround:

class MyLauncherActivity extends LauncherActivity {
    private boolean shouldRestartBrowser() {
        if (getIntent().getBooleanExtra(INTENT_REFRESHED, false)) {
            return false;
        }
        Uri uri = getIntent().getData();
        // Most likely a branch link
        return uri != null && !doesUriMatchTWAHostname(uri);
    }

    private void forceRefresh() {
        Intent newIntent = new Intent(getIntent());

        int flags = newIntent.getFlags();
        newIntent.putExtra(INTENT_REFRESHED, true);
        flags &= ~Intent.FLAG_ACTIVITY_NEW_TASK;
        flags |= Intent.FLAG_ACTIVITY_CLEAR_TOP;
        newIntent.setFlags(flags);
        startActivity(newIntent);
        finish();
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        if (shouldRestartBrowser()) {
            Log.d(TAG, "Received a branch.io intent, restarting browser");
            forceRefresh();
        }
        super.onCreate(savedInstanceState);
    }
}
SayedElabady commented 1 year ago

Hey, so if I understand this correctly you need a way to add extra parameters to the intent before restarting the app?

SergeyPoznyakAkvelon commented 1 year ago

@SayedElabady More like disable the default behavior of forwarding the intent to custom tabs activity if the app is already open. Because when it does that it doesn't let my custom activity to start and do its thing.

SayedElabady commented 1 year ago

@SergeyPoznyakAkvelon , We can add a method to let you add extra parameters to the intent before firing it, you can find a sample below. Please let me know if this will help you in resolving the issue or not.

private boolean restartInNewTask() {
        boolean hasNewTask = (getIntent().getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0;
        boolean hasNewDocument = (getIntent().getFlags() & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0;

        if (hasNewTask && !hasNewDocument) return false;

        //...

        Intent newIntent = new Intent(getIntent());

        int flags = getIntent().getFlags();
        flags |= Intent.FLAG_ACTIVITY_NEW_TASK;
        flags &= ~Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
        newIntent.setFlags(flags);
        modifyIntentForNewTask(newIntent);

        startActivity(newIntent);
        return true;
    }

    /**
     * Override this method to add extra parameter to the intent before firing it when
     * restartNewTask is required.
     */
    public Intent modifyIntentForNewTask(Intent initialIntent){
        // Do the modification here as you want, for example
        //  if (shouldRestartBrowser()){
        //     add the extra parameters here, like:
        //     initialIntent.putExtra(INTENT_REFRESHED, true);
        //  }
        return initialIntent;
    }