Merge "Converting tests to Androidx" into ub-launcher3-master
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 01e3a10..230ea4f 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher3;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.content.res.ColorStateList;
@@ -112,10 +114,13 @@
     @ViewDebug.ExportedProperty(category = "launcher")
     private float mTextAlpha = 1;
 
+    @ViewDebug.ExportedProperty(category = "launcher")
     private BadgeInfo mBadgeInfo;
     private BadgeRenderer mBadgeRenderer;
     private int mBadgeColor;
+    @ViewDebug.ExportedProperty(category = "launcher")
     private float mBadgeScale;
+    private Animator mBadgeScaleAnim;
     private boolean mForceHideBadge;
     private Point mTempSpaceForBadgeOffset = new Point();
     private Rect mTempIconBounds = new Rect();
@@ -188,10 +193,29 @@
     public void reset() {
         mBadgeInfo = null;
         mBadgeColor = Color.TRANSPARENT;
+        cancelBadgeScaleAnim();
         mBadgeScale = 0f;
         mForceHideBadge = false;
     }
 
+    private void cancelBadgeScaleAnim() {
+        if (mBadgeScaleAnim != null) {
+            mBadgeScaleAnim.cancel();
+        }
+    }
+
+    private void animateBadgeScale(float... badgeScales) {
+        cancelBadgeScaleAnim();
+        mBadgeScaleAnim = ObjectAnimator.ofFloat(this, BADGE_SCALE_PROPERTY, badgeScales);
+        mBadgeScaleAnim.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mBadgeScaleAnim = null;
+            }
+        });
+        mBadgeScaleAnim.start();
+    }
+
     public void applyFromShortcutInfo(ShortcutInfo info) {
         applyFromShortcutInfo(info, false);
     }
@@ -378,7 +402,7 @@
         if (forceHideBadge) {
             invalidate();
         } else if (hasBadge()) {
-            ObjectAnimator.ofFloat(this, BADGE_SCALE_PROPERTY, 0, 1).start();
+            animateBadgeScale(0, 1);
         }
     }
 
@@ -524,8 +548,9 @@
             if (wasBadged || isBadged) {
                 // Animate when a badge is first added or when it is removed.
                 if (animate && (wasBadged ^ isBadged) && isShown()) {
-                    ObjectAnimator.ofFloat(this, BADGE_SCALE_PROPERTY, newBadgeScale).start();
+                    animateBadgeScale(newBadgeScale);
                 } else {
+                    cancelBadgeScaleAnim();
                     mBadgeScale = newBadgeScale;
                     invalidate();
                 }
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 7f99323..f0ddd53 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -353,6 +353,7 @@
     public void onEnterAnimationComplete() {
         super.onEnterAnimationComplete();
         UiFactory.onEnterAnimationComplete(this);
+        mAllAppsController.highlightWorkTabIfNecessary();
     }
 
     @Override
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 6908ab4..3d15c75 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -486,8 +486,13 @@
     }
 
     public void onScrollUpEnd() {
+        highlightWorkTabIfNecessary();
+    }
+
+    void highlightWorkTabIfNecessary() {
         if (mUsingTabs) {
-            ((PersonalWorkSlidingTabStrip) findViewById(R.id.tabs)).highlightWorkTabIfNecessary();
+            ((PersonalWorkSlidingTabStrip) findViewById(R.id.tabs))
+                    .highlightWorkTabIfNecessary();
         }
     }
 
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 24a8d51..e7313e8 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -249,11 +249,21 @@
         if (Float.compare(mProgress, 1f) == 0) {
             mAppsView.setVisibility(View.INVISIBLE);
             mAppsView.reset(false /* animate */);
-        } else if (Float.compare(mProgress, 0f) == 0) {
+        } else if (isAllAppsExpanded()) {
             mAppsView.setVisibility(View.VISIBLE);
             mAppsView.onScrollUpEnd();
         } else {
             mAppsView.setVisibility(View.VISIBLE);
         }
     }
+
+    private boolean isAllAppsExpanded() {
+        return Float.compare(mProgress, 0f) == 0;
+    }
+
+    public void highlightWorkTabIfNecessary() {
+        if (isAllAppsExpanded()) {
+            mAppsView.highlightWorkTabIfNecessary();
+        }
+    }
 }
diff --git a/src/com/android/launcher3/badge/FolderBadgeInfo.java b/src/com/android/launcher3/badge/FolderBadgeInfo.java
index 3a1bf60..fa5e8a4 100644
--- a/src/com/android/launcher3/badge/FolderBadgeInfo.java
+++ b/src/com/android/launcher3/badge/FolderBadgeInfo.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher3.badge;
 
+import android.view.ViewDebug;
+
 import com.android.launcher3.Utilities;
 
 /**
@@ -56,6 +58,7 @@
         return 0;
     }
 
+    @ViewDebug.ExportedProperty(category = "launcher")
     public boolean hasBadge() {
         return mNumNotifications > 0;
     }
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 6a3ebcf..a059627 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -644,7 +644,7 @@
                 mFolderIcon.mBackground.animateBackgroundStroke();
                 mFolderIcon.onFolderClose(mContent.getCurrentPage());
                 if (mFolderIcon.hasBadge()) {
-                    mFolderIcon.createBadgeScaleAnimator(0f, 1f).start();
+                    mFolderIcon.animateBadgeScale(0f, 1f);
                 }
                 mFolderIcon.requestFocus();
             }
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 87a0796..d09f036 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -20,6 +20,7 @@
 import static com.android.launcher3.folder.PreviewItemManager.INITIAL_ITEM_ANIMATION_DURATION;
 
 import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.graphics.Canvas;
@@ -32,6 +33,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
+import android.view.ViewDebug;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 
@@ -106,9 +108,12 @@
 
     private Alarm mOpenAlarm = new Alarm();
 
+    @ViewDebug.ExportedProperty(category = "launcher", deepExport = true)
     private FolderBadgeInfo mBadgeInfo = new FolderBadgeInfo();
     private BadgeRenderer mBadgeRenderer;
+    @ViewDebug.ExportedProperty(category = "launcher")
     private float mBadgeScale;
+    private Animator mBadgeScaleAnim;
     private Point mTempSpaceForBadgeOffset = new Point();
 
     private static final Property<FolderIcon, Float> BADGE_SCALE_PROPERTY
@@ -393,15 +398,30 @@
         float newBadgeScale = isBadged ? 1f : 0f;
         // Animate when a badge is first added or when it is removed.
         if ((wasBadged ^ isBadged) && isShown()) {
-            createBadgeScaleAnimator(newBadgeScale).start();
+            animateBadgeScale(newBadgeScale);
         } else {
+            cancelBadgeScaleAnim();
             mBadgeScale = newBadgeScale;
             invalidate();
         }
     }
 
-    public Animator createBadgeScaleAnimator(float... badgeScales) {
-        return ObjectAnimator.ofFloat(this, BADGE_SCALE_PROPERTY, badgeScales);
+    private void cancelBadgeScaleAnim() {
+        if (mBadgeScaleAnim != null) {
+            mBadgeScaleAnim.cancel();
+        }
+    }
+
+    public void animateBadgeScale(float... badgeScales) {
+        cancelBadgeScaleAnim();
+        mBadgeScaleAnim = ObjectAnimator.ofFloat(this, BADGE_SCALE_PROPERTY, badgeScales);
+        mBadgeScaleAnim.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mBadgeScaleAnim = null;
+            }
+        });
+        mBadgeScaleAnim.start();
     }
 
     public boolean hasBadge() {
diff --git a/src/com/android/launcher3/util/ConfigMonitor.java b/src/com/android/launcher3/util/ConfigMonitor.java
index 2489d30..611931d 100644
--- a/src/com/android/launcher3/util/ConfigMonitor.java
+++ b/src/com/android/launcher3/util/ConfigMonitor.java
@@ -21,37 +21,102 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.Configuration;
+import android.graphics.Point;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManager.DisplayListener;
+import android.os.Handler;
 import android.util.Log;
+import android.view.Display;
+import android.view.WindowManager;
 
 /**
  * {@link BroadcastReceiver} which watches configuration changes and
  * restarts the process in case changes which affect the device profile occur.
  */
-public class ConfigMonitor extends BroadcastReceiver {
+public class ConfigMonitor extends BroadcastReceiver implements DisplayListener {
+
+    private static final String TAG = "ConfigMonitor";
+
+    private final Point mTmpPoint1 = new Point();
+    private final Point mTmpPoint2 = new Point();
 
     private final Context mContext;
     private final float mFontScale;
     private final int mDensity;
 
+    private final int mDisplayId;
+    private final Point mRealSize;
+    private final Point mSmallestSize, mLargestSize;
+
     public ConfigMonitor(Context context) {
         mContext = context;
 
         Configuration config = context.getResources().getConfiguration();
         mFontScale = config.fontScale;
         mDensity = config.densityDpi;
+
+        Display display = getDefaultDisplay(context);
+        mDisplayId = display.getDisplayId();
+
+        mRealSize = new Point();
+        display.getRealSize(mRealSize);
+
+        mSmallestSize = new Point();
+        mLargestSize = new Point();
+        display.getCurrentSizeRange(mSmallestSize, mLargestSize);
     }
 
     @Override
     public void onReceive(Context context, Intent intent) {
         Configuration config = context.getResources().getConfiguration();
         if (mFontScale != config.fontScale || mDensity != config.densityDpi) {
-            Log.d("ConfigMonitor", "Configuration changed, restarting launcher");
-            mContext.unregisterReceiver(this);
-            android.os.Process.killProcess(android.os.Process.myPid());
+            Log.d(TAG, "Configuration changed");
+            killProcess();
         }
     }
 
     public void register() {
         mContext.registerReceiver(this, new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED));
+        mContext.getSystemService(DisplayManager.class)
+                .registerDisplayListener(this, new Handler(UiThreadHelper.getBackgroundLooper()));
+    }
+
+    @Override
+    public void onDisplayAdded(int displayId) { }
+
+    @Override
+    public void onDisplayRemoved(int displayId) { }
+
+    @Override
+    public void onDisplayChanged(int displayId) {
+        if (displayId != mDisplayId) {
+            return;
+        }
+        Display display = getDefaultDisplay(mContext);
+        display.getRealSize(mTmpPoint1);
+
+        if (!mRealSize.equals(mTmpPoint1) && !mRealSize.equals(mTmpPoint1.y, mTmpPoint1.x)) {
+            Log.d(TAG, String.format("Display size changed from %s to %s", mRealSize, mTmpPoint1));
+            killProcess();
+            return;
+        }
+
+        display.getCurrentSizeRange(mTmpPoint1, mTmpPoint2);
+        if (!mSmallestSize.equals(mTmpPoint1) || !mLargestSize.equals(mTmpPoint2)) {
+            Log.d(TAG, String.format("Available size changed from [%s, %s] to [%s, %s]",
+                    mSmallestSize, mLargestSize, mTmpPoint1, mTmpPoint2));
+            killProcess();
+        }
+    }
+
+    private void killProcess() {
+        Log.d(TAG, "restarting launcher");
+        mContext.unregisterReceiver(this);
+        mContext.getSystemService(DisplayManager.class).unregisterDisplayListener(this);
+        android.os.Process.killProcess(android.os.Process.myPid());
+    }
+
+    private Display getDefaultDisplay(Context context) {
+        return context.getSystemService(WindowManager.class).getDefaultDisplay();
     }
 }
diff --git a/src/com/android/launcher3/views/AbstractSlideInView.java b/src/com/android/launcher3/views/AbstractSlideInView.java
index 59bea48..26c8f24 100644
--- a/src/com/android/launcher3/views/AbstractSlideInView.java
+++ b/src/com/android/launcher3/views/AbstractSlideInView.java
@@ -108,7 +108,8 @@
     @Override
     public boolean onControllerTouchEvent(MotionEvent ev) {
         mSwipeDetector.onTouchEvent(ev);
-        if (ev.getAction() == MotionEvent.ACTION_UP && mSwipeDetector.isIdleState()) {
+        if (ev.getAction() == MotionEvent.ACTION_UP && mSwipeDetector.isIdleState()
+                && !isOpeningAnimationRunning()) {
             // If we got ACTION_UP without ever starting swipe, close the panel.
             if (!getPopupContainer().isEventOverView(mContent, ev)) {
                 close(true);
@@ -117,6 +118,10 @@
         return true;
     }
 
+    private boolean isOpeningAnimationRunning() {
+        return mIsOpen && mOpenCloseAnimator.isRunning();
+    }
+
     /* SwipeDetector.Listener */
 
     @Override
@@ -154,7 +159,7 @@
             onCloseComplete();
             return;
         }
-        if (!mIsOpen || mOpenCloseAnimator.isRunning()) {
+        if (!mIsOpen) {
             return;
         }
         mOpenCloseAnimator.setValues(
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index bf8b537..74a91a4 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -115,7 +115,7 @@
         sActiveContainer = new WeakReference<>(container);
     }
 
-    boolean isSwipeUpEnabled() {
+    public boolean isSwipeUpEnabled() {
         return mSwipeUpEnabledOverride != null ? mSwipeUpEnabledOverride : mSwipeUpEnabled;
     }