Merge "Implement swipe up and quick scrub onboarding" into pi-dev
am: 08a2028228
Change-Id: Ie6a41f240dda33edcfa8f5015ae0884ca9701e94
This commit is contained in:
@@ -41,7 +41,12 @@ interface ISystemUiProxy {
|
||||
void setInteractionState(int flags) = 4;
|
||||
|
||||
/**
|
||||
* Notifies SystemUI that split screen has been invoked.
|
||||
*/
|
||||
* Notifies SystemUI that split screen has been invoked.
|
||||
*/
|
||||
void onSplitScreenInvoked() = 5;
|
||||
|
||||
/**
|
||||
* Notifies SystemUI that Overview is shown.
|
||||
*/
|
||||
void onOverviewShown(boolean fromHome) = 6;
|
||||
}
|
||||
|
||||
@@ -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() {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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 {
|
||||
show(R.string.recents_swipe_up_onboarding);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (mHasDismissed) {
|
||||
mNumAppsLaunchedSinceDismiss = numAppsLaunched;
|
||||
} else {
|
||||
Prefs.putInt(mContext, Prefs.Key.NUM_APPS_LAUNCHED, numAppsLaunched);
|
||||
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 {
|
||||
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) {
|
||||
|
||||
if (hasSeenSwipeUpOnboarding() && hasSeenQuickScrubOnboarding()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mOverviewProxyListenerRegistered) {
|
||||
mOverviewProxyService.addCallback(mOverviewProxyListener);
|
||||
mOverviewProxyListenerRegistered = true;
|
||||
}
|
||||
if (!mTaskListenerRegistered) {
|
||||
ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskListener);
|
||||
mTaskListenerRegistered = true;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -259,7 +336,7 @@ public class RecentsOnboarding {
|
||||
private boolean shouldShow() {
|
||||
return SystemProperties.getBoolean("persist.quickstep.onboarding.enabled",
|
||||
!(mContext.getSystemService(UserManager.class)).isDemoUser() &&
|
||||
!ActivityManager.isRunningInTestHarness());
|
||||
!ActivityManager.isRunningInTestHarness());
|
||||
}
|
||||
|
||||
public void hide(boolean animate) {
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -287,12 +287,6 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
|
||||
notifyVerticalChangedListener(mVertical);
|
||||
}
|
||||
|
||||
public void onQuickStepStarted() {
|
||||
if (mRecentsOnboarding != null) {
|
||||
mRecentsOnboarding.onQuickStepStarted();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||
if (mDeadZone.onTouchEvent(event)) {
|
||||
|
||||
@@ -407,6 +407,7 @@ public class QuickStepController implements GestureHelper {
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to send start of quick scrub.", e);
|
||||
}
|
||||
mOverviewEventSender.notifyQuickScrubStarted();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user