Allow Users to migrate their hotseat when returning from AiAi
- If a user has mostly predicted hotseat, show a snack bar. otherwise, show migration option.
- Guard onboarding activity with permission `com.google.android.apps.nexuslauncher.permission.HOTSEAT_EDU`
Bug: 158569583
Test: Manual
Change-Id: Id0c1c812233fcf288a2f49848720199dedd2015d
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
index 00b0951..e49f2ec 100644
--- a/quickstep/AndroidManifest.xml
+++ b/quickstep/AndroidManifest.xml
@@ -22,11 +22,16 @@
xmlns:tools="http://schemas.android.com/tools"
package="com.android.launcher3" >
+ <permission
+ android:name="${packageName}.permission.HOTSEAT_EDU"
+ android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+ android:protectionLevel="signatureOrSystem" />
+
<uses-permission android:name="android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
+ <uses-permission android:name="${packageName}.permission.HOTSEAT_EDU" />
-
<application
android:backupAgent="com.android.launcher3.LauncherBackupAgent"
android:fullBackupOnly="true"
@@ -105,6 +110,18 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
+ <activity
+ android:name=".hybridhotseat.HotseatEduActivity"
+ android:theme="@android:style/Theme.NoDisplay"
+ android:noHistory="true"
+ android:launchMode="singleTask"
+ android:clearTaskOnLaunch="true"
+ android:permission="${packageName}.permission.HOTSEAT_EDU">
+ <intent-filter>
+ <action android:name="com.android.launcher3.action.SHOW_HYBRID_HOTSEAT_EDU"/>
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
</application>
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduActivity.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduActivity.java
new file mode 100644
index 0000000..c968de9
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduActivity.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2020 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.hybridhotseat;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
+import com.android.launcher3.util.ActivityTracker;
+
+/**
+ * Proxy activity to return user to home screen and show halfsheet education
+ */
+public class HotseatEduActivity extends Activity {
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Intent homeIntent = new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_HOME)
+ .setPackage(getPackageName())
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ new HotseatActivityTracker<>().addToIntent(homeIntent);
+ startActivity(homeIntent);
+ finish();
+ }
+
+ static class HotseatActivityTracker<T extends QuickstepLauncher> implements
+ ActivityTracker.SchedulerCallback {
+
+ @Override
+ public boolean init(BaseActivity activity, boolean alreadyOnHome) {
+ QuickstepLauncher launcher = (QuickstepLauncher) activity;
+ if (launcher != null && launcher.getHotseatPredictionController() != null) {
+ launcher.getHotseatPredictionController().showEdu();
+ }
+ return false;
+ }
+
+ }
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index 296f1dc..698e208 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -17,6 +17,7 @@
import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_GRID;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.hybridhotseat.HotseatEduController.getSettingsIntent;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_RANKED;
@@ -153,35 +154,35 @@
* Shows appropriate hotseat education based on prediction enabled and migration states.
*/
public void showEdu() {
- if (mComponentKeyMappers.isEmpty()) {
- // launcher has empty predictions set
- Snackbar.show(mLauncher, R.string.hotsaet_tip_prediction_disabled,
- R.string.hotseat_prediction_settings, null,
- () -> mLauncher.startActivity(getSettingsIntent()));
- } else if (isEduSeen()) {
- // user has already went through education
- new ArrowTipView(mLauncher).show(
- mLauncher.getString(R.string.hotsaet_tip_prediction_enabled),
- mHotseat.getTop());
- } else {
- HotseatEduController eduController = new HotseatEduController(mLauncher, mRestoreHelper,
- this::createPredictor);
- eduController.setPredictedApps(mapToWorkspaceItemInfo(mComponentKeyMappers));
- eduController.showEdu();
- }
+ mLauncher.getStateManager().goToState(NORMAL, true, () -> {
+ if (mComponentKeyMappers.isEmpty()) {
+ // launcher has empty predictions set
+ Snackbar.show(mLauncher, R.string.hotsaet_tip_prediction_disabled,
+ R.string.hotseat_prediction_settings, null,
+ () -> mLauncher.startActivity(getSettingsIntent()));
+ } else if (isEduSeen() || getPredictedIcons().size() >= (mHotSeatItemsCount + 1) / 2) {
+ showDiscoveryTip();
+ } else {
+ HotseatEduController eduController = new HotseatEduController(mLauncher,
+ mRestoreHelper,
+ this::createPredictor);
+ eduController.setPredictedApps(mapToWorkspaceItemInfo(mComponentKeyMappers));
+ eduController.showEdu();
+ }
+ });
}
/**
* Shows educational tip for hotseat if user does not go through Tips app.
*/
- public void showDiscoveryTip() {
- if (getPredictedIcons().size() == mHotSeatItemsCount) {
+ private void showDiscoveryTip() {
+ if (getPredictedIcons().isEmpty()) {
new ArrowTipView(mLauncher).show(
mLauncher.getString(R.string.hotseat_tip_no_empty_slots), mHotseat.getTop());
} else {
Snackbar.show(mLauncher, R.string.hotseat_tip_gaps_filled,
R.string.hotseat_prediction_settings, null,
- () -> mLauncher.startActivity(HotseatEduController.getSettingsIntent()));
+ () -> mLauncher.startActivity(getSettingsIntent()));
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 0e690eb..e946942 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -45,7 +45,6 @@
import com.android.launcher3.appprediction.PredictionUiStateManager;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.Folder;
-import com.android.launcher3.hybridhotseat.HotseatEduController;
import com.android.launcher3.hybridhotseat.HotseatPredictionController;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.model.data.AppInfo;
@@ -108,20 +107,6 @@
}
@Override
- protected void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
- if (HotseatEduController.HOTSEAT_EDU_ACTION.equals(intent.getAction())
- && mHotseatPredictionController != null) {
- boolean alreadyOnHome = hasWindowFocus() && ((intent.getFlags()
- & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)
- != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
- getStateManager().goToState(NORMAL, alreadyOnHome, () -> {
- mHotseatPredictionController.showEdu();
- });
- }
- }
-
- @Override
protected void logAppLaunch(ItemInfo info, InstanceId instanceId) {
super.logAppLaunch(info, instanceId);
if (mHotseatPredictionController != null) {
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 1b82826..769d298 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -87,7 +87,7 @@
<string name="hotseat_tip_gaps_filled">App suggestions added to empty space</string>
<!-- tip shown when user migrates and predictions are enabled in hotseat -->
<string name="hotsaet_tip_prediction_enabled">App suggestions enabled</string>
- <!-- tip shown when hotseat edu is requested while predicions are disabled -->
+ <!-- tip shown when hotseat edu is requested while predictions are disabled -->
<string name="hotsaet_tip_prediction_disabled">App suggestions are disabled</string>
<!-- content description for hotseat items -->
diff --git a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
index 1abe903..2f03d76 100644
--- a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
+++ b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
@@ -115,7 +115,7 @@
HotseatPredictionController client = mLauncher.getHotseatPredictionController();
if (mFromAllApps && finalState == NORMAL && client.hasPredictions()) {
if (incrementEventCount(HOTSEAT_DISCOVERY_TIP_COUNT)) {
- client.showDiscoveryTip();
+ client.showEdu();
stateManager.removeStateListener(this);
}
}