Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3c61313c authored by Tracy Zhou's avatar Tracy Zhou Committed by android-build-merger
Browse files

Merge "Implement swipe up and quick scrub onboarding" into pi-dev

am: 08a20282

Change-Id: Ie6a41f240dda33edcfa8f5015ae0884ca9701e94
parents a596129a 08a20282
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -44,4 +44,9 @@ interface ISystemUiProxy {
     * Notifies SystemUI that split screen has been invoked.
     */
    void onSplitScreenInvoked() = 5;

    /**
     * Notifies SystemUI that Overview is shown.
     */
    void onOverviewShown(boolean fromHome) = 6;
}
+21 −0
Original line number Diff line number Diff line
@@ -118,6 +118,19 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
            }
        }

        public void onOverviewShown(boolean fromHome) {
            long token = Binder.clearCallingIdentity();
            try {
                mHandler.post(() -> {
                    for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
                        mConnectionCallbacks.get(i).onOverviewShown(fromHome);
                    }
                });
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }

        public void setInteractionState(@InteractionType int flags) {
            long token = Binder.clearCallingIdentity();
            try {
@@ -306,6 +319,12 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
        }
    }

    public void notifyQuickScrubStarted() {
        for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
            mConnectionCallbacks.get(i).onQuickScrubStarted();
        }
    }

    private void updateEnabledState() {
        mIsEnabled = mContext.getPackageManager().resolveServiceAsUser(mQuickStepIntent,
                MATCH_DIRECT_BOOT_UNAWARE,
@@ -325,5 +344,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
        default void onConnectionChanged(boolean isConnected) {}
        default void onQuickStepStarted() {}
        default void onInteractionFlagsChanged(@InteractionType int flags) {}
        default void onOverviewShown(boolean fromHome) {}
        default void onQuickScrubStarted() {}
    }
}
+8 −4
Original line number Diff line number Diff line
@@ -50,8 +50,10 @@ public final class Prefs {
            Key.QS_NIGHTDISPLAY_ADDED,
            Key.QS_LONG_PRESS_TOOLTIP_SHOWN_COUNT,
            Key.SEEN_MULTI_USER,
            Key.NUM_APPS_LAUNCHED,
            Key.HAS_SEEN_RECENTS_ONBOARDING,
            Key.HAS_SEEN_RECENTS_SWIPE_UP_ONBOARDING,
            Key.HAS_SEEN_RECENTS_QUICK_SCRUB_ONBOARDING,
            Key.OVERVIEW_OPENED_COUNT,
            Key.OVERVIEW_OPENED_FROM_HOME_COUNT,
            Key.SEEN_RINGER_GUIDANCE_COUNT,
            Key.QS_HAS_TURNED_OFF_MOBILE_DATA,
            Key.TOUCHED_RINGER_TOGGLE,
@@ -88,8 +90,10 @@ public final class Prefs {
         */
        String QS_LONG_PRESS_TOOLTIP_SHOWN_COUNT = "QsLongPressTooltipShownCount";
        String SEEN_MULTI_USER = "HasSeenMultiUser";
        String NUM_APPS_LAUNCHED = "NumAppsLaunched";
        String HAS_SEEN_RECENTS_ONBOARDING = "HasSeenRecentsOnboarding";
        String OVERVIEW_OPENED_COUNT = "OverviewOpenedCount";
        String OVERVIEW_OPENED_FROM_HOME_COUNT = "OverviewOpenedFromHomeCount";
        String HAS_SEEN_RECENTS_SWIPE_UP_ONBOARDING = "HasSeenRecentsSwipeUpOnboarding";
        String HAS_SEEN_RECENTS_QUICK_SCRUB_ONBOARDING = "HasSeenRecentsQuickScrubOnboarding";
        String SEEN_RINGER_GUIDANCE_COUNT = "RingerGuidanceCount";
        String QS_TILE_SPECS_REVEALED = "QsTileSpecsRevealed";
        String QS_HAS_TURNED_OFF_MOBILE_DATA = "QsHasTurnedOffMobileData";
+157 −41
Original line number Diff line number Diff line
@@ -19,6 +19,12 @@ package com.android.systemui.recents;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;

import static com.android.systemui.Prefs.Key.HAS_SEEN_RECENTS_QUICK_SCRUB_ONBOARDING;
import static com.android.systemui.Prefs.Key.HAS_SEEN_RECENTS_SWIPE_UP_ONBOARDING;
import static com.android.systemui.Prefs.Key.OVERVIEW_OPENED_COUNT;
import static com.android.systemui.Prefs.Key.OVERVIEW_OPENED_FROM_HOME_COUNT;

import android.annotation.StringRes;
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.content.Context;
@@ -31,8 +37,6 @@ import android.graphics.drawable.ShapeDrawable;
import android.os.Build;
import android.os.SystemProperties;
import android.os.UserManager;
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -65,10 +69,16 @@ public class RecentsOnboarding {
    private static final boolean ONBOARDING_ENABLED = false;
    private static final long SHOW_DELAY_MS = 500;
    private static final long SHOW_HIDE_DURATION_MS = 300;
    // Don't show the onboarding until the user has launched this number of apps.
    private static final int SHOW_ON_APP_LAUNCH = 2;
    // After explicitly dismissing, show again after launching this number of apps.
    private static final int SHOW_ON_APP_LAUNCH_AFTER_DISMISS = 5;
    // Show swipe-up tips after opening overview from home this number of times.
    private static final int SWIPE_UP_SHOW_ON_OVERVIEW_OPENED_FROM_HOME_COUNT = 3;
    // Show quick scrub tips after opening overview this number of times.
    private static final int QUICK_SCRUB_SHOW_ON_OVERVIEW_OPENED_COUNT = 10;
    // After explicitly dismissing, show again after launching this number of apps for swipe-up
    // tips.
    private static final int SWIPE_UP_SHOW_ON_APP_LAUNCH_AFTER_DISMISS = 5;
    // After explicitly dismissing, show again after launching this number of apps for QuickScrub
    // tips.
    private static final int QUICK_SCRUB_SHOW_ON_APP_LAUNCH_AFTER_DISMISS = 10;

    private final Context mContext;
    private final WindowManager mWindowManager;
@@ -82,11 +92,14 @@ public class RecentsOnboarding {
    private final int mOnboardingToastArrowRadius;
    private int mNavBarHeight;

    private boolean mOverviewProxyListenerRegistered;
    private boolean mTaskListenerRegistered;
    private boolean mLayoutAttachedToWindow;
    private int mLastTaskId;
    private boolean mHasDismissed;
    private int mNumAppsLaunchedSinceDismiss;
    private boolean mHasDismissedSwipeUpTip;
    private boolean mHasDismissedQuickScrubTip;
    private int mNumAppsLaunchedSinceSwipeUpTipDismiss;
    private int mNumAppsLaunchedSinceQuickScrubTipDismiss;

    private final SysUiTaskStackChangeListener mTaskListener = new SysUiTaskStackChangeListener() {
        @Override
@@ -107,18 +120,40 @@ public class RecentsOnboarding {
            int activityType = info.configuration.windowConfiguration.getActivityType();
            if (activityType == ACTIVITY_TYPE_STANDARD) {
                mLastTaskId = info.id;
                int numAppsLaunched = mHasDismissed ? mNumAppsLaunchedSinceDismiss
                        : Prefs.getInt(mContext, Prefs.Key.NUM_APPS_LAUNCHED, 0);
                int showOnAppLaunch = mHasDismissed ? SHOW_ON_APP_LAUNCH_AFTER_DISMISS
                        : SHOW_ON_APP_LAUNCH;
                numAppsLaunched++;
                if (numAppsLaunched >= showOnAppLaunch) {
                    show();

                boolean alreadySeenSwipeUpOnboarding = hasSeenSwipeUpOnboarding();
                boolean alreadySeenQuickScrubsOnboarding = hasSeenQuickScrubOnboarding();
                if (alreadySeenSwipeUpOnboarding && alreadySeenQuickScrubsOnboarding) {
                    onDisconnectedFromLauncher();
                    return;
                }

                if (!alreadySeenSwipeUpOnboarding) {
                    if (getOpenedOverviewFromHomeCount()
                            >= SWIPE_UP_SHOW_ON_OVERVIEW_OPENED_FROM_HOME_COUNT) {
                        if (mHasDismissedSwipeUpTip) {
                            mNumAppsLaunchedSinceSwipeUpTipDismiss++;
                            if (mNumAppsLaunchedSinceSwipeUpTipDismiss
                                    == SWIPE_UP_SHOW_ON_APP_LAUNCH_AFTER_DISMISS) {
                                mNumAppsLaunchedSinceSwipeUpTipDismiss = 0;
                                show(R.string.recents_swipe_up_onboarding);
                            }
                        } else {
                    if (mHasDismissed) {
                        mNumAppsLaunchedSinceDismiss = numAppsLaunched;
                            show(R.string.recents_swipe_up_onboarding);
                        }
                    }
                } else {
                    if (getOpenedOverviewCount() >= QUICK_SCRUB_SHOW_ON_OVERVIEW_OPENED_COUNT) {
                        if (mHasDismissedQuickScrubTip) {
                            mNumAppsLaunchedSinceQuickScrubTipDismiss++;
                            if (mNumAppsLaunchedSinceQuickScrubTipDismiss
                                    == QUICK_SCRUB_SHOW_ON_APP_LAUNCH_AFTER_DISMISS) {
                                mNumAppsLaunchedSinceQuickScrubTipDismiss = 0;
                                show(R.string.recents_quick_scrub_onboarding);
                            }
                        } else {
                        Prefs.putInt(mContext, Prefs.Key.NUM_APPS_LAUNCHED, numAppsLaunched);
                            show(R.string.recents_quick_scrub_onboarding);
                        }
                    }
                }
            } else {
@@ -127,13 +162,36 @@ public class RecentsOnboarding {
        }
    };

    private OverviewProxyService.OverviewProxyListener mOverviewProxyListener =
            new OverviewProxyService.OverviewProxyListener() {
                @Override
                public void onOverviewShown(boolean fromHome) {
                    boolean alreadySeenRecentsOnboarding = hasSeenSwipeUpOnboarding();
                    if (!alreadySeenRecentsOnboarding && !fromHome) {
                        setHasSeenSwipeUpOnboarding(true);
                    }
                    if (fromHome) {
                        setOpenedOverviewFromHomeCount(getOpenedOverviewFromHomeCount() + 1);
                    }
                    setOpenedOverviewCount(getOpenedOverviewCount() + 1);
                }

                @Override
                public void onQuickScrubStarted() {
                    boolean alreadySeenQuickScrubsOnboarding = hasSeenQuickScrubOnboarding();
                    if (!alreadySeenQuickScrubsOnboarding) {
                        setHasSeenQuickScrubOnboarding(true);
                    }
                }
            };

    private final View.OnAttachStateChangeListener mOnAttachStateChangeListener
            = new View.OnAttachStateChangeListener() {
        @Override
        public void onViewAttachedToWindow(View view) {
            if (view == mLayout) {
                mLayoutAttachedToWindow = true;
                mHasDismissed = false;
                mHasDismissedSwipeUpTip = false;
            }
        }

@@ -167,8 +225,19 @@ public class RecentsOnboarding {
        mLayout.addOnAttachStateChangeListener(mOnAttachStateChangeListener);
        mDismissView.setOnClickListener(v -> {
            hide(true);
            mHasDismissed = true;
            mNumAppsLaunchedSinceDismiss = 0;
            if (v.getTag().equals(R.string.recents_swipe_up_onboarding)) {
                mHasDismissedSwipeUpTip = true;
                mNumAppsLaunchedSinceSwipeUpTipDismiss = 0;
            } else {
                if (mHasDismissedQuickScrubTip) {
                    // If user dismisses the quick scrub tip twice, we consider user has seen it
                    // and do not show it again.
                    setHasSeenQuickScrubOnboarding(true);
                } else {
                    mHasDismissedQuickScrubTip = true;
                }
                mNumAppsLaunchedSinceQuickScrubTipDismiss = 0;
            }
        });

        ViewGroup.LayoutParams arrowLp = mArrowView.getLayoutParams();
@@ -181,8 +250,10 @@ public class RecentsOnboarding {
        mArrowView.setBackground(arrowDrawable);

        if (RESET_PREFS_FOR_DEBUG) {
            Prefs.putBoolean(mContext, Prefs.Key.HAS_SEEN_RECENTS_ONBOARDING, false);
            Prefs.putInt(mContext, Prefs.Key.NUM_APPS_LAUNCHED, 0);
            setHasSeenSwipeUpOnboarding(false);
            setHasSeenQuickScrubOnboarding(false);
            setOpenedOverviewCount(0);
            setOpenedOverviewFromHomeCount(0);
        }
    }

@@ -190,30 +261,35 @@ public class RecentsOnboarding {
        if (!ONBOARDING_ENABLED) {
            return;
        }
        boolean alreadySeenRecentsOnboarding = Prefs.getBoolean(mContext,
                Prefs.Key.HAS_SEEN_RECENTS_ONBOARDING, false);
        if (!mTaskListenerRegistered && !alreadySeenRecentsOnboarding) {
            ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskListener);
            mTaskListenerRegistered = true;
        }

        if (hasSeenSwipeUpOnboarding() && hasSeenQuickScrubOnboarding()) {
            return;
        }

    public void onQuickStepStarted() {
        boolean alreadySeenRecentsOnboarding = Prefs.getBoolean(mContext,
                Prefs.Key.HAS_SEEN_RECENTS_ONBOARDING, false);
        if (!alreadySeenRecentsOnboarding) {
            Prefs.putBoolean(mContext, Prefs.Key.HAS_SEEN_RECENTS_ONBOARDING, true);
            onDisconnectedFromLauncher();
        if (!mOverviewProxyListenerRegistered) {
            mOverviewProxyService.addCallback(mOverviewProxyListener);
            mOverviewProxyListenerRegistered = true;
        }
        if (!mTaskListenerRegistered) {
            ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskListener);
            mTaskListenerRegistered = true;
        }
    }

    public void onDisconnectedFromLauncher() {
        if (mOverviewProxyListenerRegistered) {
            mOverviewProxyService.removeCallback(mOverviewProxyListener);
            mOverviewProxyListenerRegistered = false;
        }
        if (mTaskListenerRegistered) {
            ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskListener);
            mTaskListenerRegistered = false;
        }
        mHasDismissed = false;
        mNumAppsLaunchedSinceDismiss = 0;

        mHasDismissedSwipeUpTip = false;
        mHasDismissedQuickScrubTip = false;
        mNumAppsLaunchedSinceSwipeUpTipDismiss = 0;
        mNumAppsLaunchedSinceQuickScrubTipDismiss = 0;
        hide(false);
    }

@@ -223,11 +299,12 @@ public class RecentsOnboarding {
        }
    }

    public void show() {
    public void show(@StringRes int stringRes) {
        if (!shouldShow()) {
            return;
        }
        mTextView.setText(R.string.recents_swipe_up_onboarding);
        mDismissView.setTag(stringRes);
        mTextView.setText(stringRes);
        // Only show in portrait.
        int orientation = mContext.getResources().getConfiguration().orientation;
        if (!mLayoutAttachedToWindow && orientation == Configuration.ORIENTATION_PORTRAIT) {
@@ -299,4 +376,43 @@ public class RecentsOnboarding {
        lp.gravity = Gravity.BOTTOM;
        return lp;
    }

    private boolean hasSeenSwipeUpOnboarding() {
        return Prefs.getBoolean(mContext, HAS_SEEN_RECENTS_SWIPE_UP_ONBOARDING, false);
    }

    private void setHasSeenSwipeUpOnboarding(boolean hasSeenSwipeUpOnboarding) {
        Prefs.putBoolean(mContext, HAS_SEEN_RECENTS_SWIPE_UP_ONBOARDING, hasSeenSwipeUpOnboarding);
        if (hasSeenSwipeUpOnboarding && hasSeenQuickScrubOnboarding()) {
            onDisconnectedFromLauncher();
        }
    }

    private boolean hasSeenQuickScrubOnboarding() {
        return Prefs.getBoolean(mContext, HAS_SEEN_RECENTS_QUICK_SCRUB_ONBOARDING, false);
    }

    private void setHasSeenQuickScrubOnboarding(boolean hasSeenQuickScrubOnboarding) {
        Prefs.putBoolean(mContext, HAS_SEEN_RECENTS_QUICK_SCRUB_ONBOARDING,
                hasSeenQuickScrubOnboarding);
        if (hasSeenQuickScrubOnboarding && hasSeenSwipeUpOnboarding()) {
            onDisconnectedFromLauncher();
        }
    }

    private int getOpenedOverviewFromHomeCount() {
        return Prefs.getInt(mContext, OVERVIEW_OPENED_FROM_HOME_COUNT, 0);
    }

    private void setOpenedOverviewFromHomeCount(int openedOverviewFromHomeCount) {
        Prefs.putInt(mContext, OVERVIEW_OPENED_FROM_HOME_COUNT, openedOverviewFromHomeCount);
    }

    private int getOpenedOverviewCount() {
        return Prefs.getInt(mContext, OVERVIEW_OPENED_COUNT, 0);
    }

    private void setOpenedOverviewCount(int openedOverviewCount) {
        Prefs.putInt(mContext, OVERVIEW_OPENED_COUNT, openedOverviewCount);
    }
}
+0 −2
Original line number Diff line number Diff line
@@ -177,8 +177,6 @@ public class NavigationBarFragment extends Fragment implements Callbacks {

        @Override
        public void onQuickStepStarted() {
            mNavigationBarView.onQuickStepStarted();

            // Use navbar dragging as a signal to hide the rotate button
            setRotateSuggestionButtonState(false);
        }
Loading