Merge "Migrate Aardwolf to Soong" am: c6cb960ecc am: 526386b255

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

Change-Id: I1cffed080d5c3c6c08dcecc9d8aeb4eeebcb836c
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index 370fb8e..8c9ac12 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -26,6 +26,7 @@
 import android.os.IBinder;
 import android.os.SystemProperties;
 import android.util.FloatProperty;
+import android.view.AttachedSurfaceControl;
 import android.view.CrossWindowBlurListeners;
 import android.view.SurfaceControl;
 import android.view.View;
@@ -108,6 +109,13 @@
         }
     };
 
+    private final Runnable mOpaquenessListener = new Runnable() {
+        @Override
+        public void run() {
+            dispatchTransactionSurface(mDepth);
+        }
+    };
+
     private final Launcher mLauncher;
     /**
      * Blur radius when completely zoomed out, in pixels.
@@ -150,23 +158,28 @@
                     if (windowToken != null) {
                         mWallpaperManager.setWallpaperZoomOut(windowToken, mDepth);
                     }
-                    CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
-                            mCrossWindowBlurListener);
+                    onAttached();
                 }
 
                 @Override
                 public void onViewDetachedFromWindow(View view) {
                     CrossWindowBlurListeners.getInstance().removeListener(mCrossWindowBlurListener);
+                    mLauncher.getScrimView().removeOpaquenessListener(mOpaquenessListener);
                 }
             };
             mLauncher.getRootView().addOnAttachStateChangeListener(mOnAttachListener);
             if (mLauncher.getRootView().isAttachedToWindow()) {
-                CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
-                        mCrossWindowBlurListener);
+                onAttached();
             }
         }
     }
 
+    private void onAttached() {
+        CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
+                mCrossWindowBlurListener);
+        mLauncher.getScrimView().addOpaquenessListener(mOpaquenessListener);
+    }
+
     /**
      * Sets if the underlying activity is started or not
      */
@@ -270,10 +283,15 @@
 
             int blur = opaque || isOverview || !mCrossWindowBlursEnabled
                     || mBlurDisabledForAppLaunch ? 0 : (int) (depth * mMaxBlurRadius);
-            new SurfaceControl.Transaction()
+            SurfaceControl.Transaction transaction = new SurfaceControl.Transaction()
                     .setBackgroundBlurRadius(mSurface, blur)
-                    .setOpaque(mSurface, opaque)
-                    .apply();
+                    .setOpaque(mSurface, opaque);
+
+            AttachedSurfaceControl rootSurfaceControl =
+                    mLauncher.getRootView().getRootSurfaceControl();
+            if (rootSurfaceControl != null) {
+                rootSurfaceControl.applyTransactionOnDraw(transaction);
+            }
         }
         return true;
     }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
index c2c721a..1cf50f7 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
@@ -71,7 +71,7 @@
             }
         }
         activityOptions.options.setPendingIntentLaunchFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        activityOptions.options.setSplashscreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON);
+        activityOptions.options.setSplashscreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_EMPTY);
         Object itemInfo = hostView.getTag();
         if (itemInfo instanceof ItemInfo) {
             mLauncher.addLaunchCookie((ItemInfo) itemInfo, activityOptions.options);
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index ce79125..3887060 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -1146,20 +1146,24 @@
         }
         updateTaskSize();
 
+        int targetPage = -1;
         if (mNextPage == INVALID_PAGE) {
             // Set the current page to the running task, but not if settling on new task.
             TaskView runningTaskView = getRunningTaskView();
             if (runningTaskView != null) {
-                setCurrentPage(indexOfChild(runningTaskView));
+                targetPage = indexOfChild(runningTaskView);
             } else if (getTaskViewCount() > 0) {
-                setCurrentPage(indexOfChild(getTaskViewAt(0)));
+                targetPage = indexOfChild(getTaskViewAt(0));
             }
         } else if (currentTaskId != -1) {
             currentTaskView = getTaskView(currentTaskId);
             if (currentTaskView != null) {
-                setCurrentPage(indexOfChild(currentTaskView));
+                targetPage = indexOfChild(currentTaskView);
             }
         }
+        if (targetPage != -1 && mCurrentPage != targetPage) {
+            setCurrentPage(targetPage);
+        }
 
         if (mIgnoreResetTaskId != -1 && getTaskView(mIgnoreResetTaskId) != ignoreResetTaskView) {
             // If the taskView mapping is changing, do not preserve the visuals. Since we are
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index eef3980..545f4c3 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -72,6 +72,7 @@
 import java.util.List;
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.Executor;
+import java.util.function.Consumer;
 import java.util.function.Supplier;
 
 /**
@@ -376,7 +377,13 @@
                     loaderResults.bindWidgets();
                     return true;
                 } else {
-                    startLoaderForResults(loaderResults);
+                    stopLoader();
+                    mLoaderTask = new LoaderTask(
+                            mApp, mBgAllAppsList, mBgDataModel, mModelDelegate, loaderResults);
+
+                    // Always post the loader task, instead of running directly
+                    // (even on same thread) so that we exit any nested synchronized blocks
+                    MODEL_EXECUTOR.post(mLoaderTask);
                 }
             }
         }
@@ -399,25 +406,17 @@
         }
     }
 
-    public void startLoaderForResults(LoaderResults results) {
+    /**
+     * Loads the model if not loaded
+     * @param callback called with the data model upon successful load or null on model thread.
+     */
+    public void loadAsync(Consumer<BgDataModel> callback) {
         synchronized (mLock) {
-            stopLoader();
-            mLoaderTask = new LoaderTask(
-                    mApp, mBgAllAppsList, mBgDataModel, mModelDelegate, results);
-
-            // Always post the loader task, instead of running directly (even on same thread) so
-            // that we exit any nested synchronized blocks
-            MODEL_EXECUTOR.post(mLoaderTask);
-        }
-    }
-
-    public void startLoaderForResultsIfNotLoaded(LoaderResults results) {
-        synchronized (mLock) {
-            if (!isModelLoaded()) {
-                Log.d(TAG, "Workspace not loaded, loading now");
-                startLoaderForResults(results);
+            if (!mModelLoaded && !mIsLoaderTaskRunning) {
+                startLoader();
             }
         }
+        MODEL_EXECUTOR.post(() -> callback.accept(isModelLoaded() ? mBgDataModel : null));
     }
 
     @Override
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index d2c71b2..f420ec2 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -499,8 +499,10 @@
 
     private void replaceRVContainer(boolean showTabs) {
         for (int i = 0; i < mAH.length; i++) {
-            if (mAH[i].recyclerView != null) {
-                mAH[i].recyclerView.setLayoutManager(null);
+            AllAppsRecyclerView rv = mAH[i].recyclerView;
+            if (rv != null) {
+                rv.setLayoutManager(null);
+                rv.setAdapter(null);
             }
         }
         View oldView = getRecyclerViewContainer();
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 2c84a3d..bddbbd0 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -63,6 +63,13 @@
     private final SparseIntArray mCachedScrollPositions = new SparseIntArray();
     private final AllAppsFastScrollHelper mFastScrollHelper;
 
+
+    private final AdapterDataObserver mObserver = new RecyclerView.AdapterDataObserver() {
+        public void onChanged() {
+            mCachedScrollPositions.clear();
+        }
+    };
+
     // The empty-search result background
     private AllAppsBackgroundDrawable mEmptySearchBackground;
     private int mEmptySearchBackgroundTopOffset;
@@ -247,12 +254,13 @@
 
     @Override
     public void setAdapter(Adapter adapter) {
+        if (getAdapter() != null) {
+            getAdapter().unregisterAdapterDataObserver(mObserver);
+        }
         super.setAdapter(adapter);
-        adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
-            public void onChanged() {
-                mCachedScrollPositions.clear();
-            }
-        });
+        if (adapter != null) {
+            adapter.registerAdapterDataObserver(mObserver);
+        }
     }
 
     @Override
diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
index df49359..3b140a0 100644
--- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
+++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
@@ -49,7 +49,6 @@
 import com.android.launcher3.model.GridSizeMigrationTaskV2;
 import com.android.launcher3.model.LoaderTask;
 import com.android.launcher3.model.ModelDelegate;
-import com.android.launcher3.model.ModelPreload;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.RunnableList;
 import com.android.launcher3.util.Themes;
@@ -174,18 +173,13 @@
                 }
             }.run();
         } else {
-            new ModelPreload() {
-
-                @Override
-                public void onComplete(boolean isSuccess) {
-                    if (isSuccess) {
-                        MAIN_EXECUTOR.execute(() ->
-                                renderView(inflationContext, getBgDataModel(), null));
-                    } else {
-                        Log.e(TAG, "Model loading failed");
-                    }
+            LauncherAppState.getInstance(inflationContext).getModel().loadAsync(dataModel -> {
+                if (dataModel != null) {
+                    MAIN_EXECUTOR.execute(() -> renderView(inflationContext, dataModel, null));
+                } else {
+                    Log.e(TAG, "Model loading failed");
                 }
-            }.start(inflationContext);
+            });
         }
     }
 
diff --git a/src/com/android/launcher3/model/ModelPreload.java b/src/com/android/launcher3/model/ModelPreload.java
deleted file mode 100644
index 756b7da..0000000
--- a/src/com/android/launcher3/model/ModelPreload.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2018 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.launcher3.model;
-
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-
-import android.content.Context;
-import android.util.Log;
-
-import androidx.annotation.WorkerThread;
-
-import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherModel;
-import com.android.launcher3.LauncherModel.ModelUpdateTask;
-import com.android.launcher3.model.BgDataModel.Callbacks;
-
-import java.util.concurrent.Executor;
-
-/**
- * Utility class to preload LauncherModel
- */
-public class ModelPreload implements ModelUpdateTask {
-
-    private static final String TAG = "ModelPreload";
-
-    private LauncherAppState mApp;
-    private LauncherModel mModel;
-    private BgDataModel mBgDataModel;
-    private AllAppsList mAllAppsList;
-
-    @Override
-    public final void init(LauncherAppState app, LauncherModel model, BgDataModel dataModel,
-            AllAppsList allAppsList, Executor uiExecutor) {
-        mApp = app;
-        mModel = model;
-        mBgDataModel = dataModel;
-        mAllAppsList = allAppsList;
-    }
-
-    @Override
-    public final void run() {
-        mModel.startLoaderForResultsIfNotLoaded(
-                new LoaderResults(mApp, mBgDataModel, mAllAppsList, new Callbacks[0]));
-        MODEL_EXECUTOR.post(() -> {
-            Log.d(TAG, "Preload completed : " + mModel.isModelLoaded());
-            onComplete(mModel.isModelLoaded());
-        });
-    }
-
-    public BgDataModel getBgDataModel() {
-        return mBgDataModel;
-    }
-
-    /**
-     * Called when the task is complete
-     */
-    @WorkerThread
-    public void onComplete(boolean isSuccess) { }
-
-    public void start(Context context) {
-        LauncherAppState.getInstance(context).getModel().enqueueModelUpdateTask(this);
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java
index 1eb79ad..4c0bfde 100644
--- a/src/com/android/launcher3/views/ScrimView.java
+++ b/src/com/android/launcher3/views/ScrimView.java
@@ -25,23 +25,27 @@
 import android.util.AttributeSet;
 import android.view.View;
 
+import androidx.annotation.NonNull;
 import androidx.core.graphics.ColorUtils;
 
 import com.android.launcher3.BaseActivity;
 import com.android.launcher3.Insettable;
 import com.android.launcher3.util.SystemUiController;
 
+import java.util.ArrayList;
+
 /**
  * Simple scrim which draws a flat color
  */
 public class ScrimView extends View implements Insettable {
     private static final float STATUS_BAR_COLOR_FORCE_UPDATE_THRESHOLD = 0.9f;
 
+    private final ArrayList<Runnable> mOpaquenessListeners = new ArrayList<>(1);
     private SystemUiController mSystemUiController;
-
     private ScrimDrawingController mDrawingController;
     private int mBackgroundColor;
     private boolean mIsVisible = true;
+    private boolean mLastDispatchedOpaqueness;
 
     public ScrimView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -60,6 +64,7 @@
     @Override
     protected boolean onSetAlpha(int alpha) {
         updateSysUiColors();
+        dispatchVisibilityListenersIfNeeded();
         return super.onSetAlpha(alpha);
     }
 
@@ -67,6 +72,7 @@
     public void setBackgroundColor(int color) {
         mBackgroundColor = color;
         updateSysUiColors();
+        dispatchVisibilityListenersIfNeeded();
         super.setBackgroundColor(color);
     }
 
@@ -74,6 +80,7 @@
     public void onVisibilityAggregated(boolean isVisible) {
         super.onVisibilityAggregated(isVisible);
         mIsVisible = isVisible;
+        dispatchVisibilityListenersIfNeeded();
     }
 
     public boolean isFullyOpaque() {
@@ -108,6 +115,17 @@
         }
     }
 
+    private void dispatchVisibilityListenersIfNeeded() {
+        boolean fullyOpaque = isFullyOpaque();
+        if (mLastDispatchedOpaqueness == fullyOpaque) {
+            return;
+        }
+        mLastDispatchedOpaqueness = fullyOpaque;
+        for (int i = 0; i < mOpaquenessListeners.size(); i++) {
+            mOpaquenessListeners.get(i).run();
+        }
+    }
+
     private SystemUiController getSystemUiController() {
         if (mSystemUiController == null) {
             mSystemUiController = BaseActivity.fromContext(getContext()).getSystemUiController();
@@ -136,6 +154,22 @@
     }
 
     /**
+     * Registers a listener to be notified of whether the scrim is occluding other UI elements.
+     * @see #isFullyOpaque()
+     */
+    public void addOpaquenessListener(@NonNull Runnable listener) {
+        mOpaquenessListeners.add(listener);
+    }
+
+    /**
+     * Removes previously registered listener.
+     * @see #addOpaquenessListener(Runnable)
+     */
+    public void removeOpaquenessListener(@NonNull Runnable listener) {
+        mOpaquenessListeners.remove(listener);
+    }
+
+    /**
      * A Utility interface allowing for other surfaces to draw on ScrimView
      */
     public interface ScrimDrawingController {