Merge "Updating content description for accessibility no matter the state" into udc-qpr-dev
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 512d5f4..a5ba815 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -1305,11 +1305,9 @@
                                 : groupTask.mSplitBounds.leftTaskPercent);
     }
 
-    @Override
     public boolean isCommandQueueEmpty() {
         OverviewCommandHelper overviewCommandHelper = mTISBindHelper.getOverviewCommandHelper();
-        return super.isCommandQueueEmpty()
-                && (overviewCommandHelper == null || overviewCommandHelper.isCommandQueueEmpty());
+        return overviewCommandHelper == null || overviewCommandHelper.isCommandQueueEmpty();
     }
 
     private static final class LauncherTaskViewController extends
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index e282d1f..8a9c3c8 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -467,10 +467,8 @@
         };
     }
 
-    @Override
     public boolean isCommandQueueEmpty() {
         OverviewCommandHelper overviewCommandHelper = mTISBindHelper.getOverviewCommandHelper();
-        return super.isCommandQueueEmpty()
-                && (overviewCommandHelper == null || overviewCommandHelper.isCommandQueueEmpty());
+        return overviewCommandHelper == null || overviewCommandHelper.isCommandQueueEmpty();
     }
 }
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index a9a57c6..7dc8347 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -86,7 +86,7 @@
     }
 
     @Override
-    public boolean isCommandQueueEmpty() {
+    protected boolean isCommandQueueEmpty() {
         return mActivity.isCommandQueueEmpty();
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 9e9b22f..3ee9009 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -90,7 +90,7 @@
     }
 
     @Override
-    public boolean isCommandQueueEmpty() {
+    protected boolean isCommandQueueEmpty() {
         return mActivity.isCommandQueueEmpty();
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index f0daf8d..421a48c 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -2374,7 +2374,7 @@
     protected abstract void handleStartHome(boolean animated);
 
     /** Returns whether the overview command helper queue is empty. */
-    public abstract boolean isCommandQueueEmpty();
+    protected abstract boolean isCommandQueueEmpty();
 
     public void reset() {
         setCurrentTask(-1);
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 40e3dca..5301c7c 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -842,17 +842,20 @@
                 // the actual overview state
                 failureListener.register(mActivity, mTask.key.id, () -> {
                     notifyTaskLaunchFailed(TAG);
-                    // Disable animations for now, as it is an edge case and the app usually covers
-                    // launcher and also any state transition animation also gets clobbered by
-                    // QuickstepTransitionManager.createWallpaperOpenAnimations when launcher
-                    // shows again
-                    getRecentsView().startHome(false /* animated */);
                     RecentsView rv = getRecentsView();
-                    if (rv != null && rv.mSizeStrategy.getTaskbarController() != null) {
-                        // LauncherTaskbarUIController depends on the launcher state when checking
-                        // whether to handle resume, but that can come in before startHome() changes
-                        // the state, so force-refresh here to ensure the taskbar is updated
-                        rv.mSizeStrategy.getTaskbarController().refreshResumedState();
+                    if (rv != null) {
+                        // Disable animations for now, as it is an edge case and the app usually
+                        // covers launcher and also any state transition animation also gets
+                        // clobbered by QuickstepTransitionManager.createWallpaperOpenAnimations
+                        // when launcher shows again
+                        rv.startHome(false /* animated */);
+                        if (rv.mSizeStrategy.getTaskbarController() != null) {
+                            // LauncherTaskbarUIController depends on the launcher state when
+                            // checking whether to handle resume, but that can come in before
+                            // startHome() changes the state, so force-refresh here to ensure the
+                            // taskbar is updated
+                            rv.mSizeStrategy.getTaskbarController().refreshResumedState();
+                        }
                     }
                 });
             }
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index a7a25f4..758bffb 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -7,6 +7,7 @@
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
+import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_NOT_PINNABLE;
 
 import android.appwidget.AppWidgetProviderInfo;
 import android.graphics.Point;
@@ -124,12 +125,19 @@
             }
         }
 
-        if ((item instanceof WorkspaceItemFactory) || (item instanceof WorkspaceItemInfo)
-                || (item instanceof PendingAddItemInfo)) {
+        if (supportAddToWorkSpace(item)) {
             out.add(mActions.get(ADD_TO_WORKSPACE));
         }
     }
 
+    private boolean supportAddToWorkSpace(ItemInfo item) {
+        return (item instanceof WorkspaceItemFactory)
+                || ((item instanceof WorkspaceItemInfo)
+                    && (((WorkspaceItemInfo) item).runtimeStatusFlags & FLAG_NOT_PINNABLE) == 0)
+                || ((item instanceof PendingAddItemInfo)
+                    && (((PendingAddItemInfo) item).runtimeStatusFlags & FLAG_NOT_PINNABLE) == 0);
+    }
+
     /**
      * Returns all the accessibility actions that can be handled by the host.
      */
diff --git a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
index e5fb015..b4a935a 100644
--- a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
+++ b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
@@ -119,6 +119,11 @@
             | FLAG_DISABLED_VERSION_LOWER;
 
     /**
+     * Flag indicating this item can't be pinned to home screen.
+     */
+    public static final int FLAG_NOT_PINNABLE = 1 << 13;
+
+    /**
      * Status associated with the system state of the underlying item. This is calculated every
      * time a new info is created and not persisted on the disk.
      */
diff --git a/src/com/android/launcher3/statemanager/StatefulActivity.java b/src/com/android/launcher3/statemanager/StatefulActivity.java
index de5887f..520f33c 100644
--- a/src/com/android/launcher3/statemanager/StatefulActivity.java
+++ b/src/com/android/launcher3/statemanager/StatefulActivity.java
@@ -237,10 +237,4 @@
      * @param leftOrTop if the staged split will be positioned left or top.
      */
     public void enterStageSplitFromRunningApp(boolean leftOrTop) { }
-
-
-    /** Returns whether the overview command helper queue is empty. */
-    public boolean isCommandQueueEmpty() {
-        return true;
-    }
 }
diff --git a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
index 8cc01ff..36e4e76 100644
--- a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
+++ b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
@@ -156,6 +156,7 @@
     public static final String WORK_TAB_MISSING = "b/243688989";
     public static final String TWO_TASKBAR_LONG_CLICKS = "b/262282528";
     public static final String FLAKY_ACTIVITY_COUNT = "b/260260325";
+    public static final String ICON_MISSING = "b/282963545";
 
     public static final String REQUEST_EMULATE_DISPLAY = "emulate-display";
     public static final String REQUEST_STOP_EMULATE_DISPLAY = "stop-emulate-display";
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 1262a26..7f796e7 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -17,6 +17,7 @@
 
 import static androidx.test.InstrumentationRegistry.getInstrumentation;
 
+import static com.android.launcher3.testing.shared.TestProtocol.ICON_MISSING;
 import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 
@@ -603,6 +604,8 @@
 
     protected HomeAppIcon createShortcutIfNotExist(String name, int cellX, int cellY) {
         HomeAppIcon homeAppIcon = mLauncher.getWorkspace().tryGetWorkspaceAppIcon(name);
+        Log.d(ICON_MISSING, "homeAppIcon: " + homeAppIcon + " name: " + name +
+                " cell: " + cellX + ", " + cellY);
         if (homeAppIcon == null) {
             HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
             allApps.freeze();
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 095b135..2c8acc4 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -18,6 +18,8 @@
 
 import static androidx.test.InstrumentationRegistry.getInstrumentation;
 
+import static com.android.launcher3.testing.shared.TestProtocol.ICON_MISSING;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertEquals;
@@ -579,6 +581,11 @@
     @PlatinumTest(focusArea = "launcher")
     public void getIconsPosition_afterIconRemoved_notContained() throws IOException {
         Point[] gridPositions = getCornersAndCenterPositions();
+        StringBuilder sb = new StringBuilder();
+        for (Point p : gridPositions) {
+            sb.append(p).append(", ");
+        }
+        Log.d(ICON_MISSING, "allGridPositions: " + sb);
         createShortcutIfNotExist(STORE_APP_NAME, gridPositions[0]);
         createShortcutIfNotExist(MAPS_APP_NAME, gridPositions[1]);
         installDummyAppAndWaitForUIUpdate();