Merge "Add placeholder divider view when starting split tasks" into 24D1-dev
diff --git a/quickstep/res/values-land/dimens.xml b/quickstep/res/values-land/dimens.xml
index 2b17b93..e862b9e 100644
--- a/quickstep/res/values-land/dimens.xml
+++ b/quickstep/res/values-land/dimens.xml
@@ -78,7 +78,8 @@
     <!--  Taskbar 3 button spacing  -->
     <dimen name="taskbar_button_margin_split">88dp</dimen>
     <dimen name="taskbar_button_margin_6_5">219.6dp</dimen>
-    <dimen name="taskbar_contextual_button_margin">48dp</dimen>
+    <dimen name="taskbar_contextual_button_suw_margin">48dp</dimen>
+    <dimen name="taskbar_contextual_button_suw_height">48dp</dimen>
     <dimen name="taskbar_suw_frame">96dp</dimen>
     <dimen name="taskbar_suw_insets">24dp</dimen>
 
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 3331321..89a193b 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -325,9 +325,8 @@
     <dimen name="taskbar_contextual_padding_top">8dp</dimen>
     <dimen name="taskbar_nav_buttons_size">44dp</dimen>
     <dimen name="taskbar_split_instructions_margin">48dp</dimen>
-    <dimen name="taskbar_contextual_button_margin">120dp</dimen>
     <dimen name="taskbar_suw_insets">48dp</dimen>
-    <dimen name="taskbar_suw_frame">48dp</dimen>
+    <dimen name="taskbar_suw_frame">96dp</dimen>
     <dimen name="taskbar_hotseat_nav_spacing">24dp</dimen>
     <dimen name="taskbar_contextual_buttons_size">35dp</dimen>
     <dimen name="taskbar_stashed_size">24dp</dimen>
@@ -346,6 +345,11 @@
     <dimen name="taskbar_icon_size_kids">32dp</dimen>
     <dimen name="taskbar_all_apps_button_translation_x_offset">6dp</dimen>
     <dimen name="taskbar_all_apps_search_button_translation_x_offset">6dp</dimen>
+    <dimen name="taskbar_contextual_button_suw_margin">64dp</dimen>
+    <dimen name="taskbar_contextual_button_suw_height">64dp</dimen>
+    <dimen name="taskbar_back_button_suw_start_margin">48dp</dimen>
+    <dimen name="taskbar_back_button_suw_bottom_margin">1dp</dimen>
+    <dimen name="taskbar_back_button_suw_height">72dp</dimen>
 
     <!-- Transient taskbar -->
     <dimen name="transient_taskbar_padding">12dp</dimen>
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index 2f11fd7..2c5aeb3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -142,6 +142,9 @@
 
     private static final String NAV_BUTTONS_SEPARATE_WINDOW_TITLE = "Taskbar Nav Buttons";
 
+    private static final double SQUARE_ASPECT_RATIO_BOTTOM_BOUND = 0.95;
+    private static final double SQUARE_ASPECT_RATIO_UPPER_BOUND = 1.05;
+
     public static final int ALPHA_INDEX_IMMERSIVE_MODE = 0;
     public static final int ALPHA_INDEX_KEYGUARD_OR_DISABLE = 1;
     public static final int ALPHA_INDEX_SUW = 2;
@@ -735,18 +738,39 @@
         // end-aligned, so start-align instead.
         FrameLayout.LayoutParams navButtonsLayoutParams = (FrameLayout.LayoutParams)
                 mNavButtonContainer.getLayoutParams();
+        FrameLayout.LayoutParams navButtonsViewLayoutParams = (FrameLayout.LayoutParams)
+                mNavButtonsView.getLayoutParams();
         Resources resources = mContext.getResources();
         DeviceProfile deviceProfile = mContext.getDeviceProfile();
-        int setupMargin = resources.getDimensionPixelSize(R.dimen.taskbar_contextual_button_margin);
-        navButtonsLayoutParams.setMarginStart(setupMargin);
-        navButtonsLayoutParams.bottomMargin = !deviceProfile.isLandscape
-                ? 0
-                : setupMargin -
-                        (resources.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size) / 2);
+
         navButtonsLayoutParams.setMarginEnd(0);
         navButtonsLayoutParams.gravity = Gravity.START;
-        mNavButtonsView.getLayoutParams().height =
-                mControllers.taskbarActivityContext.getSetupWindowSize();
+        mControllers.taskbarActivityContext.setTaskbarWindowSize(
+                mControllers.taskbarActivityContext.getSetupWindowSize());
+
+        // If SUW is on a large screen device that is landscape (or has a square aspect
+        // ratio) the back button has to be placed accordingly
+        if ((deviceProfile.isTablet && deviceProfile.isLandscape)
+                || (deviceProfile.aspectRatio > SQUARE_ASPECT_RATIO_BOTTOM_BOUND
+                && deviceProfile.aspectRatio < SQUARE_ASPECT_RATIO_UPPER_BOUND)) {
+            navButtonsLayoutParams.setMarginStart(
+                    resources.getDimensionPixelSize(R.dimen.taskbar_back_button_suw_start_margin));
+            navButtonsViewLayoutParams.bottomMargin = resources.getDimensionPixelSize(
+                    R.dimen.taskbar_back_button_suw_bottom_margin);
+            navButtonsLayoutParams.height = resources.getDimensionPixelSize(
+                    R.dimen.taskbar_back_button_suw_height);
+        } else {
+            int phoneOrPortraitSetupMargin = resources.getDimensionPixelSize(
+                    R.dimen.taskbar_contextual_button_suw_margin);
+            navButtonsLayoutParams.setMarginStart(phoneOrPortraitSetupMargin);
+            navButtonsLayoutParams.bottomMargin = !deviceProfile.isLandscape
+                    ? 0
+                    : phoneOrPortraitSetupMargin - (resources.getDimensionPixelSize(
+                            R.dimen.taskbar_nav_buttons_size) / 2);
+            navButtonsViewLayoutParams.height = resources.getDimensionPixelSize(
+                    R.dimen.taskbar_contextual_button_suw_height);
+        }
+        mNavButtonsView.setLayoutParams(navButtonsViewLayoutParams);
         mNavButtonContainer.setLayoutParams(navButtonsLayoutParams);
     }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt
index 2b60dc0..5bfdce9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt
@@ -20,7 +20,6 @@
 import android.view.Surface.ROTATION_90
 import android.view.Surface.Rotation
 import android.view.ViewGroup
-import android.widget.FrameLayout
 import android.widget.ImageView
 import android.widget.LinearLayout
 import android.widget.Space
@@ -56,18 +55,18 @@
          * @param isThreeButtonNav are no-ops when taskbar is present/showing
          */
         fun getUiLayoutter(
-                deviceProfile: DeviceProfile,
-                navButtonsView: NearestTouchFrame,
-                imeSwitcher: ImageView?,
-                rotationButton: RotationButton?,
-                a11yButton: ImageView?,
-                space: Space?,
-                resources: Resources,
-                isKidsMode: Boolean,
-                isInSetup: Boolean,
-                isThreeButtonNav: Boolean,
-                phoneMode: Boolean,
-                @Rotation surfaceRotation: Int
+            deviceProfile: DeviceProfile,
+            navButtonsView: NearestTouchFrame,
+            imeSwitcher: ImageView?,
+            rotationButton: RotationButton?,
+            a11yButton: ImageView?,
+            space: Space?,
+            resources: Resources,
+            isKidsMode: Boolean,
+            isInSetup: Boolean,
+            isThreeButtonNav: Boolean,
+            phoneMode: Boolean,
+            @Rotation surfaceRotation: Int
         ): NavButtonLayoutter {
             val navButtonContainer =
                 navButtonsView.requireViewById<LinearLayout>(ID_END_NAV_BUTTONS)
@@ -82,43 +81,6 @@
                     if (!deviceProfile.isLandscape) {
                         navButtonsView.setIsVertical(false)
                         PhonePortraitNavLayoutter(
-                                resources,
-                                navButtonContainer,
-                                endContextualContainer,
-                                startContextualContainer,
-                                imeSwitcher,
-                                rotationButton,
-                                a11yButton,
-                                space
-                        )
-                    } else if (surfaceRotation == ROTATION_90) {
-                        navButtonsView.setIsVertical(true)
-                        PhoneLandscapeNavLayoutter(
-                                resources,
-                                navButtonContainer,
-                                endContextualContainer,
-                                startContextualContainer,
-                                imeSwitcher,
-                                rotationButton,
-                                a11yButton,
-                                space
-                        )
-                    } else {
-                        navButtonsView.setIsVertical(true)
-                        PhoneSeascapeNavLayoutter(
-                                resources,
-                                navButtonContainer,
-                                endContextualContainer,
-                                startContextualContainer,
-                                imeSwitcher,
-                                rotationButton,
-                                a11yButton,
-                                space
-                        )
-                    }
-                }
-                isPhoneGestureMode ->{
-                    PhoneGestureLayoutter(
                             resources,
                             navButtonContainer,
                             endContextualContainer,
@@ -127,44 +89,82 @@
                             rotationButton,
                             a11yButton,
                             space
+                        )
+                    } else if (surfaceRotation == ROTATION_90) {
+                        navButtonsView.setIsVertical(true)
+                        PhoneLandscapeNavLayoutter(
+                            resources,
+                            navButtonContainer,
+                            endContextualContainer,
+                            startContextualContainer,
+                            imeSwitcher,
+                            rotationButton,
+                            a11yButton,
+                            space
+                        )
+                    } else {
+                        navButtonsView.setIsVertical(true)
+                        PhoneSeascapeNavLayoutter(
+                            resources,
+                            navButtonContainer,
+                            endContextualContainer,
+                            startContextualContainer,
+                            imeSwitcher,
+                            rotationButton,
+                            a11yButton,
+                            space
+                        )
+                    }
+                }
+                isPhoneGestureMode -> {
+                    PhoneGestureLayoutter(
+                        resources,
+                        navButtonContainer,
+                        endContextualContainer,
+                        startContextualContainer,
+                        imeSwitcher,
+                        rotationButton,
+                        a11yButton,
+                        space
                     )
                 }
                 deviceProfile.isTaskbarPresent -> {
                     return when {
                         isInSetup -> {
                             SetupNavLayoutter(
-                                    resources,
-                                    navButtonContainer,
-                                    endContextualContainer,
-                                    startContextualContainer,
-                                    imeSwitcher,
-                                    rotationButton,
-                                    a11yButton,
-                                    space
+                                resources,
+                                navButtonsView,
+                                navButtonContainer,
+                                endContextualContainer,
+                                startContextualContainer,
+                                imeSwitcher,
+                                rotationButton,
+                                a11yButton,
+                                space
                             )
                         }
                         isKidsMode -> {
                             KidsNavLayoutter(
-                                    resources,
-                                    navButtonContainer,
-                                    endContextualContainer,
-                                    startContextualContainer,
-                                    imeSwitcher,
-                                    rotationButton,
-                                    a11yButton,
-                                    space
+                                resources,
+                                navButtonContainer,
+                                endContextualContainer,
+                                startContextualContainer,
+                                imeSwitcher,
+                                rotationButton,
+                                a11yButton,
+                                space
                             )
                         }
                         else ->
                             TaskbarNavLayoutter(
-                                    resources,
-                                    navButtonContainer,
-                                    endContextualContainer,
-                                    startContextualContainer,
-                                    imeSwitcher,
-                                    rotationButton,
-                                    a11yButton,
-                                    space
+                                resources,
+                                navButtonContainer,
+                                endContextualContainer,
+                                startContextualContainer,
+                                imeSwitcher,
+                                rotationButton,
+                                a11yButton,
+                                space
                             )
                     }
                 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt
index 181e0ed..8eff95c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt
@@ -24,50 +24,89 @@
 import android.widget.ImageView
 import android.widget.LinearLayout
 import android.widget.Space
+import com.android.launcher3.DeviceProfile
 import com.android.launcher3.R
 import com.android.launcher3.taskbar.TaskbarActivityContext
 import com.android.systemui.shared.rotation.RotationButton
 
+const val SQUARE_ASPECT_RATIO_BOTTOM_BOUND = 0.95
+const val SQUARE_ASPECT_RATIO_UPPER_BOUND = 1.05
+
 class SetupNavLayoutter(
-        resources: Resources,
-        navButtonContainer: LinearLayout,
-        endContextualContainer: ViewGroup,
-        startContextualContainer: ViewGroup,
-        imeSwitcher: ImageView?,
-        rotationButton: RotationButton?,
-        a11yButton: ImageView?,
-        space: Space?
+    resources: Resources,
+    navButtonsView: NearestTouchFrame,
+    navButtonContainer: LinearLayout,
+    endContextualContainer: ViewGroup,
+    startContextualContainer: ViewGroup,
+    imeSwitcher: ImageView?,
+    rotationButton: RotationButton?,
+    a11yButton: ImageView?,
+    space: Space?
 ) :
     AbstractNavButtonLayoutter(
-            resources,
-            navButtonContainer,
-            endContextualContainer,
-            startContextualContainer,
-            imeSwitcher,
-            rotationButton,
-            a11yButton,
-            space
+        resources,
+        navButtonContainer,
+        endContextualContainer,
+        startContextualContainer,
+        imeSwitcher,
+        rotationButton,
+        a11yButton,
+        space
     ) {
+    private val mNavButtonsView = navButtonsView
 
     override fun layoutButtons(context: TaskbarActivityContext, isA11yButtonPersistent: Boolean) {
         // Since setup wizard only has back button enabled, it looks strange to be
         // end-aligned, so start-align instead.
         val navButtonsLayoutParams = navButtonContainer.layoutParams as FrameLayout.LayoutParams
-        navButtonsLayoutParams.apply {
-            marginStart = navButtonsLayoutParams.marginEnd
-            marginEnd = 0
-            gravity = Gravity.START
+        val navButtonsViewLayoutParams = mNavButtonsView.layoutParams as FrameLayout.LayoutParams
+        val deviceProfile: DeviceProfile = context.deviceProfile
+
+        navButtonsLayoutParams.marginEnd = 0
+        navButtonsLayoutParams.gravity = Gravity.START
+        context.setTaskbarWindowSize(context.setupWindowSize)
+
+        // If SUW is on a large screen device that is landscape (or has a square aspect
+        // ratio) the back button has to be placed accordingly
+        if (
+            deviceProfile.isTablet && deviceProfile.isLandscape ||
+                (deviceProfile.aspectRatio > SQUARE_ASPECT_RATIO_BOTTOM_BOUND &&
+                    deviceProfile.aspectRatio < SQUARE_ASPECT_RATIO_UPPER_BOUND)
+        ) {
+            navButtonsLayoutParams.marginStart =
+                resources.getDimensionPixelSize(R.dimen.taskbar_back_button_suw_start_margin)
+            navButtonsViewLayoutParams.bottomMargin =
+                resources.getDimensionPixelSize(R.dimen.taskbar_back_button_suw_bottom_margin)
+            navButtonsLayoutParams.height =
+                resources.getDimensionPixelSize(R.dimen.taskbar_back_button_suw_height)
+        } else {
+            val phoneOrPortraitSetupMargin =
+                resources.getDimensionPixelSize(R.dimen.taskbar_contextual_button_suw_margin)
+            navButtonsLayoutParams.marginStart = phoneOrPortraitSetupMargin
+            navButtonsLayoutParams.bottomMargin =
+                if (!deviceProfile.isLandscape) 0
+                else
+                    phoneOrPortraitSetupMargin -
+                        resources.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size) / 2
+            navButtonsViewLayoutParams.height =
+                resources.getDimensionPixelSize(R.dimen.taskbar_contextual_button_suw_height)
         }
-        navButtonContainer.requestLayout()
+        mNavButtonsView.layoutParams = navButtonsViewLayoutParams
+        navButtonContainer.layoutParams = navButtonsLayoutParams
 
         endContextualContainer.removeAllViews()
         startContextualContainer.removeAllViews()
 
-        val contextualMargin = resources.getDimensionPixelSize(
-                R.dimen.taskbar_contextual_button_padding)
+        val contextualMargin =
+            resources.getDimensionPixelSize(R.dimen.taskbar_contextual_button_padding)
         repositionContextualContainer(endContextualContainer, WRAP_CONTENT, 0, 0, Gravity.END)
-        repositionContextualContainer(startContextualContainer, WRAP_CONTENT, contextualMargin,
-                contextualMargin, Gravity.START)
+        repositionContextualContainer(
+            startContextualContainer,
+            WRAP_CONTENT,
+            contextualMargin,
+            contextualMargin,
+            Gravity.START
+        )
 
         if (imeSwitcher != null) {
             startContextualContainer.addView(imeSwitcher)
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 76109c0..69c7114 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -396,7 +396,7 @@
     <dimen name="transient_taskbar_clamped_offset_bound">0dp</dimen>
     <dimen name="taskbar_icon_spacing">0dp</dimen>
     <dimen name="taskbar_nav_buttons_size">0dp</dimen>
-    <dimen name="taskbar_contextual_button_margin">0dp</dimen>
+    <dimen name="taskbar_contextual_button_suw_margin">0dp</dimen>
     <dimen name="taskbar_hotseat_nav_spacing">0dp</dimen>
     <dimen name="taskbar_button_margin_default">0dp</dimen>
     <dimen name="taskbar_button_space_inbetween">0dp</dimen>
diff --git a/src/com/android/launcher3/apppairs/AppPairIcon.java b/src/com/android/launcher3/apppairs/AppPairIcon.java
index 0e955ad..1f73241 100644
--- a/src/com/android/launcher3/apppairs/AppPairIcon.java
+++ b/src/com/android/launcher3/apppairs/AppPairIcon.java
@@ -143,7 +143,7 @@
         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);
     }
diff --git a/src/com/android/launcher3/apppairs/AppPairIconGraphic.kt b/src/com/android/launcher3/apppairs/AppPairIconGraphic.kt
index 7809102..dce97eb 100644
--- a/src/com/android/launcher3/apppairs/AppPairIconGraphic.kt
+++ b/src/com/android/launcher3/apppairs/AppPairIconGraphic.kt
@@ -55,6 +55,12 @@
             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)
diff --git a/src/com/android/launcher3/model/data/AppPairInfo.kt b/src/com/android/launcher3/model/data/AppPairInfo.kt
index fad365c..3dbd45b 100644
--- a/src/com/android/launcher3/model/data/AppPairInfo.kt
+++ b/src/com/android/launcher3/model/data/AppPairInfo.kt
@@ -68,12 +68,15 @@
     /** 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. */
     fun fetchHiResIconsIfNeeded(iconCache: IconCache) {
@@ -83,13 +86,14 @@
     }
 
     /**
-     * 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. */
diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java
index 816d5e9..f226b8d 100644
--- a/src/com/android/launcher3/touch/ItemClickHandler.java
+++ b/src/com/android/launcher3/touch/ItemClickHandler.java
@@ -149,9 +149,12 @@
      */
     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 @@
                             : 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);
     }
 
     /**