Merge "Gesture-excluding activities also exclude Assistant gesture." into ub-launcher3-rvc-dev
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
index 7c4f3ec..f1ce72e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
@@ -52,6 +52,7 @@
private final Launcher mLauncher;
private final Hotseat mHotseat;
+ private final HotseatRestoreHelper mRestoreHelper;
private List<WorkspaceItemInfo> mPredictedApps;
private HotseatEduDialog mActiveDialog;
@@ -59,9 +60,10 @@
private IntArray mNewScreens = null;
private Runnable mOnOnboardingComplete;
- HotseatEduController(Launcher launcher, Runnable runnable) {
+ HotseatEduController(Launcher launcher, HotseatRestoreHelper restoreHelper, Runnable runnable) {
mLauncher = launcher;
mHotseat = launcher.getHotseat();
+ mRestoreHelper = restoreHelper;
mOnOnboardingComplete = runnable;
}
@@ -69,11 +71,14 @@
* Checks what type of migration should be used and migrates hotseat
*/
void migrate() {
+ mRestoreHelper.createBackup();
if (FeatureFlags.HOTSEAT_MIGRATE_TO_FOLDER.get()) {
migrateToFolder();
} else {
migrateHotseatWhole();
}
+ Snackbar.show(mLauncher, R.string.hotsaet_tip_prediction_enabled, R.string.hotseat_turn_off,
+ null, () -> mLauncher.startActivity(new Intent(SETTINGS_ACTION)));
}
/**
@@ -84,7 +89,6 @@
*/
private int migrateToFolder() {
ArrayDeque<FolderInfo> folders = new ArrayDeque<>();
-
ArrayList<WorkspaceItemInfo> putIntoFolder = new ArrayList<>();
//separate folders and items that can get in folders
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
index fa137f8..12d537c 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
@@ -16,7 +16,8 @@
package com.android.launcher3.hybridhotseat;
import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.HYBRID_HOTSEAT_CANCELED;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType
+ .HYBRID_HOTSEAT_CANCELED;
import android.animation.PropertyValuesHolder;
import android.content.Context;
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 05bcb57..725f516 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
@@ -92,6 +92,8 @@
private Launcher mLauncher;
private final Hotseat mHotseat;
+ private final HotseatRestoreHelper mRestoreHelper;
+
private List<ComponentKeyMapper> mComponentKeyMappers = new ArrayList<>();
private DynamicItemCache mDynamicItemCache;
@@ -129,6 +131,7 @@
mHotSeatItemsCount = mLauncher.getDeviceProfile().inv.numHotseatIcons;
launcher.getDeviceProfile().inv.addOnChangeListener(this);
mHotseat.addOnAttachStateChangeListener(this);
+ mRestoreHelper = new HotseatRestoreHelper(mLauncher);
if (mHotseat.isAttachedToWindow()) {
onViewAttachedToWindow(mHotseat);
}
@@ -297,7 +300,8 @@
});
setPauseUIUpdate(false);
if (!isEduSeen()) {
- mHotseatEduController = new HotseatEduController(mLauncher, this::createPredictor);
+ mHotseatEduController = new HotseatEduController(mLauncher, mRestoreHelper,
+ this::createPredictor);
}
}
@@ -320,9 +324,11 @@
updateDependencies();
bindItems(items, false, null);
}
-
private void setPredictedApps(List<AppTarget> appTargets) {
mComponentKeyMappers.clear();
+ if (appTargets.isEmpty() && mRestoreHelper.shouldRestoreToBackup()) {
+ mRestoreHelper.restoreBackup();
+ }
StringBuilder predictionLog = new StringBuilder("predictedApps: [\n");
ArrayList<ComponentKey> componentKeys = new ArrayList<>();
for (AppTarget appTarget : appTargets) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java
new file mode 100644
index 0000000..c95ff7a
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java
@@ -0,0 +1,100 @@
+/*
+ * 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 static com.android.launcher3.LauncherSettings.Favorites.HYBRID_HOTSEAT_BACKUP_TABLE;
+import static com.android.launcher3.provider.LauncherDbUtils.tableExists;
+
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.model.GridBackupTable;
+import com.android.launcher3.provider.LauncherDbUtils;
+
+/**
+ * A helper class to manage migration revert restoration for hybrid hotseat
+ */
+public class HotseatRestoreHelper {
+ private final Launcher mLauncher;
+ private boolean mBackupExists;
+
+ HotseatRestoreHelper(Launcher context) {
+ mLauncher = context;
+ setupBackupTable();
+ }
+
+ /**
+ * Creates a snapshot backup of Favorite table for future restoration use.
+ */
+ public synchronized void createBackup() {
+ try (LauncherDbUtils.SQLiteTransaction transaction = (LauncherDbUtils.SQLiteTransaction)
+ LauncherSettings.Settings.call(
+ mLauncher.getContentResolver(),
+ LauncherSettings.Settings.METHOD_NEW_TRANSACTION)
+ .getBinder(LauncherSettings.Settings.EXTRA_VALUE)) {
+ InvariantDeviceProfile idp = mLauncher.getDeviceProfile().inv;
+ GridBackupTable backupTable = new GridBackupTable(mLauncher,
+ transaction.getDb(), idp.numHotseatIcons, idp.numColumns,
+ idp.numRows);
+ backupTable.createCustomBackupTable(HYBRID_HOTSEAT_BACKUP_TABLE);
+ transaction.commit();
+ LauncherSettings.Settings.call(mLauncher.getContentResolver(),
+ LauncherSettings.Settings.METHOD_REFRESH_HOTSEAT_RESTORE_TABLE);
+ mBackupExists = true;
+ }
+ }
+
+ /**
+ * Finds and restores a previously saved snapshow of Favorites table
+ */
+ public void restoreBackup() {
+ try (LauncherDbUtils.SQLiteTransaction transaction = (LauncherDbUtils.SQLiteTransaction)
+ LauncherSettings.Settings.call(
+ mLauncher.getContentResolver(),
+ LauncherSettings.Settings.METHOD_NEW_TRANSACTION)
+ .getBinder(LauncherSettings.Settings.EXTRA_VALUE)) {
+ if (!tableExists(transaction.getDb(), HYBRID_HOTSEAT_BACKUP_TABLE)) {
+ mBackupExists = false;
+ return;
+ }
+ InvariantDeviceProfile idp = mLauncher.getDeviceProfile().inv;
+ GridBackupTable backupTable = new GridBackupTable(mLauncher,
+ transaction.getDb(), idp.numHotseatIcons, idp.numColumns,
+ idp.numRows);
+ backupTable.restoreFromCustomBackupTable(HYBRID_HOTSEAT_BACKUP_TABLE, true);
+ transaction.commit();
+ mBackupExists = false;
+ mLauncher.getModel().forceReload();
+ }
+ }
+
+ /**
+ * Returns if prediction controller should attempt restoring a backup
+ */
+ public synchronized boolean shouldRestoreToBackup() {
+ return mBackupExists;
+ }
+
+ private synchronized void setupBackupTable() {
+ try (LauncherDbUtils.SQLiteTransaction transaction = (LauncherDbUtils.SQLiteTransaction)
+ LauncherSettings.Settings.call(
+ mLauncher.getContentResolver(),
+ LauncherSettings.Settings.METHOD_NEW_TRANSACTION)
+ .getBinder(LauncherSettings.Settings.EXTRA_VALUE)) {
+ mBackupExists = tableExists(transaction.getDb(), HYBRID_HOTSEAT_BACKUP_TABLE);
+ }
+ }
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
index c18a0fd..e5782e7 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -33,11 +33,11 @@
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.quickstep.util.RemoteAnimationProvider;
+import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.util.TransformParams;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
/**
* Provider for the atomic (for 3-button mode) remote window animation from the app to the overview.
@@ -132,8 +132,7 @@
TransformParams params = new TransformParams()
.setTargetSet(targets)
- .setSyncTransactionApplier(
- new SyncRtSurfaceTransactionApplierCompat(mActivity.getRootView()));
+ .setSyncTransactionApplier(new SurfaceTransactionApplier(mActivity.getRootView()));
AnimatedFloat recentsAlpha = new AnimatedFloat(() -> { });
params.setBaseBuilderProxy((builder, app, p)
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
index 045f459..6cbe794 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -40,13 +40,14 @@
import com.android.quickstep.RecentsAnimationCallbacks.RecentsAnimationListener;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.ActivityInitListener;
+import com.android.quickstep.util.RectFSpringAnim;
+import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.TransformParams;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
import java.util.ArrayList;
import java.util.function.Consumer;
@@ -114,10 +115,10 @@
public abstract Intent getLaunchIntent();
protected void linkRecentsViewScroll() {
- SyncRtSurfaceTransactionApplierCompat.create(mRecentsView, applier -> {
+ SurfaceTransactionApplier.create(mRecentsView, applier -> {
mTransformParams.setSyncTransactionApplier(applier);
runOnRecentsAnimationStart(() ->
- mRecentsAnimationTargets.addDependentTransactionApplier(applier));
+ mRecentsAnimationTargets.addReleaseCheck(applier));
});
mRecentsView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
@@ -365,6 +366,17 @@
}
}
+ @Override
+ protected RectFSpringAnim createWindowAnimationToHome(float startProgress,
+ HomeAnimationFactory homeAnimationFactory) {
+ RectFSpringAnim anim =
+ super.createWindowAnimationToHome(startProgress, homeAnimationFactory);
+ if (mRecentsAnimationTargets != null) {
+ mRecentsAnimationTargets.addReleaseCheck(anim);
+ }
+ return anim;
+ }
+
public interface Factory {
BaseSwipeUpHandler newHandler(
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskShortcutFactory.java
index 021d39d..cdaa655 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskShortcutFactory.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskShortcutFactory.java
@@ -18,6 +18,8 @@
import static android.view.Display.DEFAULT_DISPLAY;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_FREE_FORM_TAP;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_SPLIT_SCREEN_TAP;
import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
import android.app.Activity;
@@ -35,6 +37,7 @@
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
+import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
import com.android.launcher3.model.WellbeingModel;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.SystemShortcut;
@@ -83,10 +86,12 @@
private final int mIconRes;
private final int mTextRes;
+ private final LauncherEvent mLauncherEvent;
- MultiWindowFactory(int iconRes, int textRes) {
+ MultiWindowFactory(int iconRes, int textRes, LauncherEvent launcherEvent) {
mIconRes = iconRes;
mTextRes = textRes;
+ mLauncherEvent = launcherEvent;
}
protected abstract boolean isAvailable(BaseDraggingActivity activity, int displayId);
@@ -102,7 +107,8 @@
if (!isAvailable(activity, task.key.displayId)) {
return null;
}
- return new MultiWindowSystemShortcut(mIconRes, mTextRes, activity, taskView, this);
+ return new MultiWindowSystemShortcut(mIconRes, mTextRes, activity, taskView, this,
+ mLauncherEvent);
}
}
@@ -114,11 +120,12 @@
private final TaskThumbnailView mThumbnailView;
private final TaskView mTaskView;
private final MultiWindowFactory mFactory;
+ private final LauncherEvent mLauncherEvent;
- public MultiWindowSystemShortcut(int iconRes, int textRes,
- BaseDraggingActivity activity, TaskView taskView, MultiWindowFactory factory) {
+ public MultiWindowSystemShortcut(int iconRes, int textRes, BaseDraggingActivity activity,
+ TaskView taskView, MultiWindowFactory factory, LauncherEvent launcherEvent) {
super(iconRes, textRes, activity, dummyInfo(taskView));
-
+ mLauncherEvent = launcherEvent;
mHandler = new Handler(Looper.getMainLooper());
mTaskView = taskView;
mRecentsView = activity.getOverviewPanel();
@@ -203,12 +210,13 @@
WindowManagerWrapper.getInstance().overridePendingAppTransitionMultiThumbFuture(
future, animStartedListener, mHandler, true /* scaleUp */,
taskKey.displayId);
+ mTarget.getStatsLogManager().log(mLauncherEvent, mTaskView.buildProto());
}
}
}
- TaskShortcutFactory SPLIT_SCREEN = new MultiWindowFactory(
- R.drawable.ic_split_screen, R.string.recent_task_option_split_screen) {
+ TaskShortcutFactory SPLIT_SCREEN = new MultiWindowFactory(R.drawable.ic_split_screen,
+ R.string.recent_task_option_split_screen, LAUNCHER_SYSTEM_SHORTCUT_SPLIT_SCREEN_TAP) {
@Override
protected boolean isAvailable(BaseDraggingActivity activity, int displayId) {
@@ -241,8 +249,8 @@
}
};
- TaskShortcutFactory FREE_FORM = new MultiWindowFactory(
- R.drawable.ic_split_screen, R.string.recent_task_option_freeform) {
+ TaskShortcutFactory FREE_FORM = new MultiWindowFactory(R.drawable.ic_split_screen,
+ R.string.recent_task_option_freeform, LAUNCHER_SYSTEM_SHORTCUT_FREE_FORM_TAP) {
@Override
protected boolean isAvailable(BaseDraggingActivity activity, int displayId) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
index c68d6e2..e2e25f3 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
@@ -42,6 +42,7 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.util.DefaultDisplay;
+import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.util.TransformParams;
import com.android.quickstep.views.RecentsView;
@@ -49,7 +50,6 @@
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
/**
* Utility class for helpful methods related to {@link TaskView} objects and their tasks.
@@ -128,11 +128,10 @@
RemoteAnimationTargetCompat[] wallpaperTargets, DepthController depthController,
PendingAnimation out) {
- SyncRtSurfaceTransactionApplierCompat applier =
- new SyncRtSurfaceTransactionApplierCompat(v);
+ SurfaceTransactionApplier applier = new SurfaceTransactionApplier(v);
final RemoteAnimationTargets targets =
new RemoteAnimationTargets(appTargets, wallpaperTargets, MODE_OPENING);
- targets.addDependentTransactionApplier(applier);
+ targets.addReleaseCheck(applier);
TransformParams params = new TransformParams()
.setSyncTransactionApplier(applier)
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index 412a05a..6f596e9 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -135,10 +135,10 @@
private static final int MAX_BACK_NOTIFICATION_COUNT = 3;
/**
- * System Action ID to show all apps. This ID should follow the ones in
- * com.android.systemui.accessibility.SystemActions.
+ * System Action ID to show all apps.
+ * TODO: Use AccessibilityService's corresponding global action constant in S
*/
- private static final int SYSTEM_ACTION_ID_ALL_APPS = 100;
+ private static final int SYSTEM_ACTION_ID_ALL_APPS = 14;
private int mBackGestureNotificationCounter = -1;
@Nullable
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java
index 8a6c4a1..e5d2c53 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java
@@ -29,6 +29,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.FlingSpringAnim;
import com.android.launcher3.util.DynamicResource;
+import com.android.quickstep.RemoteAnimationTargets.ReleaseCheck;
import com.android.systemui.plugins.ResourceProvider;
import java.util.ArrayList;
@@ -39,7 +40,7 @@
* Applies spring forces to animate from a starting rect to a target rect,
* while providing update callbacks to the caller.
*/
-public class RectFSpringAnim {
+public class RectFSpringAnim extends ReleaseCheck {
private static final FloatPropertyCompat<RectFSpringAnim> RECT_CENTER_X =
new FloatPropertyCompat<RectFSpringAnim>("rectCenterXSpring") {
@@ -116,6 +117,7 @@
ResourceProvider rp = DynamicResource.provider(context);
mMinVisChange = rp.getDimension(R.dimen.swipe_up_fling_min_visible_change);
mYOvershoot = rp.getDimension(R.dimen.swipe_up_y_overshoot);
+ setCanRelease(true);
}
public void onTargetPositionChanged() {
@@ -190,10 +192,12 @@
maybeOnEnd();
});
+ setCanRelease(false);
+ mAnimsStarted = true;
+
mRectXAnim.start();
mRectYAnim.start();
mRectScaleAnim.start();
- mAnimsStarted = true;
for (Animator.AnimatorListener animatorListener : mAnimatorListeners) {
animatorListener.onAnimationStart(null);
}
@@ -245,6 +249,7 @@
private void maybeOnEnd() {
if (mAnimsStarted && isEnded()) {
mAnimsStarted = false;
+ setCanRelease(true);
for (Animator.AnimatorListener animatorListener : mAnimatorListeners) {
animatorListener.onAnimationEnd(null);
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SurfaceTransactionApplier.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SurfaceTransactionApplier.java
new file mode 100644
index 0000000..0a3e3ec
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SurfaceTransactionApplier.java
@@ -0,0 +1,136 @@
+/*
+ * 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.quickstep.util;
+
+import static com.android.systemui.shared.system.TransactionCompat.deferTransactionUntil;
+import static com.android.systemui.shared.system.TransactionCompat.setEarlyWakeup;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Message;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
+import android.view.View;
+
+import com.android.quickstep.RemoteAnimationTargets.ReleaseCheck;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
+import com.android.systemui.shared.system.ViewRootImplCompat;
+
+import java.util.function.Consumer;
+
+
+/**
+ * Helper class to apply surface transactions in sync with RenderThread similar to
+ * android.view.SyncRtSurfaceTransactionApplier
+ * with some Launcher specific utility methods
+ */
+@TargetApi(Build.VERSION_CODES.R)
+public class SurfaceTransactionApplier extends ReleaseCheck {
+
+ private static final int MSG_UPDATE_SEQUENCE_NUMBER = 0;
+
+ private final SurfaceControl mBarrierSurfaceControl;
+ private final ViewRootImplCompat mTargetViewRootImpl;
+ private final Handler mApplyHandler;
+
+ private int mLastSequenceNumber = 0;
+
+ /**
+ * @param targetView The view in the surface that acts as synchronization anchor.
+ */
+ public SurfaceTransactionApplier(View targetView) {
+ mTargetViewRootImpl = new ViewRootImplCompat(targetView);
+ mBarrierSurfaceControl = mTargetViewRootImpl.getRenderSurfaceControl();
+ mApplyHandler = new Handler(this::onApplyMessage);
+ }
+
+ protected boolean onApplyMessage(Message msg) {
+ if (msg.what == MSG_UPDATE_SEQUENCE_NUMBER) {
+ setCanRelease(msg.arg1 == mLastSequenceNumber);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Schedules applying surface parameters on the next frame.
+ *
+ * @param params The surface parameters to apply. DO NOT MODIFY the list after passing into
+ * this method to avoid synchronization issues.
+ */
+ public void scheduleApply(final SurfaceParams... params) {
+ View view = mTargetViewRootImpl.getView();
+ if (view == null) {
+ return;
+ }
+
+ mLastSequenceNumber++;
+ final int toApplySeqNo = mLastSequenceNumber;
+ setCanRelease(false);
+ mTargetViewRootImpl.registerRtFrameCallback(frame -> {
+ if (mBarrierSurfaceControl == null || !mBarrierSurfaceControl.isValid()) {
+ Message.obtain(mApplyHandler, MSG_UPDATE_SEQUENCE_NUMBER, toApplySeqNo, 0)
+ .sendToTarget();
+ return;
+ }
+ Transaction t = new Transaction();
+ for (int i = params.length - 1; i >= 0; i--) {
+ SurfaceParams surfaceParams = params[i];
+ if (surfaceParams.surface.isValid()) {
+ deferTransactionUntil(t, surfaceParams.surface, mBarrierSurfaceControl, frame);
+ surfaceParams.applyTo(t);
+ }
+ }
+ setEarlyWakeup(t);
+ t.apply();
+ Message.obtain(mApplyHandler, MSG_UPDATE_SEQUENCE_NUMBER, toApplySeqNo, 0)
+ .sendToTarget();
+ });
+
+ // Make sure a frame gets scheduled.
+ view.invalidate();
+ }
+
+ /**
+ * Creates an instance of SyncRtSurfaceTransactionApplier, deferring until the target view is
+ * attached if necessary.
+ */
+ public static void create(
+ final View targetView, final Consumer<SurfaceTransactionApplier> callback) {
+ if (targetView == null) {
+ // No target view, no applier
+ callback.accept(null);
+ } else if (new ViewRootImplCompat(targetView).isValid()) {
+ // Already attached, we're good to go
+ callback.accept(new SurfaceTransactionApplier(targetView));
+ } else {
+ // Haven't been attached before we can get the view root
+ targetView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ targetView.removeOnAttachStateChangeListener(this);
+ callback.accept(new SurfaceTransactionApplier(targetView));
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ // Do nothing
+ }
+ });
+ }
+ }
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TransformParams.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TransformParams.java
index 9bb508e..7a62e83 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TransformParams.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TransformParams.java
@@ -57,7 +57,7 @@
private float mTargetAlpha;
private float mCornerRadius;
private RemoteAnimationTargets mTargetSet;
- private SyncRtSurfaceTransactionApplierCompat mSyncTransactionApplier;
+ private SurfaceTransactionApplier mSyncTransactionApplier;
private BuilderProxy mHomeBuilderProxy = BuilderProxy.ALWAYS_VISIBLE;
private BuilderProxy mBaseBuilderProxy = BuilderProxy.ALWAYS_VISIBLE;
@@ -112,7 +112,7 @@
* are computed based on these TransformParams.
*/
public TransformParams setSyncTransactionApplier(
- SyncRtSurfaceTransactionApplierCompat applier) {
+ SurfaceTransactionApplier applier) {
mSyncTransactionApplier = applier;
return this;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index 5e90e0b..f27bedb 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -127,6 +127,7 @@
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.quickstep.util.SplitScreenBounds;
+import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.TransformParams;
import com.android.systemui.plugins.ResourceProvider;
import com.android.systemui.shared.recents.IPinnedStackAnimationListener;
@@ -135,7 +136,6 @@
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.LauncherEventUtil;
import com.android.systemui.shared.system.PackageManagerWrapper;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
import com.android.systemui.shared.system.TaskStackChangeListener;
import java.util.ArrayList;
@@ -211,7 +211,7 @@
protected final BaseActivityInterface mSizeStrategy;
protected RecentsAnimationController mRecentsAnimationController;
protected RecentsAnimationTargets mRecentsAnimationTargets;
- protected SyncRtSurfaceTransactionApplierCompat mSyncTransactionApplier;
+ protected SurfaceTransactionApplier mSyncTransactionApplier;
protected int mTaskWidth;
protected int mTaskHeight;
protected boolean mEnableDrawingLiveTile = false;
@@ -502,7 +502,7 @@
mModel.getThumbnailCache().getHighResLoadingState().addCallback(this);
mActivity.addMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
- mSyncTransactionApplier = new SyncRtSurfaceTransactionApplierCompat(this);
+ mSyncTransactionApplier = new SurfaceTransactionApplier(this);
RecentsModel.INSTANCE.get(getContext()).addThumbnailChangeListener(this);
mIdp.addOnChangeListener(this);
mIPinnedStackAnimationListener.setActivity(mActivity);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
index 6b759ba..af9d7f7 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
@@ -30,6 +30,7 @@
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP;
import android.animation.Animator;
@@ -222,8 +223,8 @@
setOutlineProvider(mOutlineProvider);
}
- /* Builds proto for logging */
- protected LauncherAtom.ItemInfo buildProto() {
+ /** Builds proto for logging */
+ public LauncherAtom.ItemInfo buildProto() {
ComponentKey componentKey = TaskUtils.getLaunchComponentKeyForTask(getTask().key);
LauncherAtom.ItemInfo.Builder itemBuilder = LauncherAtom.ItemInfo.newBuilder();
itemBuilder.setIsWork(componentKey.user != Process.myUserHandle());
@@ -424,6 +425,7 @@
private boolean showTaskMenu(int action) {
getRecentsView().snapToPage(getRecentsView().indexOfChild(this));
mMenuView = TaskMenuView.showForTask(this);
+ mActivity.getStatsLogManager().log(LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS, buildProto());
UserEventDispatcher.newInstance(getContext()).logActionOnItem(action, Direction.NONE,
LauncherLogProto.ItemType.TASK_ICON);
if (mMenuView != null) {
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 77345a0..35ff792 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -83,6 +83,8 @@
<string name="hotseat_tip_no_empty_slots">Drag apps off the bottom row to get app suggestions</string>
<!-- tip shown if user declines migration and has some open spots for prediction -->
<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>
<!-- content description for hotseat items -->
<string name="hotseat_prediction_content_description">Predicted app: <xliff:g id="title" example="Chrome">%1$s</xliff:g></string>
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index 25c07f1..fe7b946 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -82,6 +82,7 @@
import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.quickstep.util.RemoteAnimationProvider;
import com.android.quickstep.util.StaggeredWorkspaceAnim;
+import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.systemui.shared.system.ActivityCompat;
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.QuickStepContract;
@@ -89,7 +90,6 @@
import com.android.systemui.shared.system.RemoteAnimationDefinitionCompat;
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
import com.android.systemui.shared.system.WindowManagerWrapper;
@@ -455,9 +455,9 @@
RemoteAnimationTargets openingTargets = new RemoteAnimationTargets(appTargets,
wallpaperTargets, MODE_OPENING);
- SyncRtSurfaceTransactionApplierCompat surfaceApplier =
- new SyncRtSurfaceTransactionApplierCompat(floatingView);
- openingTargets.addDependentTransactionApplier(surfaceApplier);
+ SurfaceTransactionApplier surfaceApplier =
+ new SurfaceTransactionApplier(floatingView);
+ openingTargets.addReleaseCheck(surfaceApplier);
// Scale the app icon to take up the entire screen. This simplifies the math when
// animating the app window position / scale.
@@ -712,8 +712,7 @@
*/
private Animator getUnlockWindowAnimator(RemoteAnimationTargetCompat[] appTargets,
RemoteAnimationTargetCompat[] wallpaperTargets) {
- SyncRtSurfaceTransactionApplierCompat surfaceApplier =
- new SyncRtSurfaceTransactionApplierCompat(mDragLayer);
+ SurfaceTransactionApplier surfaceApplier = new SurfaceTransactionApplier(mDragLayer);
ValueAnimator unlockAnimator = ValueAnimator.ofFloat(0, 1);
unlockAnimator.setDuration(CLOSING_TRANSITION_DURATION_MS);
float cornerRadius = mDeviceProfile.isMultiWindowMode ? 0 :
@@ -741,8 +740,7 @@
*/
private Animator getClosingWindowAnimators(RemoteAnimationTargetCompat[] appTargets,
RemoteAnimationTargetCompat[] wallpaperTargets) {
- SyncRtSurfaceTransactionApplierCompat surfaceApplier =
- new SyncRtSurfaceTransactionApplierCompat(mDragLayer);
+ SurfaceTransactionApplier surfaceApplier = new SurfaceTransactionApplier(mDragLayer);
Matrix matrix = new Matrix();
Point tmpPos = new Point();
ValueAnimator closingAnimator = ValueAnimator.ofFloat(0, 1);
diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
index a976126..c3ff32f 100644
--- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
+++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
@@ -36,6 +36,7 @@
import com.android.launcher3.R;
import com.android.launcher3.ResourceUtils;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.DefaultDisplay;
import java.io.PrintWriter;
@@ -246,6 +247,10 @@
}
boolean touchInValidSwipeRegions(float x, float y) {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_SWIPE_TO_HOME, "touchInValidSwipeRegions " + x + "," + y + " in "
+ + mLastRectTouched);
+ }
if (mLastRectTouched != null) {
return mLastRectTouched.contains(x, y);
}
diff --git a/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java b/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java
index f90df45..ab5e3ba 100644
--- a/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java
+++ b/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java
@@ -16,19 +16,16 @@
package com.android.quickstep;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
-import java.util.ArrayDeque;
import java.util.ArrayList;
-import java.util.Queue;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
* Holds a collection of RemoteAnimationTargets, filtered by different properties.
*/
public class RemoteAnimationTargets {
- private final Queue<SyncRtSurfaceTransactionApplierCompat> mDependentTransactionAppliers =
- new ArrayDeque<>(1);
+ private final CopyOnWriteArrayList<ReleaseCheck> mReleaseChecks = new CopyOnWriteArrayList<>();
public final RemoteAnimationTargetCompat[] unfilteredApps;
public final RemoteAnimationTargetCompat[] apps;
@@ -36,6 +33,8 @@
public final int targetMode;
public final boolean hasRecents;
+ private boolean mReleased = false;
+
public RemoteAnimationTargets(RemoteAnimationTargetCompat[] apps,
RemoteAnimationTargetCompat[] wallpapers, int targetMode) {
ArrayList<RemoteAnimationTargetCompat> filteredApps = new ArrayList<>();
@@ -76,21 +75,65 @@
return false;
}
- public void addDependentTransactionApplier(SyncRtSurfaceTransactionApplierCompat delay) {
- mDependentTransactionAppliers.add(delay);
+ public void addReleaseCheck(ReleaseCheck check) {
+ mReleaseChecks.add(check);
}
public void release() {
- SyncRtSurfaceTransactionApplierCompat applier = mDependentTransactionAppliers.poll();
- if (applier == null) {
- for (RemoteAnimationTargetCompat target : unfilteredApps) {
- target.release();
+ if (mReleased) {
+ return;
+ }
+ for (ReleaseCheck check : mReleaseChecks) {
+ if (!check.mCanRelease) {
+ check.addOnSafeToReleaseCallback(this::release);
+ return;
}
- for (RemoteAnimationTargetCompat target : wallpapers) {
- target.release();
+ }
+ mReleaseChecks.clear();
+ mReleased = true;
+
+ for (RemoteAnimationTargetCompat target : unfilteredApps) {
+ target.release();
+ }
+ for (RemoteAnimationTargetCompat target : wallpapers) {
+ target.release();
+ }
+ }
+
+ /**
+ * Interface for intercepting surface release method
+ */
+ public static class ReleaseCheck {
+
+ boolean mCanRelease = false;
+ private Runnable mAfterApplyCallback;
+
+ protected void setCanRelease(boolean canRelease) {
+ mCanRelease = canRelease;
+ if (mCanRelease && mAfterApplyCallback != null) {
+ Runnable r = mAfterApplyCallback;
+ mAfterApplyCallback = null;
+ r.run();
}
- } else {
- applier.addAfterApplyCallback(this::release);
+ }
+
+ /**
+ * Adds a callback to notify when the surface can safely be released
+ */
+ void addOnSafeToReleaseCallback(Runnable callback) {
+ if (mCanRelease) {
+ callback.run();
+ } else {
+ if (mAfterApplyCallback == null) {
+ mAfterApplyCallback = callback;
+ } else {
+ final Runnable oldCallback = mAfterApplyCallback;
+ mAfterApplyCallback = () -> {
+ callback.run();
+ oldCallback.run();
+ };
+ }
+ }
}
}
}
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 20d133c..c727da9 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -31,6 +31,7 @@
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.systemui.shared.recents.IPinnedStackAnimationListener;
import com.android.systemui.shared.recents.ISystemUiProxy;
+import com.android.systemui.shared.recents.model.Task;
/**
* Holds the reference to SystemUI.
@@ -344,4 +345,8 @@
}
}
}
+
+ public void handleImageBundleAsScreenshot(Bundle screenImageBundle, Rect locationInScreen,
+ Insets visibleInsets, Task.TaskKey task) {
+ }
}
diff --git a/robolectric_tests/config/robolectric.properties b/robolectric_tests/config/robolectric.properties
index c162255..b171712 100644
--- a/robolectric_tests/config/robolectric.properties
+++ b/robolectric_tests/config/robolectric.properties
@@ -13,6 +13,6 @@
com.android.launcher3.shadows.ShadowLooperExecutor \
com.android.launcher3.shadows.ShadowMainThreadInitializedObject \
com.android.launcher3.shadows.ShadowOverrides \
- com.android.launcher3.shadows.ShadowSyncRtSurfaceTransactionApplierCompat \
+ com.android.launcher3.shadows.ShadowSurfaceTransactionApplier \
application=com.android.launcher3.util.LauncherTestApplication
\ No newline at end of file
diff --git a/robolectric_tests/src/com/android/launcher3/shadows/ShadowSyncRtSurfaceTransactionApplierCompat.java b/robolectric_tests/src/com/android/launcher3/shadows/ShadowSurfaceTransactionApplier.java
similarity index 83%
rename from robolectric_tests/src/com/android/launcher3/shadows/ShadowSyncRtSurfaceTransactionApplierCompat.java
rename to robolectric_tests/src/com/android/launcher3/shadows/ShadowSurfaceTransactionApplier.java
index 238926c..a9f2f27 100644
--- a/robolectric_tests/src/com/android/launcher3/shadows/ShadowSyncRtSurfaceTransactionApplierCompat.java
+++ b/robolectric_tests/src/com/android/launcher3/shadows/ShadowSurfaceTransactionApplier.java
@@ -26,11 +26,11 @@
import org.robolectric.annotation.RealObject;
/**
- * Shadow for SyncRtSurfaceTransactionApplierCompat to override default functionality
+ * Shadow for SurfaceTransactionApplier to override default functionality
*/
-@Implements(className = "com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat",
+@Implements(className = "com.android.quickstep.util.SurfaceTransactionApplier",
isInAndroidSdk = false)
-public class ShadowSyncRtSurfaceTransactionApplierCompat {
+public class ShadowSurfaceTransactionApplier {
@RealObject
private Object mRealObject;
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 48b97fa..e8b5568 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -411,6 +411,11 @@
Favorites.BACKUP_TABLE_NAME);
return null;
}
+ case LauncherSettings.Settings.METHOD_REFRESH_HOTSEAT_RESTORE_TABLE: {
+ mOpenHelper.mHotseatRestoreTableExists = tableExists(
+ mOpenHelper.getReadableDatabase(), Favorites.HYBRID_HOTSEAT_BACKUP_TABLE);
+ return null;
+ }
case LauncherSettings.Settings.METHOD_RESTORE_BACKUP_TABLE: {
final long ts = System.currentTimeMillis();
if (ts - mLastRestoreTimestamp > RESTORE_BACKUP_TABLE_DELAY) {
@@ -609,6 +614,7 @@
private int mMaxItemId = -1;
private int mMaxScreenId = -1;
private boolean mBackupTableExists;
+ private boolean mHotseatRestoreTableExists;
static DatabaseHelper createDatabaseHelper(Context context, boolean forMigration) {
return createDatabaseHelper(context, null, forMigration);
@@ -633,6 +639,8 @@
databaseHelper.mBackupTableExists = tableExists(
databaseHelper.getReadableDatabase(), Favorites.BACKUP_TABLE_NAME);
}
+ databaseHelper.mHotseatRestoreTableExists = tableExists(
+ databaseHelper.getReadableDatabase(), Favorites.HYBRID_HOTSEAT_BACKUP_TABLE);
databaseHelper.initIds();
return databaseHelper;
@@ -679,6 +687,10 @@
dropTable(db, Favorites.BACKUP_TABLE_NAME);
mBackupTableExists = false;
}
+ if (mHotseatRestoreTableExists) {
+ dropTable(db, Favorites.HYBRID_HOTSEAT_BACKUP_TABLE);
+ mHotseatRestoreTableExists = false;
+ }
}
/**
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index 2cb3910..2a5ee00 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -100,6 +100,11 @@
public static final String BACKUP_TABLE_NAME = "favorites_bakup";
/**
+ * Backup table created when user hotseat is moved to workspace for hybrid hotseat
+ */
+ public static final String HYBRID_HOTSEAT_BACKUP_TABLE = "hotseat_restore_backup";
+
+ /**
* Temporary table used specifically for grid migrations during wallpaper preview
*/
public static final String PREVIEW_TABLE_NAME = "favorites_preview";
@@ -333,6 +338,8 @@
public static final String METHOD_REFRESH_BACKUP_TABLE = "refresh_backup_table";
+ public static final String METHOD_REFRESH_HOTSEAT_RESTORE_TABLE = "restore_hotseat_table";
+
public static final String METHOD_RESTORE_BACKUP_TABLE = "restore_backup_table";
public static final String METHOD_UPDATE_CURRENT_OPEN_HELPER = "update_current_open_helper";
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index dda39e8..85013d7 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -96,13 +96,23 @@
+ "the icon onto 'Uninstall' button in the target bar")
LAUNCHER_ITEM_UNINSTALL_CANCELLED(470),
+ @UiEvent(doc = "User tapped or long pressed on the task icon(aka package icon) "
+ + "from overview to open task menu.")
+ LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS(517),
+
@UiEvent(doc = "User opened package specific widgets list by tapping on widgets system "
+ "shortcut within longpress popup window.")
LAUNCHER_SYSTEM_SHORTCUT_WIDGETS_TAP(514),
@UiEvent(doc = "User opened app info of the package by tapping on appinfo system shortcut "
+ "within longpress popup window.")
- LAUNCHER_SYSTEM_SHORTCUT_APP_INFO_TAP(515);
+ LAUNCHER_SYSTEM_SHORTCUT_APP_INFO_TAP(515),
+
+ @UiEvent(doc = "User tapped on split screen icon on a task menu.")
+ LAUNCHER_SYSTEM_SHORTCUT_SPLIT_SCREEN_TAP(518),
+
+ @UiEvent(doc = "User tapped on free form icon on a task menu.")
+ LAUNCHER_SYSTEM_SHORTCUT_FREE_FORM_TAP(519);
// ADD MORE
private final int mId;
diff --git a/src/com/android/launcher3/model/GridBackupTable.java b/src/com/android/launcher3/model/GridBackupTable.java
index 4a1bc4d..acfc339 100644
--- a/src/com/android/launcher3/model/GridBackupTable.java
+++ b/src/com/android/launcher3/model/GridBackupTable.java
@@ -128,6 +128,32 @@
}
/**
+ * Creates a new table and populates with copy of Favorites.TABLE_NAME
+ */
+ public void createCustomBackupTable(String tableName) {
+ long profileId = UserCache.INSTANCE.get(mContext).getSerialNumberForUser(
+ Process.myUserHandle());
+ copyTable(mDb, Favorites.TABLE_NAME, tableName, profileId);
+ encodeDBProperties(0);
+ }
+
+ /**
+ *
+ * Restores the contents of a custom table to Favorites.TABLE_NAME
+ */
+
+ public void restoreFromCustomBackupTable(String tableName, boolean dropAfterUse) {
+ if (!tableExists(mDb, tableName)) {
+ return;
+ }
+ long userSerial = UserCache.INSTANCE.get(mContext).getSerialNumberForUser(
+ Process.myUserHandle());
+ copyTable(mDb, tableName, Favorites.TABLE_NAME, userSerial);
+ if (dropAfterUse) {
+ dropTable(mDb, tableName);
+ }
+ }
+ /**
* Copy valid grid entries from one table to another.
*/
private static void copyTable(SQLiteDatabase db, String from, String to, long userSerial) {