Initial changes for handling configuration changes dynamically

Bug: 71709920
Change-Id: I88cf2229dea28d01c13a5a76d2290e91b07d095e
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 31c195d..aa23ee5 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -26,12 +26,14 @@
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
+import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Matrix;
 import android.graphics.Rect;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.util.Log;
@@ -57,6 +59,8 @@
 /**
  * Manages the opening and closing app transitions from Launcher.
  */
+@TargetApi(Build.VERSION_CODES.O)
+@SuppressWarnings("unused")
 public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManager {
 
     private static final String TAG = "LauncherTransition";
@@ -94,6 +98,8 @@
         Resources res = mLauncher.getResources();
         mContentTransY = res.getDimensionPixelSize(R.dimen.content_trans_y);
         mWorkspaceTransY = res.getDimensionPixelSize(R.dimen.workspace_trans_y);
+
+        registerRemoteAnimations();
     }
 
     private void setCurrentAnimator(Animator animator) {
@@ -392,8 +398,7 @@
     /**
      * Registers remote animations used when closing apps to home screen.
      */
-    @Override
-    public void registerRemoteAnimations() {
+    private void registerRemoteAnimations() {
         if (hasControlRemoteAppTransitionPermission()) {
             try {
                 RemoteAnimationDefinitionCompat definition = new RemoteAnimationDefinitionCompat();
diff --git a/src/com/android/launcher3/DropTargetBar.java b/src/com/android/launcher3/DropTargetBar.java
index cc6a58f..a3fe89a 100644
--- a/src/com/android/launcher3/DropTargetBar.java
+++ b/src/com/android/launcher3/DropTargetBar.java
@@ -111,6 +111,7 @@
 
             lp.topMargin += grid.edgeMarginPx;
             lp.height = grid.dropTargetBarSizePx;
+            lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
         }
         setLayoutParams(lp);
         for (ButtonDropTarget button : mDropTargets) {
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 9d2bb07..03043f2 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -28,12 +28,10 @@
 import android.view.View;
 import android.view.ViewDebug;
 import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
 import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.logging.UserEventDispatcher;
 import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
diff --git a/src/com/android/launcher3/InsettableFrameLayout.java b/src/com/android/launcher3/InsettableFrameLayout.java
index baf3328..1db1fc0 100644
--- a/src/com/android/launcher3/InsettableFrameLayout.java
+++ b/src/com/android/launcher3/InsettableFrameLayout.java
@@ -38,10 +38,6 @@
 
     @Override
     public void setInsets(Rect insets) {
-        // If the insets haven't changed, this is a no-op. Avoid unnecessary layout caused by
-        // modifying child layout params.
-        if (insets.equals(mInsets)) return;
-
         final int n = getChildCount();
         for (int i = 0; i < n; i++) {
             final View child = getChildAt(i);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 85443ed..8ef1da9 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher3;
 
+import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
+import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 
@@ -53,7 +55,9 @@
 import android.content.IntentSender;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
+import android.content.res.Configuration;
 import android.database.sqlite.SQLiteDatabase;
 import android.graphics.Point;
 import android.graphics.PointF;
@@ -215,6 +219,7 @@
     @Thunk static final int NEW_APPS_ANIMATION_DELAY = 500;
 
     private LauncherAppTransitionManager mAppTransitionManager;
+    private Configuration mOldConfig;
 
     @Thunk Workspace mWorkspace;
     private View mLauncherView;
@@ -237,10 +242,6 @@
     // UI and state for the overview panel
     private ViewGroup mOverviewPanel;
 
-    // We need to store the orientation Launcher was created with, due to a bug (b/64916689)
-    // that results in widgets being inflated in the wrong orientation.
-    private int mOrientation;
-
     @Thunk boolean mWorkspaceLoading = true;
 
     private OnResumeCallback mOnResumeCallback;
@@ -310,17 +311,9 @@
         TraceHelper.partitionSection("Launcher-onCreate", "super call");
 
         LauncherAppState app = LauncherAppState.getInstance(this);
+        mOldConfig = new Configuration(getResources().getConfiguration());
+        initDeviceProfile(app.getInvariantDeviceProfile());
 
-        // Load configuration-specific DeviceProfile
-        mDeviceProfile = app.getInvariantDeviceProfile().getDeviceProfile(this);
-        if (isInMultiWindowModeCompat()) {
-            Display display = getWindowManager().getDefaultDisplay();
-            Point mwSize = new Point();
-            display.getSize(mwSize);
-            mDeviceProfile = mDeviceProfile.getMultiWindowProfile(this, mwSize);
-        }
-
-        mOrientation = getResources().getConfiguration().orientation;
         mSharedPrefs = Utilities.getPrefs(this);
         mIsSafeModeEnabled = getPackageManager().isSafeMode();
         mModel = app.setLauncher(this);
@@ -393,7 +386,7 @@
                 ? SCREEN_ORIENTATION_UNSPECIFIED : SCREEN_ORIENTATION_NOSENSOR);
 
         setContentView(mLauncherView);
-        ((LauncherRootView) mLauncherView).dispatchInsets();
+        getRootView().dispatchInsets();
 
         // Listen for broadcasts
         IntentFilter filter = new IntentFilter();
@@ -405,10 +398,7 @@
         getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW,
                 Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText));
 
-        mAppTransitionManager = Utilities.getOverrideObject(LauncherAppTransitionManager.class,
-                        this, R.string.app_transition_manager_class);
-
-        mAppTransitionManager.registerRemoteAnimations();
+        mAppTransitionManager = LauncherAppTransitionManager.newInstance(this);
 
         if (mLauncherCallbacks != null) {
             mLauncherCallbacks.onCreate(savedInstanceState);
@@ -418,6 +408,45 @@
     }
 
     @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        int diff = newConfig.diff(mOldConfig);
+        if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0) {
+            mUserEventDispatcher = null;
+            initDeviceProfile(mDeviceProfile.inv);
+
+            // Re create transition manager as it may rely on the device profile.
+            // TODO: Remove any dynamic states from this class.
+            mAppTransitionManager = LauncherAppTransitionManager.newInstance(this);
+
+            // TODO: Link these to the callbacks
+            mAllAppsController.onDeviceProfileChanged(mDeviceProfile);
+            mDragLayer.setup(this, mDragController);
+
+            // TODO: Clear all-apps recycler view pools
+
+            getRootView().dispatchInsets();
+            getStateManager().reapplyState();
+
+            // TODO: We can probably avoid rebind when only screen size changed.
+            mModel.startLoader(mWorkspace.getNextPage());
+        }
+
+        mOldConfig.setTo(newConfig);
+        super.onConfigurationChanged(newConfig);
+    }
+
+    private void initDeviceProfile(InvariantDeviceProfile idp) {
+        // Load configuration-specific DeviceProfile
+        mDeviceProfile = idp.getDeviceProfile(this);
+        if (isInMultiWindowModeCompat()) {
+            Display display = getWindowManager().getDefaultDisplay();
+            Point mwSize = new Point();
+            display.getSize(mwSize);
+            mDeviceProfile = mDeviceProfile.getMultiWindowProfile(this, mwSize);
+        }
+    }
+
+    @Override
     public void onThemeChanged() {
         recreate();
     }
@@ -1216,7 +1245,7 @@
         return mSharedPrefs;
     }
 
-    public int getOrientation() { return mOrientation; }
+    public int getOrientation() { return mOldConfig.orientation; }
 
     @Override
     protected void onNewIntent(Intent intent) {
diff --git a/src/com/android/launcher3/LauncherAppTransitionManager.java b/src/com/android/launcher3/LauncherAppTransitionManager.java
index 9d68dc9..be2dc54 100644
--- a/src/com/android/launcher3/LauncherAppTransitionManager.java
+++ b/src/com/android/launcher3/LauncherAppTransitionManager.java
@@ -18,6 +18,7 @@
 
 
 import android.app.ActivityOptions;
+import android.content.Context;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
@@ -28,6 +29,11 @@
  */
 public class LauncherAppTransitionManager {
 
+    public static LauncherAppTransitionManager newInstance(Context context) {
+        return Utilities.getOverrideObject(LauncherAppTransitionManager.class,
+                context, R.string.app_transition_manager_class);
+    }
+
     public Bundle getDefaultActivityLaunchOptions(Launcher launcher, View v) {
         if (Utilities.ATLEAST_MARSHMALLOW) {
             int left = 0, top = 0;
@@ -58,7 +64,4 @@
     public Bundle getActivityLaunchOptions(Launcher launcher, View v) {
         return getDefaultActivityLaunchOptions(launcher, v);
     }
-
-    public void registerRemoteAnimations() {
-    }
 }
diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java
index 18d5234..fc4de2d 100644
--- a/src/com/android/launcher3/LauncherRootView.java
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -89,13 +89,17 @@
 
     @Override
     public void setInsets(Rect insets) {
-        super.setInsets(insets);
+        // If the insets haven't changed, this is a no-op. Avoid unnecessary layout caused by
+        // modifying child layout params.
+        if (!insets.equals(mInsets)) {
+            super.setInsets(insets);
+        }
         setBackground(insets.top == 0 ? null
                 : Themes.getAttrDrawable(getContext(), R.attr.workspaceStatusBarScrim));
     }
 
     public void dispatchInsets() {
-        fitSystemWindows(mInsets);
+        super.setInsets(mInsets);
     }
 
     @Override
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index dc3de18..19df17e 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -307,19 +307,24 @@
             mAH[i].padding.left = mAH[i].padding.right = leftRightPadding;
             mAH[i].applyPadding();
         }
+
+        ViewGroup.MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
         if (grid.isVerticalBarLayout()) {
-            ViewGroup.MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
             mlp.leftMargin = insets.left;
             mlp.topMargin = insets.top;
             mlp.rightMargin = insets.right;
-            setLayoutParams(mlp);
             setPadding(grid.workspacePadding.left, 0, grid.workspacePadding.right, 0);
         } else {
-            View navBarBg = findViewById(R.id.nav_bar_bg);
-            ViewGroup.LayoutParams navBarBgLp = navBarBg.getLayoutParams();
-            navBarBgLp.height = insets.bottom;
-            navBarBg.setLayoutParams(navBarBgLp);
+            mlp.leftMargin = mlp.rightMargin = mlp.topMargin = 0;
+            setPadding(0, 0, 0, 0);
         }
+        setLayoutParams(mlp);
+
+        View navBarBg = findViewById(R.id.nav_bar_bg);
+        ViewGroup.LayoutParams navBarBgLp = navBarBg.getLayoutParams();
+        navBarBgLp.height = insets.bottom;
+        navBarBg.setLayoutParams(navBarBgLp);
+
         InsettableFrameLayout.dispatchInsets(this, insets);
     }
 
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index dadc6cd..4292f65 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -2,6 +2,7 @@
 
 import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.util.SystemUiController.UI_STATE_ALL_APPS;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -10,6 +11,7 @@
 import android.view.View;
 import android.view.animation.Interpolator;
 
+import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Hotseat;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
@@ -59,7 +61,7 @@
 
     private final Launcher mLauncher;
     private final boolean mIsDarkTheme;
-    private final boolean mIsVerticalLayout;
+    private boolean mIsVerticalLayout;
 
     // Animation in this class is controlled by a single variable {@link mProgress}.
     // Visually, it represents top y coordinate of the all apps container if multiplied with
@@ -80,7 +82,7 @@
         mProgress = 1f;
 
         mIsDarkTheme = Themes.getAttrBoolean(mLauncher, R.attr.isMainColorDark);
-        mIsVerticalLayout = mLauncher.getDeviceProfile().isVerticalBarLayout();
+        onDeviceProfileChanged(mLauncher.getDeviceProfile());
     }
 
     public float getShiftRange() {
@@ -93,6 +95,10 @@
         mAppsView.setVisibility(View.VISIBLE);
     }
 
+    public void onDeviceProfileChanged(DeviceProfile profile) {
+        mIsVerticalLayout = profile.isVerticalBarLayout();
+    }
+
     /**
      * Note this method should not be called outside this class. This is public because it is used
      * in xml-based animations which also handle updating the appropriate UI.
@@ -125,13 +131,15 @@
             // status bar.
             boolean forceChange = shiftCurrent <= mShiftRange / 4;
             if (forceChange) {
-                mLauncher.getSystemUiController().updateUiState(
-                        SystemUiController.UI_STATE_ALL_APPS, !mIsDarkTheme);
+                mLauncher.getSystemUiController().updateUiState(UI_STATE_ALL_APPS, !mIsDarkTheme);
             } else {
-                mLauncher.getSystemUiController().updateUiState(
-                        SystemUiController.UI_STATE_ALL_APPS, 0);
+                mLauncher.getSystemUiController().updateUiState(UI_STATE_ALL_APPS, 0);
             }
-
+        } else {
+            mAppsView.setAlpha(1);
+            mLauncher.getHotseat().setTranslationY(0);
+            mLauncher.getWorkspace().getPageIndicator().setTranslationY(0);
+            mLauncher.getSystemUiController().updateUiState(UI_STATE_ALL_APPS, 0);
         }
     }
 
diff --git a/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java b/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java
index 3e4bd31..ee4e4ee 100644
--- a/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java
+++ b/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java
@@ -271,6 +271,7 @@
             setOnClickListener(this);
 
         } else {
+            lp.leftMargin = lp.rightMargin = 0;
             lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
             lp.height = grid.pageIndicatorSizePx;
             lp.bottomMargin = grid.hotseatBarSizePx + insets.bottom;
diff --git a/src/com/android/launcher3/views/AllAppsScrim.java b/src/com/android/launcher3/views/AllAppsScrim.java
index 662f99c..0ef9c8f 100644
--- a/src/com/android/launcher3/views/AllAppsScrim.java
+++ b/src/com/android/launcher3/views/AllAppsScrim.java
@@ -50,12 +50,13 @@
     private final Rect mDrawRect = new Rect();
     private final Rect mPadding = new Rect();
     private final Rect mInsets = new Rect();
-    private final DeviceProfile mGrid;
+
     private final float mRadius;
-    private final int mMinAlpha;
-    private final int mAlphaRange;
     private final int mScrimColor;
 
+    private int mMinAlpha;
+    private int mAlphaRange;
+
     private final float mShadowBlur;
     private final Bitmap mShadowBitmap;
 
@@ -82,16 +83,21 @@
         mRadius = getResources().getDimension(R.dimen.all_apps_scrim_radius);
         mShadowBlur = getResources().getDimension(R.dimen.all_apps_scrim_blur);
 
-        Launcher launcher = Launcher.getLauncher(context);
-        mGrid = launcher.getDeviceProfile();
-        mFillAlpha = mMinAlpha = mGrid.isVerticalBarLayout()
-                ? MIN_ALPHA_LANDSCAPE : MIN_ALPHA_PORTRAIT;
-        mAlphaRange = MAX_ALPHA - mMinAlpha;
+        initDefaults();
+        mFillAlpha = mMinAlpha;
         mShadowBitmap = generateShadowBitmap();
 
         updateColors(mWallpaperColorInfo);
     }
 
+    private DeviceProfile initDefaults() {
+        DeviceProfile grid = Launcher.getLauncher(getContext()).getDeviceProfile();
+        mMinAlpha = grid.isVerticalBarLayout()
+                ? MIN_ALPHA_LANDSCAPE : MIN_ALPHA_PORTRAIT;
+        mAlphaRange = MAX_ALPHA - mMinAlpha;
+        return grid;
+    }
+
     private Bitmap generateShadowBitmap() {
         float curveBot = mRadius + mShadowBlur;
 
@@ -191,29 +197,32 @@
     @Override
     public void setInsets(Rect insets) {
         mInsets.set(insets);
-        if (mGrid.isVerticalBarLayout()) {
-            mPadding.set(mGrid.workspacePadding);
+        DeviceProfile grid = initDefaults();
+        if (grid.isVerticalBarLayout()) {
+            mPadding.set(grid.workspacePadding);
             mPadding.bottom = 0;
             mPadding.left += mInsets.left;
             mPadding.top = mInsets.top;
             mPadding.right += mInsets.right;
+            setDrawRegion(0);
         } else {
+            mPadding.setEmpty();
             float scrimMargin = getResources().getDimension(R.dimen.all_apps_scrim_margin);
-            setDrawRegion(mGrid.hotseatBarSizePx + insets.bottom + scrimMargin);
+            setDrawRegion(grid.hotseatBarSizePx + insets.bottom + scrimMargin);
         }
-        updateDrawRect();
+        updateDrawRect(grid);
         invalidate();
     }
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
-        updateDrawRect();
+        updateDrawRect(Launcher.getLauncher(getContext()).getDeviceProfile());
     }
 
-    private void updateDrawRect() {
+    private void updateDrawRect(DeviceProfile grid) {
         mDrawRect.bottom = getHeight();
-        if (mGrid.isVerticalBarLayout()) {
+        if (grid.isVerticalBarLayout()) {
             mDrawRect.left = (int) (mPadding.left - mShadowBlur - 0.5f);
             mDrawRect.right = (int) (getWidth() - mPadding.right + 0.5f);
         } else {
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index fa82714..b22509c 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -113,6 +113,10 @@
 
     protected void onCloseComplete() {
         super.onCloseComplete();
+        clearNavBarColor();
+    }
+
+    protected void clearNavBarColor() {
         mLauncher.getSystemUiController().updateUiState(
                 SystemUiController.UI_STATE_WIDGET_BOTTOM_SHEET, 0);
     }
diff --git a/src/com/android/launcher3/widget/WidgetsFullSheet.java b/src/com/android/launcher3/widget/WidgetsFullSheet.java
index a1bfe88..d62a909 100644
--- a/src/com/android/launcher3/widget/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsFullSheet.java
@@ -100,6 +100,8 @@
                 mRecyclerView.getPaddingRight(), insets.bottom);
         if (insets.bottom > 0) {
             setupNavBarColor();
+        } else {
+            clearNavBarColor();
         }
         requestLayout();
     }