diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java index 2c6629d595..da464c0072 100644 --- a/src/com/android/launcher3/AbstractFloatingView.java +++ b/src/com/android/launcher3/AbstractFloatingView.java @@ -59,6 +59,10 @@ public abstract class AbstractFloatingView extends LinearLayout implements Touch | TYPE_WIDGETS_BOTTOM_SHEET | TYPE_WIDGET_RESIZE_FRAME | TYPE_WIDGETS_FULL_SHEET | TYPE_QUICKSTEP_PREVIEW | TYPE_ON_BOARD_POPUP; + // Type of popups which should be kept open during launcher rebind + public static final int TYPE_REBIND_SAFE = TYPE_WIDGETS_FULL_SHEET + | TYPE_QUICKSTEP_PREVIEW | TYPE_ON_BOARD_POPUP; + protected boolean mIsOpen; public AbstractFloatingView(Context context, AttributeSet attrs) { diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 44b64d94aa..6b6029d3ae 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -60,7 +60,6 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.pm.PackageManager; import android.database.sqlite.SQLiteDatabase; import android.graphics.Point; -import android.graphics.PointF; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.AsyncTask; @@ -99,10 +98,10 @@ import com.android.launcher3.Workspace.ItemOperator; import com.android.launcher3.accessibility.LauncherAccessibilityDelegate; import com.android.launcher3.allapps.AllAppsContainerView; import com.android.launcher3.allapps.AllAppsTransitionController; +import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.compat.AppWidgetManagerCompat; import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.compat.LauncherAppsCompatVO; -import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragLayer; @@ -121,7 +120,6 @@ import com.android.launcher3.pageindicators.PageIndicator; import com.android.launcher3.popup.PopupContainerWithArrow; import com.android.launcher3.popup.PopupDataProvider; import com.android.launcher3.shortcuts.DeepShortcutManager; -import com.android.launcher3.states.AllAppsState; import com.android.launcher3.states.InternalStateHandler; import com.android.launcher3.uioverrides.UiFactory; import com.android.launcher3.userevent.nano.LauncherLogProto; @@ -848,9 +846,7 @@ public class Launcher extends BaseActivity // Refresh shortcuts if the permission changed. mModel.refreshShortcutsIfRequired(); - if (shouldShowDiscoveryBounce()) { - mAllAppsController.showDiscoveryBounce(); - } + DiscoveryBounce.showIfNeeded(this); if (mLauncherCallbacks != null) { mLauncherCallbacks.onResume(); } @@ -1040,7 +1036,7 @@ public class Launcher extends BaseActivity | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); // Setup the drag layer - mDragLayer.setup(this, mDragController, mAllAppsController); + mDragLayer.setup(this, mDragController); // Setup the hotseat mHotseat = (Hotseat) findViewById(R.id.hotseat); @@ -2429,7 +2425,7 @@ public class Launcher extends BaseActivity // we are starting a fresh bind, close all such panels as all the icons are about // to go away. AbstractFloatingView.closeOpenViews(this, true, - AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_WIDGETS_FULL_SHEET); + AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE); setWorkspaceLoading(true); @@ -3070,12 +3066,6 @@ public class Launcher extends BaseActivity return mRotationEnabled; } - private boolean shouldShowDiscoveryBounce() { - return isInState(NORMAL) - && !mSharedPrefs.getBoolean(AllAppsState.APPS_VIEW_SHOWN, false) - && !UserManagerCompat.getInstance(this).isDemoUser(); - } - /** * $ adb shell dumpsys activity com.android.launcher3.Launcher [--all] */ diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index eb2670426c..1ec7ac0b1e 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -4,7 +4,6 @@ import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; import static com.android.launcher3.anim.Interpolators.LINEAR; import android.animation.Animator; -import android.animation.AnimatorInflater; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; @@ -77,8 +76,6 @@ public class AllAppsTransitionController private static final float DEFAULT_SHIFT_RANGE = 10; - private boolean mIsTranslateWithoutWorkspace = false; - private Animator mDiscoBounceAnimation; private GradientView mGradientView; public AllAppsTransitionController(Launcher l) { @@ -149,10 +146,6 @@ public class AllAppsTransitionController PARALLAX_COEFFICIENT * (-mShiftRange + shiftCurrent), hotseatAlpha); } - - if (mIsTranslateWithoutWorkspace) { - return; - } mWorkspace.setWorkspaceYTranslationAndAlpha( PARALLAX_COEFFICIENT * (-mShiftRange + shiftCurrent), workspaceAlpha); @@ -191,7 +184,13 @@ public class AllAppsTransitionController this, PROGRESS, mProgress, toState.verticalProgress); anim.setDuration(config.duration); anim.setInterpolator(interpolator); - anim.addListener(new AnimationSuccessListener() { + anim.addListener(getProgressAnimatorListener()); + + animationOut.play(anim); + } + + public AnimatorListenerAdapter getProgressAnimatorListener() { + return new AnimationSuccessListener() { @Override public void onAnimationSuccess(Animator animator) { onProgressAnimationEnd(); @@ -201,50 +200,7 @@ public class AllAppsTransitionController public void onAnimationStart(Animator animation) { onProgressAnimationStart(); } - }); - - animationOut.play(anim); - } - - public void showDiscoveryBounce() { - // cancel existing animation in case user locked and unlocked at a super human speed. - cancelDiscoveryAnimation(); - - // assumption is that this variable is always null - mDiscoBounceAnimation = AnimatorInflater.loadAnimator(mLauncher, - R.animator.discovery_bounce); - mDiscoBounceAnimation.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animator) { - mIsTranslateWithoutWorkspace = true; - onProgressAnimationStart(); - } - - @Override - public void onAnimationEnd(Animator animator) { - onProgressAnimationEnd(); - mDiscoBounceAnimation = null; - mIsTranslateWithoutWorkspace = false; - } - }); - mDiscoBounceAnimation.setTarget(this); - mAppsView.post(new Runnable() { - @Override - public void run() { - if (mDiscoBounceAnimation == null) { - return; - } - mDiscoBounceAnimation.start(); - } - }); - } - - public void cancelDiscoveryAnimation() { - if (mDiscoBounceAnimation == null) { - return; - } - mDiscoBounceAnimation.cancel(); - mDiscoBounceAnimation = null; + }; } public void setupViews(AllAppsContainerView appsView, Hotseat hotseat, Workspace workspace) { diff --git a/src/com/android/launcher3/allapps/DiscoveryBounce.java b/src/com/android/launcher3/allapps/DiscoveryBounce.java new file mode 100644 index 0000000000..9723545151 --- /dev/null +++ b/src/com/android/launcher3/allapps/DiscoveryBounce.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2017 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.allapps; + +import static com.android.launcher3.LauncherState.NORMAL; + +import android.animation.Animator; +import android.animation.AnimatorInflater; +import android.animation.AnimatorListenerAdapter; +import android.view.MotionEvent; + +import com.android.launcher3.AbstractFloatingView; +import com.android.launcher3.Launcher; +import com.android.launcher3.R; +import com.android.launcher3.compat.UserManagerCompat; +import com.android.launcher3.states.AllAppsState; + +/** + * Floating view responsible for showing discovery bounce animation + */ +public class DiscoveryBounce extends AbstractFloatingView { + + private final Launcher mLauncher; + private final Animator mDiscoBounceAnimation; + + public DiscoveryBounce(Launcher launcher) { + super(launcher, null); + mLauncher = launcher; + + mDiscoBounceAnimation = AnimatorInflater.loadAnimator(mLauncher, + R.animator.discovery_bounce); + AllAppsTransitionController controller = mLauncher.getAllAppsController(); + mDiscoBounceAnimation.setTarget(controller); + mDiscoBounceAnimation.addListener(controller.getProgressAnimatorListener()); + + mDiscoBounceAnimation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + handleClose(false); + } + }); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + mDiscoBounceAnimation.start(); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (mDiscoBounceAnimation.isRunning()) { + mDiscoBounceAnimation.end(); + } + } + + @Override + public boolean onControllerInterceptTouchEvent(MotionEvent ev) { + handleClose(false); + return false; + } + + @Override + protected void handleClose(boolean animate) { + if (mIsOpen) { + mIsOpen = false; + mLauncher.getDragLayer().removeView(this); + } + } + + @Override + public void logActionCommand(int command) { + // Since this is on-boarding popup, it is not a user controlled action. + } + + @Override + protected boolean isOfType(int type) { + return (type & TYPE_ON_BOARD_POPUP) != 0; + } + + public static void showIfNeeded(Launcher launcher) { + if (!launcher.isInState(NORMAL) + || launcher.getSharedPrefs().getBoolean(AllAppsState.APPS_VIEW_SHOWN, false) + || AbstractFloatingView.getTopOpenView(launcher) != null + || UserManagerCompat.getInstance(launcher).isDemoUser()) { + return; + } + + DiscoveryBounce view = new DiscoveryBounce(launcher); + view.mIsOpen = true; + launcher.getDragLayer().addView(view); + } +} diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java index 9f9822c4c6..cf76e2ec9c 100644 --- a/src/com/android/launcher3/dragndrop/DragLayer.java +++ b/src/com/android/launcher3/dragndrop/DragLayer.java @@ -45,7 +45,6 @@ import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.ShortcutAndWidgetContainer; import com.android.launcher3.Utilities; -import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.folder.Folder; import com.android.launcher3.folder.FolderIcon; @@ -90,9 +89,6 @@ public class DragLayer extends InsettableFrameLayout { private final ViewGroupFocusHelper mFocusIndicatorHelper; private final PageCutOutScrimDrawable mPageCutOutScrim; - // Handles all apps pull up interaction - private AllAppsTransitionController mAllAppsController; - protected TouchController[] mControllers; private TouchController mActiveController; /** @@ -113,11 +109,9 @@ public class DragLayer extends InsettableFrameLayout { mPageCutOutScrim.setCallback(this); } - public void setup(Launcher launcher, DragController dragController, - AllAppsTransitionController allAppsTransitionController) { + public void setup(Launcher launcher, DragController dragController) { mLauncher = launcher; mDragController = dragController; - mAllAppsController = allAppsTransitionController; mControllers = UiFactory.createTouchControllers(mLauncher); } @@ -156,12 +150,7 @@ public class DragLayer extends InsettableFrameLayout { public boolean onInterceptTouchEvent(MotionEvent ev) { int action = ev.getAction(); - if (action == MotionEvent.ACTION_DOWN) { - // Cancel discovery bounce animation when a user start interacting on anywhere on - // dray layer even if mAllAppsController is NOT the active controller. - // TODO: handle other input other than touch - mAllAppsController.cancelDiscoveryAnimation(); - } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { + if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { if (mTouchCompleteListener != null) { mTouchCompleteListener.onTouchComplete(); } @@ -800,6 +789,6 @@ public class DragLayer extends InsettableFrameLayout { } public interface TouchCompleteListener { - public void onTouchComplete(); + void onTouchComplete(); } }