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

Commit 841e6c1e authored by Jeremy Sim's avatar Jeremy Sim Committed by Vinit Nayak
Browse files

Set camera icon as gray when app is unlaunchable

This CL is a follow-up to ag/26825455. Now that we are changing app pairs' disabled appearance back to icon-only, the case where a camera icon should be grayed out on an app pair on a small screen needs to be reinstated.

Fixes: 333137187
Flag: ACONFIG com.android.wm.shell.enable_app_pairs TRUNKFOOD
Test: Manual
Change-Id: I64ae3db28293fa0adc249d700e9e03c074b6854f
(cherry picked from commit a5e838d6)
Merged-In: I64ae3db28293fa0adc249d700e9e03c074b6854f
parent 1ece740e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -143,7 +143,7 @@ public class AppPairIcon extends FrameLayout implements DraggableView, Reorderab
        CharSequence app2 = getInfo().getSecondApp().title;
        String a11yTitle = getContext().getString(R.string.app_pair_name_format, app1, app2);
        setContentDescription(
                getInfo().shouldDrawAsDisabled(getContext())
                getInfo().shouldReportDisabled(getContext())
                        ? getContext().getString(R.string.disabled_app_label, a11yTitle)
                        : a11yTitle);
    }
+6 −0
Original line number Diff line number Diff line
@@ -55,6 +55,12 @@ constructor(context: Context, attrs: AttributeSet? = null) :
            appIcon1.setBounds(0, 0, p.memberIconSize.toInt(), p.memberIconSize.toInt())
            appIcon2.setBounds(0, 0, p.memberIconSize.toInt(), p.memberIconSize.toInt())

            // If icons are unlaunchable due to screen size, manually override disabled appearance.
            // (otherwise, leave disabled state alone; icons will naturally inherit the app's state)
            val (isApp1Launchable, isApp2Launchable) = appPairInfo.isLaunchable(p.context)
            if (!isApp1Launchable) appIcon1.setIsDisabled(true)
            if (!isApp2Launchable) appIcon2.setIsDisabled(true)

            // Create icon drawable.
            val fullIconDrawable = AppPairIconDrawable(p, appIcon1, appIcon2)
            fullIconDrawable.setBounds(0, 0, p.iconSize, p.iconSize)
+13 −9
Original line number Diff line number Diff line
@@ -68,11 +68,14 @@ class AppPairInfo() : CollectionInfo() {
    /** Returns if either of the app pair members is currently disabled. */
    override fun isDisabled() = anyMatch { it.isDisabled }

    /** Checks if the app pair is launchable at the current screen size. */
    fun isLaunchable(context: Context) =
        (ActivityContext.lookupContext(context) as ActivityContext).getDeviceProfile().isTablet ||
            getAppContents().stream().noneMatch {
                it.hasStatusFlag(WorkspaceItemInfo.FLAG_NON_RESIZEABLE)
    /** Checks if member apps are launchable at the current screen size. */
    fun isLaunchable(context: Context): Pair<Boolean, Boolean> {
        val isTablet =
            (ActivityContext.lookupContext(context) as ActivityContext).getDeviceProfile().isTablet
        return Pair(
            isTablet || !getFirstApp().hasStatusFlag(WorkspaceItemInfo.FLAG_NON_RESIZEABLE),
            isTablet || !getSecondApp().hasStatusFlag(WorkspaceItemInfo.FLAG_NON_RESIZEABLE)
        )
    }

    /** Fetches high-res icons for member apps if needed. */
@@ -83,13 +86,14 @@ class AppPairInfo() : CollectionInfo() {
    }

    /**
     * App pairs will draw as "disabled" if either of the following is true:
     * App pairs will report itself as "disabled" (for accessibility) if either of the following is
     * true:
     * 1) One of the member WorkspaceItemInfos is disabled (i.e. the app software itself is paused
     *    or can't be launched for some other reason).
     * 2) One of the member apps can't be launched due to screen size requirements.
     */
    fun shouldDrawAsDisabled(context: Context): Boolean {
        return isDisabled || !isLaunchable(context)
    fun shouldReportDisabled(context: Context): Boolean {
        return isDisabled || !isLaunchable(context).first || !isLaunchable(context).second
    }

    /** Generates a default title for the app pair and sets it. */
+14 −10
Original line number Diff line number Diff line
@@ -149,9 +149,12 @@ public class ItemClickHandler {
     */
    private static void onClickAppPairIcon(View v) {
        Launcher launcher = Launcher.getLauncher(v.getContext());
        AppPairIcon appPairIcon = (AppPairIcon) v;
        if (!appPairIcon.getInfo().isLaunchable(launcher)) {
            // Display a message for app pairs that are disabled due to screen size
        AppPairIcon icon = (AppPairIcon) v;
        AppPairInfo info = icon.getInfo();
        boolean isApp1Launchable = info.isLaunchable(launcher).getFirst(),
                isApp2Launchable = info.isLaunchable(launcher).getSecond();
        if (!isApp1Launchable || !isApp2Launchable) {
            // App pair is unlaunchable due to screen size.
            boolean isFoldable = InvariantDeviceProfile.INSTANCE.get(launcher)
                    .supportedProfiles.stream().anyMatch(dp -> dp.isTwoPanels);
            Toast.makeText(launcher, isFoldable
@@ -159,26 +162,27 @@ public class ItemClickHandler {
                            : R.string.app_pair_unlaunchable_at_screen_size,
                    Toast.LENGTH_SHORT).show();
            return;
        } else if (appPairIcon.getInfo().isDisabled()) {
            WorkspaceItemInfo app1 = appPairIcon.getInfo().getFirstApp();
            WorkspaceItemInfo app2 = appPairIcon.getInfo().getSecondApp();
        } else if (info.isDisabled()) {
            // App pair is disabled for another reason.
            WorkspaceItemInfo app1 = info.getFirstApp();
            WorkspaceItemInfo app2 = info.getSecondApp();
            // Show the user why the app pair is disabled.
            if (app1.isDisabled() && app2.isDisabled()) {
                // Both apps are disabled, show "app pair is not available" toast.
                // Both apps are disabled, show generic "app pair is not available" toast.
                Toast.makeText(launcher, R.string.app_pair_not_available, Toast.LENGTH_SHORT)
                        .show();
                return;
            } else if ((app1.isDisabled() && handleDisabledItemClicked(app1, launcher))
                    || (app2.isDisabled() && handleDisabledItemClicked(app2, launcher))) {
                // Only one is disabled, and handleDisabledItemClicked() will show a toast, so we
                // are done.
                // Only one is disabled, and handleDisabledItemClicked() showed a specific toast
                // explaining why, so we are done.
                return;
            }
        }

        // Either the app pair is not disabled, or it is a disabled state that can be handled by
        // framework directly (e.g. one app is paused), so go ahead and launch.
        launcher.launchAppPair(appPairIcon);
        launcher.launchAppPair(icon);
    }

    /**