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

Commit f478eb8e authored by Ajinkya Chalke's avatar Ajinkya Chalke
Browse files

Update backlinks logic to use explicit main intent

- Update to build and use an explicit intent when building the main
  launcher intent.
- Explicit intent is required for main launcher intent because not all
  apps use CATEGORY_DEFAULT for their main launcher activity.
- Update tests to ensure the same.
- Also made an unrelated update to UI to better match the mocks.

Bug: 352033030
Test: atest AppClipsViewModelTest AppClipsTest
Flag: com.android.systemui.app_clips_backlinks
Change-Id: I880c0418a69e84607a0e8b95ab6e006d8ad586af
parent 5627a898
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@
        android:layout_marginStart="16dp"
        android:checked="true"
        android:text="@string/backlinks_include_link"
        android:textColor="?android:textColorSecondary"
        android:visibility="gone"
        app:layout_constraintBottom_toTopOf="@id/preview"
        app:layout_constraintStart_toEndOf="@id/cancel"
@@ -74,6 +75,7 @@
        android:drawablePadding="4dp"
        android:gravity="center"
        android:paddingHorizontal="8dp"
        android:textColor="?android:textColorSecondary"
        android:visibility="gone"
        app:layout_constraintBottom_toTopOf="@id/preview"
        app:layout_constraintStart_toEndOf="@id/backlinks_include_data"
+16 −4
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.content.ClipData;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.HardwareRenderer;
import android.graphics.RecordingCanvas;
@@ -267,6 +268,8 @@ final class AppClipsViewModel extends ViewModel {
    }

    private boolean canAppStartThroughLauncher(String packageName) {
        // Use Intent.resolveActivity API to check if the intent resolves as that is what Android
        // uses internally when apps use Context.startActivity.
        return getMainLauncherIntentForPackage(packageName).resolveActivity(mPackageManager)
                != null;
    }
@@ -366,10 +369,19 @@ final class AppClipsViewModel extends ViewModel {
        return taskInfo.topActivityInfo.loadLabel(mPackageManager).toString();
    }

    private Intent getMainLauncherIntentForPackage(String packageName) {
        return new Intent(ACTION_MAIN)
                .addCategory(CATEGORY_LAUNCHER)
                .setPackage(packageName);
    private Intent getMainLauncherIntentForPackage(String pkgName) {
        Intent intent = new Intent(ACTION_MAIN).addCategory(CATEGORY_LAUNCHER).setPackage(pkgName);

        // Not all apps use DEFAULT_CATEGORY for their main launcher activity so the exact component
        // needs to be queried and set on the Intent in order for note-taking apps to be able to
        // start this intent. When starting an activity with an implicit intent, Android adds the
        // DEFAULT_CATEGORY flag otherwise it fails to resolve the intent.
        ResolveInfo resolvedActivity = mPackageManager.resolveActivity(intent, /* flags= */ 0);
        if (resolvedActivity != null) {
            intent.setComponent(resolvedActivity.getComponentInfo().getComponentName());
        }

        return intent;
    }

    /** Helper factory to help with injecting {@link AppClipsViewModel}. */
+9 −3
Original line number Diff line number Diff line
@@ -334,13 +334,17 @@ public final class AppClipsViewModelTest extends SysuiTestCase {
    }

    private void resetPackageManagerMockingForUsingFallbackBacklinks() {
        ResolveInfo backlinksTaskResolveInfo = createBacklinksTaskResolveInfo();
        reset(mPackageManager);
        when(mPackageManager.loadItemIcon(any(), any())).thenReturn(FAKE_DRAWABLE);
        when(mPackageManager.resolveActivity(any(Intent.class), anyInt()))
                // First the logic queries whether a package has a launcher activity, this should
                // Firstly, the logic queries whether a package has a launcher activity, this should
                // resolve otherwise the logic filters out the task.
                .thenReturn(createBacklinksTaskResolveInfo())
                // Then logic queries with the backlinks intent, this should not resolve for the
                .thenReturn(backlinksTaskResolveInfo)
                // Secondly, the logic builds a fallback main launcher intent, this should also
                // resolve for the fallback intent to build correctly.
                .thenReturn(backlinksTaskResolveInfo)
                // Lastly, logic queries with the backlinks intent, this should not resolve for the
                // logic to use the fallback intent.
                .thenReturn(null);
    }
@@ -360,6 +364,8 @@ public final class AppClipsViewModelTest extends SysuiTestCase {
        assertThat(actualBacklinksIntent.getPackage()).isEqualTo(BACKLINKS_TASK_PACKAGE_NAME);
        assertThat(actualBacklinksIntent.getAction()).isEqualTo(ACTION_MAIN);
        assertThat(actualBacklinksIntent.getCategories()).containsExactly(CATEGORY_LAUNCHER);
        assertThat(actualBacklinksIntent.getComponent()).isEqualTo(
                new ComponentName(BACKLINKS_TASK_PACKAGE_NAME, BACKLINKS_TASK_APP_NAME));
    }

    private static ResolveInfo createBacklinksTaskResolveInfo() {