Merge "Fix app opening transition for deep shortcuts." into ub-launcher3-master
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
index d5859a7..0e45791 100644
--- a/quickstep/libs/sysui_shared.jar
+++ b/quickstep/libs/sysui_shared.jar
Binary files differ
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 1df8cfd..fea83d6 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -16,7 +16,6 @@
 
 package com.android.launcher3;
 
-import static com.android.launcher3.LauncherAnimUtils.DRAWABLE_ALPHA;
 import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
 import static com.android.systemui.shared.recents.utilities.Utilities.getNextFrameNumber;
 import static com.android.systemui.shared.recents.utilities.Utilities.getSurface;
@@ -327,9 +326,6 @@
         launcherAnimator.play(recenterWorkspace);
         CellLayout currentWorkspacePage = (CellLayout) workspace.getPageAt(
                 workspace.getCurrentPage());
-        Animator hideWorkspaceScrim = ObjectAnimator.ofInt(
-                currentWorkspacePage.getScrimBackground(), DRAWABLE_ALPHA, 0);
-        launcherAnimator.play(hideWorkspaceScrim);
 
         launcherAnimator.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
         launcherAnimator.setDuration(RECENTS_LAUNCH_DURATION);
diff --git a/quickstep/src/com/android/quickstep/TaskSystemShortcut.java b/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
index 75d8619..e172291 100644
--- a/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
+++ b/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
@@ -19,13 +19,18 @@
 import android.app.ActivityOptions;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.Rect;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Log;
 import android.view.View;
+import android.view.ViewTreeObserver.OnPreDrawListener;
 
+import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
@@ -34,9 +39,15 @@
 import com.android.launcher3.util.InstantAppResolver;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecCompat;
+import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture;
+import com.android.systemui.shared.recents.view.RecentsTransition;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.ActivityOptionsCompat;
+import com.android.systemui.shared.system.WindowManagerWrapper;
 
+import java.util.Collections;
+import java.util.List;
 import java.util.function.Consumer;
 
 /**
@@ -86,9 +97,10 @@
         }
     }
 
-    public static class SplitScreen extends TaskSystemShortcut {
+    public static class SplitScreen extends TaskSystemShortcut implements OnPreDrawListener {
 
         private Handler mHandler;
+        private TaskView mTaskView;
 
         public SplitScreen() {
             super(R.drawable.ic_split_screen, R.string.recent_task_option_split_screen);
@@ -104,22 +116,55 @@
             if (!task.isDockable) {
                 return null;
             }
+            mTaskView = taskView;
             return (v -> {
-                final ActivityOptions options = ActivityOptionsCompat.makeSplitScreenOptions(true);
-                final Consumer<Boolean> resultCallback = success -> {
-                    if (success) {
-                        launcher.<RecentsView>getOverviewPanel().removeView(taskView);
-                    }
-                };
-                ActivityManagerWrapper.getInstance().startActivityFromRecentsAsync(
-                        task.key, options, resultCallback, mHandler);
+                AbstractFloatingView.closeOpenViews(launcher, true,
+                        AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE);
 
-                // TODO improve transition; see:
-                // DockedFirstAnimationFrameEvent
-                // RecentsTransitionHelper#composeDockAnimationSpec
-                // WindowManagerWrapper#overridePendingAppTransitionMultiThumbFuture
+                if (ActivityManagerWrapper.getInstance().startActivityFromRecents(task.key.id,
+                        ActivityOptionsCompat.makeSplitScreenOptions(true))) {
+                    ISystemUiProxy sysUiProxy = RecentsModel.getInstance(launcher).getSystemUiProxy();
+                    try {
+                        sysUiProxy.onSplitScreenInvoked();
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "Failed to notify SysUI of split screen: ", e);
+                        return;
+                    }
+
+                    final Runnable animStartedListener = () -> {
+                        mTaskView.getViewTreeObserver().addOnPreDrawListener(SplitScreen.this);
+                        launcher.<RecentsView>getOverviewPanel().removeView(taskView);
+                    };
+
+                    final int[] position = new int[2];
+                    taskView.getLocationOnScreen(position);
+                    final int width = (int) (taskView.getWidth() * taskView.getScaleX());
+                    final int height = (int) (taskView.getHeight() * taskView.getScaleY());
+                    final Rect taskBounds = new Rect(position[0], position[1],
+                            position[0] + width, position[1] + height);
+
+                    Bitmap thumbnail = RecentsTransition.drawViewIntoHardwareBitmap(
+                            taskBounds.width(), taskBounds.height(), taskView, 1f, Color.BLACK);
+                    AppTransitionAnimationSpecsFuture future =
+                            new AppTransitionAnimationSpecsFuture(mHandler) {
+                        @Override
+                        public List<AppTransitionAnimationSpecCompat> composeSpecs() {
+                            return Collections.singletonList(new AppTransitionAnimationSpecCompat(
+                                    task.key.id, thumbnail, taskBounds));
+                        }
+                    };
+                    WindowManagerWrapper.getInstance().overridePendingAppTransitionMultiThumbFuture(
+                            future, animStartedListener, mHandler, true /* scaleUp */);
+                }
             });
         }
+
+        @Override
+        public boolean onPreDraw() {
+            mTaskView.getViewTreeObserver().removeOnPreDrawListener(this);
+            WindowManagerWrapper.getInstance().endProlongedAnimations();
+            return true;
+        }
     }
 
     public static class Pin extends TaskSystemShortcut {
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 55bfef6..7209d9d 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -408,6 +408,11 @@
         if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0) {
             mUserEventDispatcher = null;
             initDeviceProfile(mDeviceProfile.inv);
+            FileLog.d(TAG, "Config changed, my orientation=" +
+                    getResources().getConfiguration().orientation +
+                    ", new orientation=" + newConfig.orientation +
+                    ", old orientation=" + mOldConfig.orientation +
+                    ", isTransposed=" + mDeviceProfile.isVerticalBarLayout());
             dispatchDeviceProfileChanged();
 
             getRootView().dispatchInsets();
@@ -2752,18 +2757,20 @@
                     writer.println(prefix + "    " + tag.toString());
                 }
             }
-
-            try {
-                FileLog.flushAll(writer);
-            } catch (Exception e) {
-                // Ignore
-            }
         }
 
         writer.println(prefix + "Misc:");
         writer.print(prefix + "\tmWorkspaceLoading=" + mWorkspaceLoading);
         writer.print(" mPendingRequestArgs=" + mPendingRequestArgs);
         writer.println(" mPendingActivityResult=" + mPendingActivityResult);
+        writer.println(" deviceProfile isTransposed=" + getDeviceProfile().isVerticalBarLayout());
+        writer.println(" orientation=" + getResources().getConfiguration().orientation);
+
+        try {
+            FileLog.flushAll(writer);
+        } catch (Exception e) {
+            // Ignore
+        }
 
         mModel.dumpState(prefix, fd, writer, args);
 
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 138ea0f..053dc35 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -56,6 +56,7 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.model.DbDowngradeHelper;
+import com.android.launcher3.model.ModelWriter;
 import com.android.launcher3.provider.LauncherDbUtils;
 import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
 import com.android.launcher3.provider.RestoreDbTask;
@@ -320,6 +321,11 @@
 
     @Override
     public int delete(Uri uri, String selection, String[] selectionArgs) {
+        if (ModelWriter.DEBUG_DELETE) {
+            String args = selectionArgs == null ? null : TextUtils.join(",", selectionArgs);
+            FileLog.d(TAG, "Delete uri=" + uri + ", selection=" + selection
+                    + ", selectionArgs=" + args, new Exception());
+        }
         createDbIfNotExists();
         SqlArguments args = new SqlArguments(uri, selection, selectionArgs);
 
diff --git a/src/com/android/launcher3/model/ModelWriter.java b/src/com/android/launcher3/model/ModelWriter.java
index 032ed78..40e0f49 100644
--- a/src/com/android/launcher3/model/ModelWriter.java
+++ b/src/com/android/launcher3/model/ModelWriter.java
@@ -32,6 +32,7 @@
 import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.LauncherSettings.Settings;
 import com.android.launcher3.ShortcutInfo;
+import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.util.ContentWriter;
 import com.android.launcher3.util.ItemInfoMatcher;
 import com.android.launcher3.util.LooperExecutor;
@@ -46,6 +47,7 @@
 public class ModelWriter {
 
     private static final String TAG = "ModelWriter";
+    public static final boolean DEBUG_DELETE = true;
 
     private final Context mContext;
     private final BgDataModel mBgDataModel;
@@ -243,14 +245,21 @@
      * Removes the specified items from the database
      */
     public void deleteItemsFromDatabase(final Iterable<? extends ItemInfo> items) {
-        mWorkerExecutor.execute(new Runnable() {
-            public void run() {
-                for (ItemInfo item : items) {
-                    final Uri uri = Favorites.getContentUri(item.id);
-                    mContext.getContentResolver().delete(uri, null, null);
+        if (DEBUG_DELETE) {
+            // Log it on the colling thread to get the proper stack trace
+            FileLog.d(TAG, "Starting item deletion", new Exception());
+            for (ItemInfo item : items) {
+                FileLog.d(TAG, "deleting item " + item);
+            }
+            FileLog.d(TAG, "Finished deleting items");
+        }
 
-                    mBgDataModel.removeItem(mContext, item);
-                }
+        mWorkerExecutor.execute(() -> {
+            for (ItemInfo item : items) {
+                final Uri uri = Favorites.getContentUri(item.id);
+                mContext.getContentResolver().delete(uri, null, null);
+
+                mBgDataModel.removeItem(mContext, item);
             }
         });
     }
@@ -259,17 +268,20 @@
      * Remove the specified folder and all its contents from the database.
      */
     public void deleteFolderAndContentsFromDatabase(final FolderInfo info) {
-        mWorkerExecutor.execute(new Runnable() {
-            public void run() {
-                ContentResolver cr = mContext.getContentResolver();
-                cr.delete(LauncherSettings.Favorites.CONTENT_URI,
-                        LauncherSettings.Favorites.CONTAINER + "=" + info.id, null);
-                mBgDataModel.removeItem(mContext, info.contents);
-                info.contents.clear();
+        if (DEBUG_DELETE) {
+            // Log it on the colling thread to get the proper stack trace
+            FileLog.d(TAG, "Deleting folder " + info, new Exception());
+        }
 
-                cr.delete(LauncherSettings.Favorites.getContentUri(info.id), null, null);
-                mBgDataModel.removeItem(mContext, info);
-            }
+        mWorkerExecutor.execute(() -> {
+            ContentResolver cr = mContext.getContentResolver();
+            cr.delete(LauncherSettings.Favorites.CONTENT_URI,
+                    LauncherSettings.Favorites.CONTAINER + "=" + info.id, null);
+            mBgDataModel.removeItem(mContext, info.contents);
+            info.contents.clear();
+
+            cr.delete(LauncherSettings.Favorites.getContentUri(info.id), null, null);
+            mBgDataModel.removeItem(mContext, info);
         });
     }