[automerger skipped] Merge "AOSP/Launcher3 - Update language to comply with Android's inclusive language guidance.  DO NOT MERGE" am: af6968dcec am: c7e0fc92e2 -s ours am: f617d254ca

Original change: https://android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/1389245

Change-Id: Ic3557075b54f6f44fc1cb31fea7eff6536b858cd
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml
index dd0fc21..ff5bf0d 100644
--- a/AndroidManifest-common.xml
+++ b/AndroidManifest-common.xml
@@ -156,8 +156,7 @@
         <provider
             android:name="com.android.launcher3.graphics.GridOptionsProvider"
             android:authorities="${packageName}.grid_control"
-            android:exported="true"
-            android:enabled="false" />
+            android:exported="true" />
 
         <!--
         The settings activity. To extend point settings_fragment_name to appropriate fragment class
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
index a63f3a8..aba5ab6 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -39,6 +39,7 @@
 import com.android.quickstep.RecentsAnimationCallbacks.RecentsAnimationListener;
 import com.android.quickstep.util.ActiveGestureLog;
 import com.android.quickstep.util.ActivityInitListener;
+import com.android.quickstep.util.InputConsumerProxy;
 import com.android.quickstep.util.RectFSpringAnim;
 import com.android.quickstep.util.SurfaceTransactionApplier;
 import com.android.quickstep.util.TransformParams;
@@ -61,7 +62,7 @@
     private static final String TAG = "BaseSwipeUpHandler";
 
     protected final BaseActivityInterface<?, T> mActivityInterface;
-    protected final InputConsumerController mInputConsumer;
+    protected final InputConsumerProxy mInputConsumerProxy;
 
     protected final ActivityInitListener mActivityInitListener;
 
@@ -87,7 +88,8 @@
         super(context, deviceState, gestureState, new TransformParams());
         mActivityInterface = gestureState.getActivityInterface();
         mActivityInitListener = mActivityInterface.createActivityInitListener(this::onActivityInit);
-        mInputConsumer = inputConsumer;
+        mInputConsumerProxy =
+                new InputConsumerProxy(inputConsumer, this::createNewInputProxyHandler);
     }
 
     /**
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java
index 6c4c5d3..f0f3d0f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java
@@ -850,11 +850,9 @@
             }
         }
 
-        if (endTarget.isLauncher && mRecentsAnimationController != null) {
-            mRecentsAnimationController.enableInputProxy(mInputConsumer,
-                    this::createNewInputProxyHandler);
+        if (endTarget.isLauncher) {
+            mInputConsumerProxy.enable();
         }
-
         if (endTarget == HOME) {
             setShelfState(ShelfAnimState.CANCEL, LINEAR, 0);
             duration = Math.max(MIN_OVERSHOOT_DURATION, duration);
@@ -1181,6 +1179,7 @@
     }
 
     private void invalidateHandler() {
+        mInputConsumerProxy.destroy();
         endRunningWindowAnim(false /* cancel */);
 
         if (mGestureEndCallback != null) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/InputConsumerProxy.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/InputConsumerProxy.java
new file mode 100644
index 0000000..3e87f48
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/InputConsumerProxy.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import static android.view.MotionEvent.ACTION_CANCEL;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_UP;
+
+import android.util.Log;
+import android.view.InputEvent;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import com.android.quickstep.InputConsumer;
+import com.android.systemui.shared.system.InputConsumerController;
+
+import java.util.function.Supplier;
+
+/**
+ * Utility class which manages proxying input events from {@link InputConsumerController}
+ * to an {@link InputConsumer}
+ */
+public class InputConsumerProxy {
+
+    private static final String TAG = "InputConsumerProxy";
+
+    private final InputConsumerController mInputConsumerController;
+    private final Supplier<InputConsumer> mConsumerSupplier;
+
+    // The consumer is created lazily on demand.
+    private InputConsumer mInputConsumer;
+
+    private boolean mDestroyed = false;
+    private boolean mTouchInProgress = false;
+    private boolean mDestroyPending = false;
+
+    public InputConsumerProxy(InputConsumerController inputConsumerController,
+            Supplier<InputConsumer> consumerSupplier) {
+        mInputConsumerController = inputConsumerController;
+        mConsumerSupplier = consumerSupplier;
+    }
+
+    public void enable() {
+        if (mDestroyed) {
+            return;
+        }
+        mInputConsumerController.setInputListener(this::onInputConsumerEvent);
+    }
+
+    private boolean onInputConsumerEvent(InputEvent ev) {
+        if (ev instanceof MotionEvent) {
+            onInputConsumerMotionEvent((MotionEvent) ev);
+        } else if (ev instanceof KeyEvent) {
+            if (mInputConsumer == null) {
+                mInputConsumer = mConsumerSupplier.get();
+            }
+            mInputConsumer.onKeyEvent((KeyEvent) ev);
+            return true;
+        }
+        return false;
+    }
+
+    private boolean onInputConsumerMotionEvent(MotionEvent ev) {
+        int action = ev.getAction();
+
+        // Just to be safe, verify that ACTION_DOWN comes before any other action,
+        // and ignore any ACTION_DOWN after the first one (though that should not happen).
+        if (!mTouchInProgress && action != ACTION_DOWN) {
+            Log.w(TAG, "Received non-down motion before down motion: " + action);
+            return false;
+        }
+        if (mTouchInProgress && action == ACTION_DOWN) {
+            Log.w(TAG, "Received down motion while touch was already in progress");
+            return false;
+        }
+
+        if (action == ACTION_DOWN) {
+            mTouchInProgress = true;
+            if (mInputConsumer == null) {
+                mInputConsumer = mConsumerSupplier.get();
+            }
+        } else if (action == ACTION_CANCEL || action == ACTION_UP) {
+            // Finish any pending actions
+            mTouchInProgress = false;
+            if (mDestroyPending) {
+                destroy();
+            }
+        }
+        if (mInputConsumer != null) {
+            mInputConsumer.onMotionEvent(ev);
+        }
+
+        return true;
+    }
+
+    public void destroy() {
+        if (mTouchInProgress) {
+            mDestroyPending = true;
+            return;
+        }
+        mDestroyPending = false;
+        mDestroyed = true;
+        mInputConsumerController.setInputListener(null);
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index 4e9aa61..51f5e5d 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -15,49 +15,30 @@
  */
 package com.android.quickstep;
 
-import static android.view.MotionEvent.ACTION_CANCEL;
-import static android.view.MotionEvent.ACTION_DOWN;
-import static android.view.MotionEvent.ACTION_UP;
-
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 
-import android.os.SystemClock;
-import android.util.Log;
-import android.view.InputEvent;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
 import androidx.annotation.NonNull;
 import androidx.annotation.UiThread;
 
 import com.android.launcher3.util.Preconditions;
 import com.android.systemui.shared.recents.model.ThumbnailData;
-import com.android.systemui.shared.system.InputConsumerController;
 import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 
 import java.util.function.Consumer;
-import java.util.function.Supplier;
 
 /**
  * Wrapper around RecentsAnimationControllerCompat to help with some synchronization
  */
 public class RecentsAnimationController {
 
-    private static final String TAG = "RecentsAnimationController";
-
     private final RecentsAnimationControllerCompat mController;
     private final Consumer<RecentsAnimationController> mOnFinishedListener;
     private final boolean mAllowMinimizeSplitScreen;
 
-    private InputConsumerController mInputConsumerController;
-    private Supplier<InputConsumer> mInputProxySupplier;
-    private InputConsumer mInputConsumer;
     private boolean mUseLauncherSysBarFlags = false;
     private boolean mSplitScreenMinimized = false;
-    private boolean mTouchInProgress;
-    private boolean mDisableInputProxyPending;
 
     public RecentsAnimationController(RecentsAnimationControllerCompat controller,
             boolean allowMinimizeSplitScreen,
@@ -136,12 +117,12 @@
 
     @UiThread
     public void finishAnimationToHome() {
-        finishAndDisableInputProxy(true /* toRecents */, null, false /* sendUserLeaveHint */);
+        finishController(true /* toRecents */, null, false /* sendUserLeaveHint */);
     }
 
     @UiThread
     public void finishAnimationToApp() {
-        finishAndDisableInputProxy(false /* toRecents */, null, false /* sendUserLeaveHint */);
+        finishController(false /* toRecents */, null, false /* sendUserLeaveHint */);
     }
 
     /** See {@link #finish(boolean, Runnable, boolean)} */
@@ -160,18 +141,6 @@
     @UiThread
     public void finish(boolean toRecents, Runnable onFinishComplete, boolean sendUserLeaveHint) {
         Preconditions.assertUIThread();
-        if (toRecents && mTouchInProgress) {
-            // Finish the controller as requested, but don't disable input proxy yet.
-            mDisableInputProxyPending = true;
-            finishController(toRecents, onFinishComplete, sendUserLeaveHint);
-        } else {
-            finishAndDisableInputProxy(toRecents, onFinishComplete, sendUserLeaveHint);
-        }
-    }
-
-    private void finishAndDisableInputProxy(boolean toRecents, Runnable onFinishComplete,
-            boolean sendUserLeaveHint) {
-        disableInputProxy();
         finishController(toRecents, onFinishComplete, sendUserLeaveHint);
     }
 
@@ -179,7 +148,6 @@
     public void finishController(boolean toRecents, Runnable callback, boolean sendUserLeaveHint) {
         mOnFinishedListener.accept(this);
         UI_HELPER_EXECUTOR.execute(() -> {
-            mController.setInputConsumerEnabled(false);
             mController.finish(toRecents, sendUserLeaveHint);
             if (callback != null) {
                 MAIN_EXECUTOR.execute(callback);
@@ -197,75 +165,8 @@
         });
     }
 
-    public void enableInputProxy(InputConsumerController inputConsumerController,
-            Supplier<InputConsumer> inputProxySupplier) {
-        mInputProxySupplier = inputProxySupplier;
-        mInputConsumerController = inputConsumerController;
-        mInputConsumerController.setInputListener(this::onInputConsumerEvent);
-    }
-
     /** @return wrapper controller. */
     public RecentsAnimationControllerCompat getController() {
         return mController;
     }
-
-    private void disableInputProxy() {
-        if (mInputConsumer != null && mTouchInProgress) {
-            long now = SystemClock.uptimeMillis();
-            MotionEvent dummyCancel = MotionEvent.obtain(now,  now, ACTION_CANCEL, 0, 0, 0);
-            mInputConsumer.onMotionEvent(dummyCancel);
-            dummyCancel.recycle();
-        }
-        if (mInputConsumerController != null) {
-            mInputConsumerController.setInputListener(null);
-        }
-        mInputProxySupplier = null;
-    }
-
-    private boolean onInputConsumerEvent(InputEvent ev) {
-        if (ev instanceof MotionEvent) {
-            onInputConsumerMotionEvent((MotionEvent) ev);
-        } else if (ev instanceof KeyEvent) {
-            if (mInputConsumer == null) {
-                mInputConsumer = mInputProxySupplier.get();
-            }
-            mInputConsumer.onKeyEvent((KeyEvent) ev);
-            return true;
-        }
-        return false;
-    }
-
-    private boolean onInputConsumerMotionEvent(MotionEvent ev) {
-        int action = ev.getAction();
-
-        // Just to be safe, verify that ACTION_DOWN comes before any other action,
-        // and ignore any ACTION_DOWN after the first one (though that should not happen).
-        if (!mTouchInProgress && action != ACTION_DOWN) {
-            Log.w(TAG, "Received non-down motion before down motion: " + action);
-            return false;
-        }
-        if (mTouchInProgress && action == ACTION_DOWN) {
-            Log.w(TAG, "Received down motion while touch was already in progress");
-            return false;
-        }
-
-        if (action == ACTION_DOWN) {
-            mTouchInProgress = true;
-            if (mInputConsumer == null) {
-                mInputConsumer = mInputProxySupplier.get();
-            }
-        } else if (action == ACTION_CANCEL || action == ACTION_UP) {
-            // Finish any pending actions
-            mTouchInProgress = false;
-            if (mDisableInputProxyPending) {
-                mDisableInputProxyPending = false;
-                disableInputProxy();
-            }
-        }
-        if (mInputConsumer != null) {
-            mInputConsumer.onMotionEvent(ev);
-        }
-
-        return true;
-    }
 }
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index 885fb66..458ffa3 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -28,6 +28,7 @@
 import android.annotation.TargetApi;
 import android.app.Fragment;
 import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetProviderInfo;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.Intent;
@@ -56,6 +57,7 @@
 import com.android.launcher3.InsettableFrameLayout;
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.LauncherModel;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.LauncherSettings.Favorites;
@@ -83,6 +85,7 @@
 import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.uioverrides.PredictedAppIconInflater;
 import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
+import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.launcher3.views.ActivityContext;
@@ -339,14 +342,33 @@
             addInScreenFromBind(folderIcon, info);
         }
 
+        private void inflateAndAddWidgets(LauncherAppWidgetInfo info,
+                Map<ComponentKey, AppWidgetProviderInfo> widgetProviderInfoMap) {
+            if (widgetProviderInfoMap == null) {
+                return;
+            }
+            AppWidgetProviderInfo providerInfo = widgetProviderInfoMap.get(
+                    new ComponentKey(info.providerName, info.user));
+            if (providerInfo == null) {
+                return;
+            }
+            inflateAndAddWidgets(info, LauncherAppWidgetProviderInfo.fromProviderInfo(
+                    getApplicationContext(), providerInfo));
+        }
+
         private void inflateAndAddWidgets(LauncherAppWidgetInfo info, WidgetsModel widgetsModel) {
             WidgetItem widgetItem = widgetsModel.getWidgetProviderInfoByProviderName(
                     info.providerName);
             if (widgetItem == null) {
                 return;
             }
+            inflateAndAddWidgets(info, widgetItem.widgetInfo);
+        }
+
+        private void inflateAndAddWidgets(LauncherAppWidgetInfo info,
+                LauncherAppWidgetProviderInfo providerInfo) {
             AppWidgetHostView view = new AppWidgetHostView(mContext);
-            view.setAppWidget(-1, widgetItem.widgetInfo);
+            view.setAppWidget(-1, providerInfo);
             view.updateAppWidget(null);
             view.setTag(info);
             addInScreenFromBind(view, info);
@@ -433,8 +455,13 @@
                     switch (itemInfo.itemType) {
                         case Favorites.ITEM_TYPE_APPWIDGET:
                         case Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
-                            inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
-                                    workspaceResult.mWidgetsModel);
+                            if (mMigrated) {
+                                inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
+                                        workspaceResult.mWidgetProvidersMap);
+                            } else {
+                                inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
+                                        workspaceResult.mWidgetsModel);
+                            }
                             break;
                         default:
                             break;
@@ -542,7 +569,7 @@
             }
 
             return new WorkspaceResult(mBgDataModel.workspaceItems, mBgDataModel.appWidgets,
-                    mBgDataModel.cachedPredictedItems, mBgDataModel.widgetsModel);
+                    mBgDataModel.cachedPredictedItems, mBgDataModel.widgetsModel, null);
         }
     }
 
@@ -569,9 +596,8 @@
         public WorkspaceResult call() throws Exception {
             List<ShortcutInfo> allShortcuts = new ArrayList<>();
             loadWorkspace(allShortcuts, LauncherSettings.Favorites.PREVIEW_CONTENT_URI);
-            mBgDataModel.widgetsModel.update(mApp, null);
             return new WorkspaceResult(mBgDataModel.workspaceItems, mBgDataModel.appWidgets,
-                    mBgDataModel.cachedPredictedItems, mBgDataModel.widgetsModel);
+                    mBgDataModel.cachedPredictedItems, null, mWidgetProvidersMap);
         }
     }
 
@@ -593,14 +619,17 @@
         private final ArrayList<LauncherAppWidgetInfo> mAppWidgets;
         private final ArrayList<AppInfo> mCachedPredictedItems;
         private final WidgetsModel mWidgetsModel;
+        private final Map<ComponentKey, AppWidgetProviderInfo> mWidgetProvidersMap;
 
         private WorkspaceResult(ArrayList<ItemInfo> workspaceItems,
                 ArrayList<LauncherAppWidgetInfo> appWidgets,
-                ArrayList<AppInfo> cachedPredictedItems, WidgetsModel widgetsModel) {
+                ArrayList<AppInfo> cachedPredictedItems, WidgetsModel widgetsModel,
+                Map<ComponentKey, AppWidgetProviderInfo> widgetProviderInfoMap) {
             mWorkspaceItems = workspaceItems;
             mAppWidgets = appWidgets;
             mCachedPredictedItems = cachedPredictedItems;
             mWidgetsModel = widgetsModel;
+            mWidgetProvidersMap = widgetProviderInfoMap;
         }
     }
 }
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
index ebdfa8c..79467d3 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
@@ -406,7 +406,7 @@
          * to speed up the search.
          */
         private boolean findPlacement(DbEntry entry) {
-            for (int y = mNextStartY; y > 0; y--) {
+            for (int y = mNextStartY; y >= (mScreenId == 0 ? 1 /* smartspace */ : 0); y--) {
                 for (int x = mNextStartX; x < mTrgX; x++) {
                     boolean fits = mOccupied.isRegionVacant(x, y, entry.spanX, entry.spanY);
                     boolean minFits = mOccupied.isRegionVacant(x, y, entry.minSpanX,
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 102ec31..4a64522 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -126,6 +126,8 @@
 
     private final UserManagerState mUserManagerState = new UserManagerState();
 
+    protected Map<ComponentKey, AppWidgetProviderInfo> mWidgetProvidersMap;
+
     private boolean mStopped;
 
     public LoaderTask(LauncherAppState app, AllAppsList bgAllAppsList, BgDataModel dataModel,
@@ -342,8 +344,6 @@
                     contentResolver.query(contentUri, null, null, null, null), contentUri, mApp,
                     mUserManagerState);
 
-            Map<ComponentKey, AppWidgetProviderInfo> widgetProvidersMap = null;
-
             try {
                 final int appWidgetIdIndex = c.getColumnIndexOrThrow(
                         LauncherSettings.Favorites.APPWIDGET_ID);
@@ -650,10 +650,11 @@
                             final boolean wasProviderReady = !c.hasRestoreFlag(
                                     LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY);
 
-                            if (widgetProvidersMap == null) {
-                                widgetProvidersMap = WidgetManagerHelper.getAllProvidersMap(context);
+                            if (mWidgetProvidersMap == null) {
+                                mWidgetProvidersMap = WidgetManagerHelper.getAllProvidersMap(
+                                        context);
                             }
-                            final AppWidgetProviderInfo provider = widgetProvidersMap.get(
+                            final AppWidgetProviderInfo provider = mWidgetProvidersMap.get(
                                     new ComponentKey(component, c.user));
 
                             final boolean isProviderReady = isValidProvider(provider);
diff --git a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
index 9021d9e..ca47728 100644
--- a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
@@ -52,7 +52,6 @@
     private static final float MIN_SATUNATION = 0.7f;
 
     private final Rect mRect = new Rect();
-    private View mDefaultView;
     private OnClickListener mClickListener;
     private final LauncherAppWidgetInfo mInfo;
     private final int mStartState;
@@ -111,12 +110,11 @@
 
     @Override
     protected View getDefaultView() {
-        if (mDefaultView == null) {
-            mDefaultView = mInflater.inflate(R.layout.appwidget_not_ready, this, false);
-            mDefaultView.setOnClickListener(this);
-            applyState();
-        }
-        return mDefaultView;
+        View defaultView = mInflater.inflate(R.layout.appwidget_not_ready, this, false);
+        defaultView.setOnClickListener(this);
+        applyState();
+        invalidate();
+        return defaultView;
     }
 
     @Override