Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit abc2e065 authored by Maryam Dehaini's avatar Maryam Dehaini
Browse files

Do not return intent if resolved to browser activity

Intent to switch from web to app should only be provided if intent is
resolved to non-browser activity. FLAG_ACTIVITY_REQUIRE_NON_BROWSER was
previously used to accomplish this, but this flag only throws an
exception when startActivity is called and still returns the browser
when Intent#startActivity is called.

Changes also resolves activities as a user to assure app does not open
in another user's account.

Bug: 349695493
Test: Use open in browser button in header menu after clicking on link
Flag: com.android.window.flags.enable_desktop_windowing_app_to_web
Change-Id: Id3caabd02b98e77406677ac382be1fc32d643ed0
parent 20c9033e
Loading
Loading
Loading
Loading
+16 −12
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import android.content.Context
import android.content.Intent
import android.content.Intent.ACTION_VIEW
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.content.Intent.FLAG_ACTIVITY_REQUIRE_NON_BROWSER
import android.content.pm.PackageManager
import android.content.pm.verify.domain.DomainVerificationManager
import android.content.pm.verify.domain.DomainVerificationUserState
@@ -60,13 +59,15 @@ fun isBrowserApp(context: Context, packageName: String, userId: Int): Boolean {
 * Returns intent if there is a browser application available to handle the uri. Otherwise, returns
 * null.
 */
fun getBrowserIntent(uri: Uri, packageManager: PackageManager): Intent? {
fun getBrowserIntent(uri: Uri, packageManager: PackageManager, userId: Int): Intent? {
    val intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, Intent.CATEGORY_APP_BROWSER)
        .setData(uri)
        .addFlags(FLAG_ACTIVITY_NEW_TASK)
    // If there is no browser application available to handle intent, return null
    val component = intent.resolveActivity(packageManager) ?: return null
    intent.setComponent(component)
    // If there is a browser application available to handle the intent, return the intent.
    // Otherwise, return null.
    val resolveInfo = packageManager.resolveActivityAsUser(intent, /* flags= */ 0, userId)
        ?: return null
    intent.setComponent(resolveInfo.componentInfo.componentName)
    return intent
}

@@ -74,15 +75,18 @@ fun getBrowserIntent(uri: Uri, packageManager: PackageManager): Intent? {
 * Returns intent if there is a non-browser application available to handle the uri. Otherwise,
 * returns null.
 */
fun getAppIntent(uri: Uri, packageManager: PackageManager): Intent? {
    val intent = Intent(ACTION_VIEW, uri).apply {
        flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER
    }
    // If there is no application available to handle intent, return null
    val component = intent.resolveActivity(packageManager) ?: return null
    intent.setComponent(component)
fun getAppIntent(uri: Uri, packageManager: PackageManager, userId: Int): Intent? {
    val intent = Intent(ACTION_VIEW, uri).addFlags(FLAG_ACTIVITY_NEW_TASK)
    val resolveInfo = packageManager.resolveActivityAsUser(intent, /* flags= */ 0, userId)
        ?: return null
    // If there is a non-browser application available to handle the intent, return the intent.
    // Otherwise, return null.
     if (resolveInfo.activityInfo != null && !resolveInfo.handleAllWebDataURI) {
        intent.setComponent(resolveInfo.componentInfo.componentName)
        return intent
    }
    return null
}

/**
 * Returns the [DomainVerificationUserState] of the user associated with the given
+4 −2
Original line number Diff line number Diff line
@@ -617,14 +617,16 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        }

        if (browserLink == null) return null;
        return AppToWebUtils.getBrowserIntent(browserLink, mContext.getPackageManager());
        return AppToWebUtils.getBrowserIntent(browserLink, mContext.getPackageManager(),
                mUserContext.getUserId());

    }

    @Nullable
    private Intent getAppLink() {
        return mWebUri == null ? null
                : AppToWebUtils.getAppIntent(mWebUri, mContext.getPackageManager());
                : AppToWebUtils.getAppIntent(mWebUri, mContext.getPackageManager(),
                        mUserContext.getUserId());
    }

    private boolean isBrowserApp() {
+13 −7
Original line number Diff line number Diff line
@@ -278,9 +278,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
        when(mMockPackageManager.getApplicationLabel(any())).thenReturn("applicationLabel");
        final ActivityInfo activityInfo = createActivityInfo();
        when(mMockPackageManager.getActivityInfo(any(), anyInt())).thenReturn(activityInfo);
        final ResolveInfo resolveInfo = new ResolveInfo();
        resolveInfo.activityInfo = activityInfo;
        when(mMockPackageManager.resolveActivity(any(), anyInt())).thenReturn(resolveInfo);
        final ResolveInfo resolveInfo = createResolveInfo(false /* handleAllWebDataUri */);
        when(mMockPackageManager.resolveActivityAsUser(any(), anyInt(), anyInt()))
                .thenReturn(resolveInfo);
        final Display defaultDisplay = mock(Display.class);
        doReturn(defaultDisplay).when(mMockDisplayController).getDisplay(Display.DEFAULT_DISPLAY);
        doReturn(mInsetsState).when(mMockDisplayController).getInsetsState(anyInt());
@@ -1664,11 +1664,9 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB)
    public void browserApp_transferSessionUriUsedForBrowserAppWhenAvailable() {
        // Make {@link AppToWebUtils#isBrowserApp} return true
        ResolveInfo resolveInfo = new ResolveInfo();
        resolveInfo.handleAllWebDataURI = true;
        resolveInfo.activityInfo = createActivityInfo();
        ResolveInfo browserResolveInfo = createResolveInfo(true /* handleAllWebUriData */);
        when(mMockPackageManager.queryIntentActivitiesAsUser(any(), anyInt(), anyInt()))
                .thenReturn(List.of(resolveInfo));
                .thenReturn(List.of(browserResolveInfo));

        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
        final DesktopModeWindowDecoration decor = createWindowDecoration(
@@ -1793,6 +1791,13 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
        return windowDecor;
    }

    private ResolveInfo createResolveInfo(boolean handleAllWebDataURI) {
        final ResolveInfo info = new ResolveInfo();
        info.handleAllWebDataURI = handleAllWebDataURI;
        info.activityInfo = createActivityInfo();
        return info;
    }

    private ActivityManager.RunningTaskInfo createTaskInfo(boolean visible) {
        final ActivityManager.TaskDescription.Builder taskDescriptionBuilder =
                new ActivityManager.TaskDescription.Builder();
@@ -1821,6 +1826,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
        applicationInfo.packageName = "DesktopModeWindowDecorationTestPackage";
        final ActivityInfo activityInfo = new ActivityInfo();
        activityInfo.applicationInfo = applicationInfo;
        activityInfo.packageName = "DesktopModeWindowDecorationTestPackage";
        activityInfo.name = "DesktopModeWindowDecorationTest";
        return activityInfo;
    }