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

Commit 08a20282 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

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

parents 0a161786 27599053
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