1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.quickstep.util; 17 18 import static com.android.launcher3.AbstractFloatingView.TYPE_ALL_APPS_EDU; 19 import static com.android.launcher3.AbstractFloatingView.getOpenView; 20 import static com.android.launcher3.LauncherState.ALL_APPS; 21 import static com.android.launcher3.LauncherState.HINT_STATE; 22 import static com.android.launcher3.LauncherState.NORMAL; 23 import static com.android.launcher3.LauncherState.OVERVIEW; 24 import static com.android.launcher3.util.NavigationMode.NO_BUTTON; 25 import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT; 26 import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_COUNT; 27 import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN; 28 import static com.android.launcher3.util.OnboardingPrefs.HOTSEAT_DISCOVERY_TIP_COUNT; 29 30 import com.android.launcher3.Launcher; 31 import com.android.launcher3.LauncherPrefs; 32 import com.android.launcher3.LauncherState; 33 import com.android.launcher3.Utilities; 34 import com.android.launcher3.Workspace; 35 import com.android.launcher3.appprediction.AppsDividerView; 36 import com.android.launcher3.hybridhotseat.HotseatPredictionController; 37 import com.android.launcher3.statemanager.StateManager; 38 import com.android.launcher3.statemanager.StateManager.StateListener; 39 import com.android.launcher3.uioverrides.QuickstepLauncher; 40 import com.android.launcher3.util.DisplayController; 41 import com.android.quickstep.views.AllAppsEduView; 42 43 /** 44 * Class to setup onboarding behavior for quickstep launcher 45 */ 46 public class QuickstepOnboardingPrefs { 47 48 /** 49 * Sets up the initial onboarding behavior for the launcher 50 */ setup(QuickstepLauncher launcher)51 public static void setup(QuickstepLauncher launcher) { 52 StateManager<LauncherState, Launcher> stateManager = launcher.getStateManager(); 53 if (!HOME_BOUNCE_SEEN.get(launcher)) { 54 stateManager.addStateListener(new StateListener<LauncherState>() { 55 @Override 56 public void onStateTransitionComplete(LauncherState finalState) { 57 boolean swipeUpEnabled = 58 DisplayController.getNavigationMode(launcher).hasGestures; 59 LauncherState prevState = stateManager.getLastState(); 60 61 if (((swipeUpEnabled && finalState == OVERVIEW) || (!swipeUpEnabled 62 && finalState == ALL_APPS && prevState == NORMAL) || 63 HOME_BOUNCE_COUNT.hasReachedMax(launcher))) { 64 LauncherPrefs.get(launcher).put(HOME_BOUNCE_SEEN, true); 65 stateManager.removeStateListener(this); 66 } 67 } 68 }); 69 } 70 71 if (!Utilities.isRunningInTestHarness() 72 && !HOTSEAT_DISCOVERY_TIP_COUNT.hasReachedMax(launcher)) { 73 stateManager.addStateListener(new StateListener<LauncherState>() { 74 boolean mFromAllApps = false; 75 76 @Override 77 public void onStateTransitionStart(LauncherState toState) { 78 mFromAllApps = launcher.getStateManager().getCurrentStableState() == ALL_APPS; 79 } 80 81 @Override 82 public void onStateTransitionComplete(LauncherState finalState) { 83 HotseatPredictionController client = launcher.getHotseatPredictionController(); 84 if (mFromAllApps && finalState == NORMAL && client.hasPredictions()) { 85 if (!launcher.getDeviceProfile().isTablet 86 && HOTSEAT_DISCOVERY_TIP_COUNT.increment(launcher)) { 87 client.showEdu(); 88 stateManager.removeStateListener(this); 89 } 90 } 91 } 92 }); 93 } 94 95 if (DisplayController.getNavigationMode(launcher) == NO_BUTTON) { 96 stateManager.addStateListener(new StateListener<LauncherState>() { 97 private static final int MAX_NUM_SWIPES_TO_TRIGGER_EDU = 3; 98 99 // Counts the number of consecutive swipes on nav bar without moving screens. 100 private int mCount = 0; 101 private boolean mShouldIncreaseCount; 102 103 @Override 104 public void onStateTransitionStart(LauncherState toState) { 105 if (toState == NORMAL) { 106 return; 107 } 108 mShouldIncreaseCount = toState == HINT_STATE 109 && launcher.getWorkspace().getNextPage() == Workspace.DEFAULT_PAGE; 110 } 111 112 @Override 113 public void onStateTransitionComplete(LauncherState finalState) { 114 if (finalState == NORMAL) { 115 if (mCount >= MAX_NUM_SWIPES_TO_TRIGGER_EDU) { 116 if (getOpenView(launcher, TYPE_ALL_APPS_EDU) == null) { 117 AllAppsEduView.show(launcher); 118 } 119 mCount = 0; 120 } 121 return; 122 } 123 124 if (mShouldIncreaseCount && finalState == HINT_STATE) { 125 mCount++; 126 } else { 127 mCount = 0; 128 } 129 130 if (finalState == ALL_APPS) { 131 AllAppsEduView view = getOpenView(launcher, TYPE_ALL_APPS_EDU); 132 if (view != null) { 133 view.close(false); 134 } 135 } 136 } 137 }); 138 } 139 140 if (!Utilities.isRunningInTestHarness()) { 141 launcher.getStateManager().addStateListener(new StateListener<LauncherState>() { 142 @Override 143 public void onStateTransitionComplete(LauncherState finalState) { 144 if (finalState == ALL_APPS) { 145 ALL_APPS_VISITED_COUNT.increment(launcher); 146 } 147 launcher.getAppsView().getFloatingHeaderView() 148 .findFixedRowByType(AppsDividerView.class) 149 .setShowAllAppsLabel(!ALL_APPS_VISITED_COUNT.hasReachedMax(launcher)); 150 } 151 }); 152 } 153 } 154 } 155