summaryrefslogtreecommitdiffstats
path: root/quickstep
diff options
context:
space:
mode:
Diffstat (limited to 'quickstep')
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/DynamicItemCache.java15
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java113
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java12
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java13
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java18
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitOverviewStateTouchHelper.java8
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java1
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java20
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java19
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java19
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java7
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java6
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java11
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java10
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java81
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java7
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java2
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java16
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java1
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java17
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java5
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java12
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java12
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/views/DigitalWellBeingToast.java4
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java21
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java168
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java39
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java5
-rw-r--r--quickstep/src/com/android/quickstep/BaseRecentsActivity.java2
-rw-r--r--quickstep/src/com/android/quickstep/OverviewInteractionState.java9
-rw-r--r--quickstep/src/com/android/quickstep/RecentTasksList.java33
-rw-r--r--quickstep/src/com/android/quickstep/RecentsActivityTracker.java9
-rw-r--r--quickstep/src/com/android/quickstep/RecentsModel.java39
-rw-r--r--quickstep/src/com/android/quickstep/TaskIconCache.java26
-rw-r--r--quickstep/src/com/android/quickstep/TaskThumbnailCache.java9
-rw-r--r--quickstep/src/com/android/quickstep/views/ShelfScrimView.java2
-rw-r--r--quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java8
-rw-r--r--quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java99
38 files changed, 633 insertions, 265 deletions
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/DynamicItemCache.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/DynamicItemCache.java
index 4ecc39cf6..65e69b604 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/DynamicItemCache.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/DynamicItemCache.java
@@ -17,6 +17,8 @@ package com.android.launcher3.appprediction;
import static android.content.pm.PackageManager.MATCH_INSTANT;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -30,8 +32,12 @@ import android.os.Message;
import android.util.ArrayMap;
import android.util.Log;
+import androidx.annotation.MainThread;
+import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
+import androidx.annotation.WorkerThread;
+
import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherModel;
import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.icons.LauncherIcons;
@@ -45,11 +51,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import androidx.annotation.MainThread;
-import androidx.annotation.Nullable;
-import androidx.annotation.UiThread;
-import androidx.annotation.WorkerThread;
-
/**
* Utility class which loads and caches predicted items like instant apps and shortcuts, before
* they can be displayed on the UI
@@ -77,7 +78,7 @@ public class DynamicItemCache {
public DynamicItemCache(Context context, Runnable onUpdateCallback) {
mContext = context;
- mWorker = new Handler(LauncherModel.getWorkerLooper(), this::handleWorkerMessage);
+ mWorker = new Handler(MODEL_EXECUTOR.getLooper(), this::handleWorkerMessage);
mUiHandler = new Handler(Looper.getMainLooper(), this::handleUiMessage);
mInstantAppResolver = InstantAppResolver.newInstance(context);
mOnUpdateCallback = onUpdateCallback;
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java
index 24fc61bef..4c7943b10 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,6 +16,7 @@
package com.android.launcher3.appprediction;
import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_GRID;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import android.annotation.TargetApi;
import android.app.prediction.AppPredictionContext;
@@ -34,19 +35,25 @@ import android.os.UserHandle;
import android.util.Log;
import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
+import androidx.annotation.WorkerThread;
+
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
import com.android.launcher3.model.AppLaunchTracker;
-import com.android.launcher3.util.UiThreadHelper;
+import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
+import com.android.systemui.plugins.AppLaunchEventsPlugin;
+import com.android.systemui.plugins.PluginListener;
-import androidx.annotation.UiThread;
-import androidx.annotation.WorkerThread;
+import java.util.ArrayList;
+import java.util.List;
/**
* Subclass of app tracker which publishes the data to the prediction engine and gets back results.
*/
@TargetApi(Build.VERSION_CODES.Q)
-public class PredictionAppTracker extends AppLaunchTracker {
+public class PredictionAppTracker extends AppLaunchTracker
+ implements PluginListener<AppLaunchEventsPlugin> {
private static final String TAG = "PredictionAppTracker";
private static final boolean DBG = false;
@@ -58,6 +65,7 @@ public class PredictionAppTracker extends AppLaunchTracker {
protected final Context mContext;
private final Handler mMessageHandler;
+ private final List<AppLaunchEventsPlugin> mAppLaunchEventsPluginsList;
// Accessed only on worker thread
private AppPredictor mHomeAppPredictor;
@@ -65,10 +73,14 @@ public class PredictionAppTracker extends AppLaunchTracker {
public PredictionAppTracker(Context context) {
mContext = context;
- mMessageHandler = new Handler(UiThreadHelper.getBackgroundLooper(), this::handleMessage);
+ mMessageHandler = new Handler(UI_HELPER_EXECUTOR.getLooper(), this::handleMessage);
InvariantDeviceProfile.INSTANCE.get(mContext).addOnChangeListener(this::onIdpChanged);
mMessageHandler.sendEmptyMessage(MSG_INIT);
+
+ mAppLaunchEventsPluginsList = new ArrayList<>();
+ PluginManagerWrapper.INSTANCE.get(context)
+ .addPluginListener(this, AppLaunchEventsPlugin.class, true);
}
@UiThread
@@ -96,7 +108,7 @@ public class PredictionAppTracker extends AppLaunchTracker {
AppPredictionManager apm = mContext.getSystemService(AppPredictionManager.class);
if (apm == null) {
- return null;
+ return null;
}
AppPredictor predictor = apm.createAppPredictionSession(
@@ -116,7 +128,7 @@ public class PredictionAppTracker extends AppLaunchTracker {
*/
@WorkerThread
@Nullable
- public Bundle getAppPredictionContextExtras(Client client){
+ public Bundle getAppPredictionContextExtras(Client client) {
return null;
}
@@ -128,7 +140,7 @@ public class PredictionAppTracker extends AppLaunchTracker {
destroy();
// Initialize the clients
- int count = InvariantDeviceProfile.INSTANCE.get(mContext).numColumns;
+ int count = InvariantDeviceProfile.INSTANCE.get(mContext).numAllAppsColumns;
mHomeAppPredictor = createPredictor(Client.HOME, count);
mRecentsOverviewPredictor = createPredictor(Client.OVERVIEW, count);
return true;
@@ -167,37 +179,98 @@ public class PredictionAppTracker extends AppLaunchTracker {
if (DBG) {
Log.d(TAG, String.format("Sent immediate message to update %s", client));
}
+
+ // Relay onReturnedToHome to every plugin.
+ mAppLaunchEventsPluginsList.forEach(AppLaunchEventsPlugin::onReturnedToHome);
}
@Override
@UiThread
public void onStartShortcut(String packageName, String shortcutId, UserHandle user,
- String container) {
+ String container) {
// TODO: Use the full shortcut info
- AppTarget target = new AppTarget
- .Builder(new AppTargetId("shortcut:" + shortcutId), packageName, user)
- .setClassName(shortcutId)
- .build();
+ AppTarget target = new AppTarget.Builder(
+ new AppTargetId("shortcut:" + shortcutId), packageName, user)
+ .setClassName(shortcutId)
+ .build();
+
sendLaunch(target, container);
+
+ // Relay onStartShortcut info to every connected plugin.
+ mAppLaunchEventsPluginsList
+ .forEach(plugin -> plugin.onStartShortcut(
+ packageName,
+ shortcutId,
+ user,
+ container != null ? container : CONTAINER_DEFAULT)
+ );
+
}
@Override
@UiThread
public void onStartApp(ComponentName cn, UserHandle user, String container) {
if (cn != null) {
- AppTarget target = new AppTarget
- .Builder(new AppTargetId("app:" + cn), cn.getPackageName(), user)
- .setClassName(cn.getClassName())
- .build();
+ AppTarget target = new AppTarget.Builder(
+ new AppTargetId("app:" + cn), cn.getPackageName(), user)
+ .setClassName(cn.getClassName())
+ .build();
sendLaunch(target, container);
+
+ // Relay onStartApp to every connected plugin.
+ mAppLaunchEventsPluginsList
+ .forEach(plugin -> plugin.onStartApp(
+ cn,
+ user,
+ container != null ? container : CONTAINER_DEFAULT)
+ );
}
}
+ @Override
@UiThread
- private void sendLaunch(AppTarget target, String container) {
- AppTargetEvent event = new AppTargetEvent.Builder(target, AppTargetEvent.ACTION_LAUNCH)
+ public void onDismissApp(ComponentName cn, UserHandle user, String container) {
+ if (cn == null) return;
+ AppTarget target = new AppTarget.Builder(
+ new AppTargetId("app: " + cn), cn.getPackageName(), user)
+ .setClassName(cn.getClassName())
+ .build();
+ sendDismiss(target, container);
+
+ // Relay onDismissApp to every connected plugin.
+ mAppLaunchEventsPluginsList
+ .forEach(plugin -> plugin.onDismissApp(
+ cn,
+ user,
+ container != null ? container : CONTAINER_DEFAULT)
+ );
+ }
+
+ @UiThread
+ private void sendEvent(AppTarget target, String container, int eventId) {
+ AppTargetEvent event = new AppTargetEvent.Builder(target, eventId)
.setLaunchLocation(container == null ? CONTAINER_DEFAULT : container)
.build();
Message.obtain(mMessageHandler, MSG_LAUNCH, event).sendToTarget();
}
+
+ @UiThread
+ private void sendLaunch(AppTarget target, String container) {
+ sendEvent(target, container, AppTargetEvent.ACTION_LAUNCH);
+ }
+
+ @UiThread
+ private void sendDismiss(AppTarget target, String container) {
+ sendEvent(target, container, AppTargetEvent.ACTION_DISMISS);
+ }
+
+ @Override
+ public void onPluginConnected(AppLaunchEventsPlugin appLaunchEventsPlugin, Context context) {
+ mAppLaunchEventsPluginsList.add(appLaunchEventsPlugin);
+ }
+
+ @Override
+ public void onPluginDisconnected(AppLaunchEventsPlugin appLaunchEventsPlugin) {
+ mAppLaunchEventsPluginsList.remove(appLaunchEventsPlugin);
+ }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java
index 0c7ba9c95..23db5df2e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java
@@ -43,6 +43,7 @@ import com.android.launcher3.ItemInfo;
import com.android.launcher3.ItemInfoWithIcon;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.allapps.AllAppsStore;
@@ -92,7 +93,7 @@ public class PredictionRowView extends LinearLayout implements
private final Launcher mLauncher;
private final PredictionUiStateManager mPredictionUiStateManager;
- private final int mNumPredictedAppsPerRow;
+ private int mNumPredictedAppsPerRow;
// The set of predicted app component names
private final List<ComponentKeyMapper> mPredictedAppComponents = new ArrayList<>();
@@ -128,7 +129,7 @@ public class PredictionRowView extends LinearLayout implements
mFocusHelper = new SimpleFocusIndicatorHelper(this);
- mNumPredictedAppsPerRow = LauncherAppState.getIDP(context).numColumns;
+ mNumPredictedAppsPerRow = LauncherAppState.getIDP(context).numAllAppsColumns;
mLauncher = Launcher.getLauncher(context);
mLauncher.addOnDeviceProfileChangeListener(this);
@@ -226,6 +227,7 @@ public class PredictionRowView extends LinearLayout implements
@Override
public void onDeviceProfileChanged(DeviceProfile dp) {
+ mNumPredictedAppsPerRow = dp.inv.numAllAppsColumns;
removeAllViews();
applyPredictionApps();
}
@@ -281,7 +283,7 @@ public class PredictionRowView extends LinearLayout implements
}
private List<ItemInfoWithIcon> processPredictedAppComponents(List<ComponentKeyMapper> components) {
- if (getAppsStore().getApps().isEmpty()) {
+ if (getAppsStore().getApps().length == 0) {
// Apps have not been bound yet.
return Collections.emptyList();
}
@@ -290,7 +292,9 @@ public class PredictionRowView extends LinearLayout implements
for (ComponentKeyMapper mapper : components) {
ItemInfoWithIcon info = mapper.getApp(getAppsStore());
if (info != null) {
- predictedApps.add(info);
+ ItemInfoWithIcon predictedApp = info.clone();
+ predictedApp.container = LauncherSettings.Favorites.CONTAINER_PREDICTION;
+ predictedApps.add(predictedApp);
} else {
if (FeatureFlags.IS_DOGFOOD_BUILD) {
Log.e(TAG, "Predicted app not found: " + mapper);
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
index 50cfac8e4..468b8afc9 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
@@ -19,7 +19,6 @@ import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
-import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.util.LayoutUtils;
@@ -69,8 +68,16 @@ public class BackgroundAppState extends OverviewState {
if (taskCount == 0) {
return super.getOverviewScaleAndTranslation(launcher);
}
- TaskView dummyTask = recentsView.getTaskViewAt(Utilities.boundToRange(
- recentsView.getCurrentPage(), 0, taskCount - 1));
+ TaskView dummyTask;
+ if (recentsView.getCurrentPage() >= 0) {
+ if (recentsView.getCurrentPage() <= taskCount - 1) {
+ dummyTask = recentsView.getCurrentPageTaskView();
+ } else {
+ dummyTask = recentsView.getTaskViewAt(taskCount - 1);
+ }
+ } else {
+ dummyTask = recentsView.getTaskViewAt(0);
+ }
return recentsView.getTempClipAnimationHelper().updateForFullscreenOverview(dummyTask)
.getScaleAndTranslation();
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
index ab346c059..4a3ad1d72 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/FlingAndHoldTouchController.java
@@ -42,6 +42,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
+import android.view.View;
import android.view.ViewConfiguration;
import com.android.launcher3.Launcher;
@@ -179,6 +180,11 @@ public class FlingAndHoldTouchController extends PortraitStatesTouchController {
} else {
super.onDragEnd(velocity, fling);
}
+
+ View searchView = mLauncher.getAppsView().getSearchView();
+ if (searchView instanceof FeedbackHandler) {
+ ((FeedbackHandler) searchView).resetFeedback();
+ }
mMotionPauseDetector.clear();
}
@@ -205,4 +211,16 @@ public class FlingAndHoldTouchController extends PortraitStatesTouchController {
builder.addFlag(AnimatorSetBuilder.FLAG_DONT_ANIMATE_OVERVIEW);
}
}
+
+ /**
+ * Interface for views with feedback animation requiring reset
+ */
+ public interface FeedbackHandler {
+
+ /**
+ * reset searchWidget feedback
+ */
+ void resetFeedback();
+ }
+
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitOverviewStateTouchHelper.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitOverviewStateTouchHelper.java
index 20a248734..03862db1d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitOverviewStateTouchHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitOverviewStateTouchHelper.java
@@ -47,9 +47,9 @@ public final class PortraitOverviewStateTouchHelper {
* @return true if we should intercept the motion event
*/
boolean canInterceptTouch(MotionEvent ev) {
- if (mRecentsView.getChildCount() > 0) {
+ if (mRecentsView.getTaskViewCount() > 0) {
// Allow swiping up in the gap between the hotseat and overview.
- return ev.getY() >= mRecentsView.getChildAt(0).getBottom();
+ return ev.getY() >= mRecentsView.getTaskViewAt(0).getBottom();
} else {
// If there are no tasks, we only intercept if we're below the hotseat height.
return isTouchOverHotseat(mLauncher, ev);
@@ -63,7 +63,7 @@ public final class PortraitOverviewStateTouchHelper {
* @return true if going back should take the user to the currently running task
*/
boolean shouldSwipeDownReturnToApp() {
- TaskView taskView = mRecentsView.getTaskViewAt(mRecentsView.getNextPage());
+ TaskView taskView = mRecentsView.getNextPageTaskView();
return taskView != null && mRecentsView.shouldSwipeDownLaunchApp();
}
@@ -76,7 +76,7 @@ public final class PortraitOverviewStateTouchHelper {
*/
PendingAnimation createSwipeDownToTaskAppAnimation(long duration) {
mRecentsView.setCurrentPage(mRecentsView.getPageNearestToCenterOfScreen());
- TaskView taskView = mRecentsView.getTaskViewAt(mRecentsView.getCurrentPage());
+ TaskView taskView = mRecentsView.getCurrentPageTaskView();
if (taskView == null) {
throw new IllegalStateException("There is no task view to animate to.");
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index eb571f607..6576ec573 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -50,7 +50,6 @@ import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
-import com.android.systemui.shared.system.QuickStepContract;
/**
* Handles quick switching to a recent task from the home screen.
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 d627a7f14..7196f7c6f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -22,9 +22,9 @@ import static com.android.launcher3.Utilities.postAsyncCallback;
import static com.android.launcher3.anim.Interpolators.ACCEL_1_5;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
-import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR;
-import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR;
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
import android.animation.Animator;
@@ -44,9 +44,10 @@ import android.os.Vibrator;
import android.provider.Settings;
import android.view.MotionEvent;
import android.view.View;
-import android.view.WindowManager;
import android.view.animation.Interpolator;
+import androidx.annotation.UiThread;
+
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
@@ -54,7 +55,6 @@ import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
-import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.views.FloatingIconView;
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
@@ -75,8 +75,6 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
import java.util.function.Consumer;
-import androidx.annotation.UiThread;
-
/**
* Base class for swipe up handler with some utility methods
*/
@@ -126,7 +124,7 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
protected Runnable mGestureEndCallback;
- protected final Handler mMainThreadHandler = MAIN_THREAD_EXECUTOR.getHandler();
+ protected final Handler mMainThreadHandler = MAIN_EXECUTOR.getHandler();
protected MultiStateCallback mStateCallback;
protected boolean mCanceled;
@@ -174,7 +172,7 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
if (effect == null) {
return;
}
- BACKGROUND_EXECUTOR.execute(() -> mVibrator.vibrate(effect));
+ UI_HELPER_EXECUTOR.execute(() -> mVibrator.vibrate(effect));
}
public Consumer<MotionEvent> getRecentsViewDispatcher(RotationMode rotationMode) {
@@ -229,10 +227,10 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
// Launch the task user scrolled to (mRecentsView.getNextPage()).
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
// We finish recents animation inside launchTask() when live tile is enabled.
- mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).launchTask(false /* animate */,
+ mRecentsView.getNextPageTaskView().launchTask(false /* animate */,
true /* freezeTaskList */);
} else {
- int taskId = mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).getTask().key.id;
+ int taskId = mRecentsView.getNextPageTaskView().getTask().key.id;
mFinishingRecentsAnimationForNewTaskId = taskId;
mRecentsAnimationWrapper.finish(true /* toRecents */, () -> {
if (!mCanceled) {
@@ -275,7 +273,7 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
overviewStackBounds = getStackBounds(dp);
}
dp.updateInsets(targetSet.homeContentInsets);
- dp.updateIsSeascape(mContext.getSystemService(WindowManager.class));
+ dp.updateIsSeascape(mContext);
if (runningTaskTarget != null) {
mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget);
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
index 36eb8a13b..57e6d96ef 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -268,22 +268,12 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
INDEX_RECENTS_FADE_ANIM, attached ? 1 : 0);
int runningTaskIndex = recentsView.getRunningTaskIndex();
- if (runningTaskIndex == 0) {
+ if (runningTaskIndex == recentsView.getTaskViewStartIndex()) {
// If we are on the first task (we haven't quick switched), translate recents in
// from the side. Calculate the start translation based on current scale/scroll.
float currScale = recentsView.getScaleX();
float scrollOffsetX = recentsView.getScrollOffset();
-
- float offscreenX = NORMAL.getOverviewScaleAndTranslation(activity).translationX;
- // The first task is hidden, so offset by its width.
- int firstTaskWidth = recentsView.getTaskViewAt(0).getWidth();
- offscreenX -= (firstTaskWidth + recentsView.getPageSpacing()) * currScale;
- // Offset since scale pushes tasks outwards.
- offscreenX += firstTaskWidth * (currScale - 1) / 2;
- offscreenX = Math.max(0, offscreenX);
- if (recentsView.isRtl()) {
- offscreenX = -offscreenX;
- }
+ float offscreenX = recentsView.getOffscreenTranslationX(currScale);
float fromTranslationX = attached ? offscreenX - scrollOffsetX : 0;
float toTranslationX = attached ? 0 : offscreenX - scrollOffsetX;
@@ -351,8 +341,7 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
private void playScaleDownAnim(AnimatorSet anim, Launcher launcher, LauncherState fromState,
LauncherState endState) {
RecentsView recentsView = launcher.getOverviewPanel();
- TaskView v = recentsView.getTaskViewAt(recentsView.getCurrentPage());
- if (v == null) {
+ if (recentsView.getCurrentPageTaskView() == null) {
return;
}
@@ -380,7 +369,7 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
// recents as a whole needs to translate further to keep up with the app window.
TaskView runningTaskView = recentsView.getRunningTaskView();
if (runningTaskView == null) {
- runningTaskView = recentsView.getTaskViewAt(recentsView.getCurrentPage());
+ runningTaskView = recentsView.getCurrentPageTaskView();
if (runningTaskView == null) {
// There are no task views in LockTask mode when Overview is enabled.
return;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java
index 222ef97d9..a8d402e56 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java
@@ -15,8 +15,8 @@
*/
package com.android.quickstep;
-import static com.android.systemui.shared.system.ActivityManagerWrapper
- .CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -29,7 +29,6 @@ import android.util.Log;
import android.view.ViewConfiguration;
import com.android.launcher3.BaseDraggingActivity;
-import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.userevent.nano.LauncherLogProto;
@@ -49,7 +48,6 @@ public class OverviewCommandHelper {
private final Context mContext;
private final ActivityManagerWrapper mAM;
private final RecentsModel mRecentsModel;
- private final MainThreadExecutor mMainThreadExecutor;
private final OverviewComponentObserver mOverviewComponentObserver;
private long mLastToggleTime;
@@ -57,7 +55,6 @@ public class OverviewCommandHelper {
public OverviewCommandHelper(Context context, OverviewComponentObserver observer) {
mContext = context;
mAM = ActivityManagerWrapper.getInstance();
- mMainThreadExecutor = new MainThreadExecutor();
mRecentsModel = RecentsModel.INSTANCE.get(mContext);
mOverviewComponentObserver = observer;
}
@@ -69,19 +66,19 @@ public class OverviewCommandHelper {
}
mAM.closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
- mMainThreadExecutor.execute(new RecentsActivityCommand<>());
+ MAIN_EXECUTOR.execute(new RecentsActivityCommand<>());
}
public void onOverviewShown(boolean triggeredFromAltTab) {
- mMainThreadExecutor.execute(new ShowRecentsCommand(triggeredFromAltTab));
+ MAIN_EXECUTOR.execute(new ShowRecentsCommand(triggeredFromAltTab));
}
public void onOverviewHidden() {
- mMainThreadExecutor.execute(new HideRecentsCommand());
+ MAIN_EXECUTOR.execute(new HideRecentsCommand());
}
public void onTip(int actionType, int viewType) {
- mMainThreadExecutor.execute(() ->
+ MAIN_EXECUTOR.execute(() ->
UserEventDispatcher.newInstance(mContext).logActionTip(actionType, viewType));
}
@@ -112,7 +109,7 @@ public class OverviewCommandHelper {
TaskView taskView = rv.getNextTaskView();
if (taskView == null) {
if (rv.getTaskViewCount() > 0) {
- taskView = (TaskView) rv.getPageAt(0);
+ taskView = rv.getTaskViewAt(0);
taskView.requestFocus();
} else {
rv.requestFocus();
@@ -180,7 +177,7 @@ public class OverviewCommandHelper {
// Otherwise, start overview.
mListener = mHelper.createActivityInitListener(this::onActivityReady);
mListener.registerAndStartActivity(mOverviewComponentObserver.getOverviewIntent(),
- this::createWindowAnimation, mContext, mMainThreadExecutor.getHandler(),
+ this::createWindowAnimation, mContext, MAIN_EXECUTOR.getHandler(),
mAnimationProvider.getRecentsLaunchDuration());
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java
index da4642636..72a14b58e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/QuickstepTestInformationHandler.java
@@ -1,9 +1,10 @@
package com.android.quickstep;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+
import android.content.Context;
import android.os.Bundle;
-import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.testing.TestInformationHandler;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.uioverrides.states.OverviewState;
@@ -52,7 +53,7 @@ public class QuickstepTestInformationHandler extends TestInformationHandler {
case TestProtocol.REQUEST_OVERVIEW_LEFT_GESTURE_MARGIN: {
try {
- final int leftMargin = new MainThreadExecutor().submit(() ->
+ final int leftMargin = MAIN_EXECUTOR.submit(() ->
mLauncher.<RecentsView>getOverviewPanel().getLeftGestureMargin()).get();
response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, leftMargin);
} catch (ExecutionException e) {
@@ -65,7 +66,7 @@ public class QuickstepTestInformationHandler extends TestInformationHandler {
case TestProtocol.REQUEST_OVERVIEW_RIGHT_GESTURE_MARGIN: {
try {
- final int rightMargin = new MainThreadExecutor().submit(() ->
+ final int rightMargin = MAIN_EXECUTOR.submit(() ->
mLauncher.<RecentsView>getOverviewPanel().getRightGestureMargin()).
get();
response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, rightMargin);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
index f08ae4a82..9bdc98bf8 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
@@ -136,6 +136,12 @@ public final class RecentsActivity extends BaseRecentsActivity {
}
@Override
+ public void returnToHomescreen() {
+ super.returnToHomescreen();
+ // TODO(b/137318995) This should go home, but doing so removes freeform windows
+ }
+
+ @Override
public ActivityOptions getActivityLaunchOptions(final View v) {
if (!(v instanceof TaskView)) {
return null;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java
index c55f656df..8783ee3cc 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java
@@ -15,7 +15,7 @@
*/
package com.android.quickstep;
-import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.util.Log;
@@ -25,6 +25,7 @@ import com.android.launcher3.util.Preconditions;
import com.android.quickstep.util.RecentsAnimationListenerSet;
import com.android.quickstep.util.SwipeAnimationTargetSet;
import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
+
import java.io.PrintWriter;
/**
@@ -44,6 +45,7 @@ public class SwipeSharedState implements SwipeAnimationListener {
public boolean goingToLauncher;
public boolean recentsAnimationFinishInterrupted;
public int nextRunningTaskId = -1;
+ private int mLogId;
public void setOverviewComponentObserver(OverviewComponentObserver observer) {
mOverviewComponentObserver = observer;
@@ -77,7 +79,7 @@ public class SwipeSharedState implements SwipeAnimationListener {
mRecentsAnimationListener.removeListener(this);
mRecentsAnimationListener.cancelListener();
if (mLastAnimationRunning && mLastAnimationTarget != null) {
- Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(),
+ Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(),
finishAnimation
? mLastAnimationTarget::finishAnimation
: mLastAnimationTarget::cancelAnimation);
@@ -155,5 +157,10 @@ public class SwipeSharedState implements SwipeAnimationListener {
pw.println(prefix + "nextRunningTaskId=" + nextRunningTaskId);
pw.println(prefix + "lastAnimationCancelled=" + mLastAnimationCancelled);
pw.println(prefix + "lastAnimationRunning=" + mLastAnimationRunning);
+ pw.println(prefix + "logTraceId=" + mLogId);
+ }
+
+ public void setLogTraceId(int logId) {
+ this.mLogId = logId;
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
index fd4592307..1af0db07d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
@@ -36,8 +36,6 @@ import android.view.View;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.ItemInfo;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.popup.SystemShortcut;
@@ -267,12 +265,16 @@ public class TaskSystemShortcut<T extends SystemShortcut> extends SystemShortcut
@Override
protected ActivityOptions makeLaunchOptions(Activity activity) {
- return ActivityOptionsCompat.makeFreeformOptions();
+ ActivityOptions activityOptions = ActivityOptionsCompat.makeFreeformOptions();
+ // Arbitrary bounds only because freeform is in dev mode right now
+ Rect r = new Rect(50, 50, 200, 200);
+ activityOptions.setLaunchBounds(r);
+ return activityOptions;
}
@Override
protected boolean onActivityStarted(BaseDraggingActivity activity) {
- Launcher.getLauncher(activity).getStateManager().goToState(LauncherState.NORMAL);
+ activity.returnToHomescreen();
return true;
}
}
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 86ba85578..729287c82 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -23,6 +23,8 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_HINTS_IN_OVERVIEW
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.config.FeatureFlags.FAKE_LANDSCAPE_UI;
import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_MONITOR;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
@@ -50,8 +52,6 @@ import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.RectF;
import android.graphics.Region;
-import android.hardware.display.DisplayManager;
-import android.hardware.display.DisplayManager.DisplayListener;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
@@ -61,18 +61,15 @@ import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
import android.view.Choreographer;
-import android.view.Display;
import android.view.InputEvent;
import android.view.MotionEvent;
import android.view.Surface;
-import android.view.WindowManager;
import androidx.annotation.BinderThread;
import androidx.annotation.UiThread;
import androidx.annotation.WorkerThread;
import com.android.launcher3.BaseDraggingActivity;
-import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
import com.android.launcher3.ResourceUtils;
import com.android.launcher3.Utilities;
@@ -82,8 +79,7 @@ import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.model.AppLaunchTracker;
import com.android.launcher3.provider.RestoreDbTask;
import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.util.LooperExecutor;
-import com.android.launcher3.util.UiThreadHelper;
+import com.android.launcher3.util.DefaultDisplay;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
import com.android.quickstep.inputconsumers.AccessibilityInputConsumer;
@@ -106,8 +102,8 @@ import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import com.android.systemui.shared.system.RecentsAnimationListener;
import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat;
-
import com.android.systemui.shared.system.TaskInfoCompat;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Arrays;
@@ -136,11 +132,14 @@ class ArgList extends LinkedList<String> {
*/
@TargetApi(Build.VERSION_CODES.Q)
public class TouchInteractionService extends Service implements
- NavigationModeChangeListener, DisplayListener {
+ NavigationModeChangeListener, DefaultDisplay.DisplayInfoChangeListener {
+
+ /**
+ * NOTE: This value should be kept same as
+ * ActivityTaskManagerService#INTENT_EXTRA_LOG_TRACE_ID in platform
+ */
+ public static final String INTENT_EXTRA_LOG_TRACE_ID = "INTENT_EXTRA_LOG_TRACE_ID";
- public static final MainThreadExecutor MAIN_THREAD_EXECUTOR = new MainThreadExecutor();
- public static final LooperExecutor BACKGROUND_EXECUTOR =
- new LooperExecutor(UiThreadHelper.getBackgroundLooper());
public static final EventLogArray TOUCH_INTERACTION_LOG =
new EventLogArray("touch_interaction_log", 40);
@@ -161,9 +160,9 @@ public class TouchInteractionService extends Service implements
public void onInitialize(Bundle bundle) {
mISystemUiProxy = ISystemUiProxy.Stub
.asInterface(bundle.getBinder(KEY_EXTRA_SYSUI_PROXY));
- MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::initInputMonitor);
- MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::onSystemUiProxySet);
- MAIN_THREAD_EXECUTOR.execute(() -> preloadOverview(true /* fromInit */));
+ MAIN_EXECUTOR.execute(TouchInteractionService.this::initInputMonitor);
+ MAIN_EXECUTOR.execute(TouchInteractionService.this::onSystemUiProxySet);
+ MAIN_EXECUTOR.execute(() -> preloadOverview(true /* fromInit */));
sIsInitialized = true;
}
@@ -198,7 +197,7 @@ public class TouchInteractionService extends Service implements
@Override
public void onAssistantVisibilityChanged(float visibility) {
mLastAssistantVisibility = visibility;
- MAIN_THREAD_EXECUTOR.execute(
+ MAIN_EXECUTOR.execute(
TouchInteractionService.this::onAssistantVisibilityChanged);
}
@@ -214,13 +213,13 @@ public class TouchInteractionService extends Service implements
isButton, gestureSwipeLeft, activityControl.getContainerType());
if (completed && !isButton && shouldNotifyBackGesture()) {
- BACKGROUND_EXECUTOR.execute(TouchInteractionService.this::tryNotifyBackGesture);
+ UI_HELPER_EXECUTOR.execute(TouchInteractionService.this::tryNotifyBackGesture);
}
}
public void onSystemUiStateChanged(int stateFlags) {
mSystemUiStateFlags = stateFlags;
- MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::onSystemUiFlagsChanged);
+ MAIN_EXECUTOR.execute(TouchInteractionService.this::onSystemUiFlagsChanged);
}
/** Deprecated methods **/
@@ -244,6 +243,7 @@ public class TouchInteractionService extends Service implements
private static boolean sConnected = false;
private static boolean sIsInitialized = false;
private static final SwipeSharedState sSwipeSharedState = new SwipeSharedState();
+ private int mLogId;
public static boolean isConnected() {
return sConnected;
@@ -323,8 +323,7 @@ public class TouchInteractionService extends Service implements
registerReceiver(mUserUnlockedReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
}
- mDefaultDisplayId = getSystemService(WindowManager.class).getDefaultDisplay()
- .getDisplayId();
+ mDefaultDisplayId = DefaultDisplay.INSTANCE.get(this).getInfo().id;
String blockingActivity = getString(R.string.gesture_blocking_activity);
mGestureBlockingActivity = TextUtils.isEmpty(blockingActivity) ? null :
ComponentName.unflattenFromString(blockingActivity);
@@ -391,9 +390,8 @@ public class TouchInteractionService extends Service implements
return;
}
- Display defaultDisplay = getSystemService(WindowManager.class).getDefaultDisplay();
- Point realSize = new Point();
- defaultDisplay.getRealSize(realSize);
+ DefaultDisplay.Info displayInfo = DefaultDisplay.INSTANCE.get(this).getInfo();
+ Point realSize = new Point(displayInfo.realSize);
mSwipeTouchRegion.set(0, 0, realSize.x, realSize.y);
if (mMode == Mode.NO_BUTTON) {
int touchHeight = getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE);
@@ -415,7 +413,7 @@ public class TouchInteractionService extends Service implements
} else {
mAssistantLeftRegion.setEmpty();
mAssistantRightRegion.setEmpty();
- switch (defaultDisplay.getRotation()) {
+ switch (displayInfo.rotation) {
case Surface.ROTATION_90:
mSwipeTouchRegion.left = mSwipeTouchRegion.right
- getNavbarSize(ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE);
@@ -438,10 +436,9 @@ public class TouchInteractionService extends Service implements
}
if (mMode.hasGestures != newMode.hasGestures) {
if (newMode.hasGestures) {
- getSystemService(DisplayManager.class).registerDisplayListener(
- this, MAIN_THREAD_EXECUTOR.getHandler());
+ DefaultDisplay.INSTANCE.get(this).addChangeListener(this);
} else {
- getSystemService(DisplayManager.class).unregisterDisplayListener(this);
+ DefaultDisplay.INSTANCE.get(this).removeChangeListener(this);
}
}
mMode = newMode;
@@ -457,14 +454,8 @@ public class TouchInteractionService extends Service implements
}
@Override
- public void onDisplayAdded(int i) { }
-
- @Override
- public void onDisplayRemoved(int i) { }
-
- @Override
- public void onDisplayChanged(int displayId) {
- if (displayId != mDefaultDisplayId) {
+ public void onDisplayInfoChanged(DefaultDisplay.Info info, int flags) {
+ if (info.id != mDefaultDisplayId) {
return;
}
@@ -529,7 +520,7 @@ public class TouchInteractionService extends Service implements
}
disposeEventHandlers();
if (mMode.hasGestures) {
- getSystemService(DisplayManager.class).unregisterDisplayListener(this);
+ DefaultDisplay.INSTANCE.get(this).removeChangeListener(this);
}
sConnected = false;
@@ -554,9 +545,12 @@ public class TouchInteractionService extends Service implements
Log.e(TAG, "Unknown event " + ev);
return;
}
+
MotionEvent event = (MotionEvent) ev;
- TOUCH_INTERACTION_LOG.addLog("onMotionEvent", event.getActionMasked());
if (event.getAction() == ACTION_DOWN) {
+ mLogId = TOUCH_INTERACTION_LOG.generateAndSetLogId();
+ sSwipeSharedState.setLogTraceId(mLogId);
+
if (mSwipeTouchRegion.contains(event.getX(), event.getY())) {
boolean useSharedState = mConsumer.useSharedSwipeState();
mConsumer.onConsumerAboutToBeSwitched();
@@ -576,6 +570,8 @@ public class TouchInteractionService extends Service implements
mUncheckedConsumer = InputConsumer.NO_OP;
}
}
+
+ TOUCH_INTERACTION_LOG.addLog("onMotionEvent", event.getActionMasked());
mUncheckedConsumer.onMotionEvent(event);
}
@@ -661,7 +657,7 @@ public class TouchInteractionService extends Service implements
final ComponentName homeComponent =
mOverviewComponentObserver.getHomeIntent().getComponent();
forceOverviewInputConsumer =
- runningTaskInfo.baseIntent.getComponent().equals(homeComponent);
+ runningTaskInfo.baseIntent.getComponent(). equals(homeComponent);
}
}
@@ -718,13 +714,13 @@ public class TouchInteractionService extends Service implements
return new OtherActivityInputConsumer(this, runningTaskInfo,
shouldDefer, mOverviewCallbacks, this::onConsumerInactive,
sSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion,
- disableHorizontalSwipe(event), factory);
+ disableHorizontalSwipe(event), factory, mLogId);
}
private InputConsumer createDeviceLockedInputConsumer(RunningTaskInfo taskInfo) {
if (mMode == Mode.NO_BUTTON && taskInfo != null) {
return new DeviceLockedInputConsumer(this, sSwipeSharedState, mInputMonitorCompat,
- mSwipeTouchRegion, taskInfo.taskId);
+ mSwipeTouchRegion, taskInfo.taskId, mLogId);
} else {
return mResetGestureInputConsumer;
}
@@ -788,7 +784,8 @@ public class TouchInteractionService extends Service implements
}
// Pass null animation handler to indicate this start is preload.
- startRecentsActivityAsync(mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState(), null);
+ startRecentsActivityAsync(mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState(),
+ null);
}
@Override
@@ -897,7 +894,7 @@ public class TouchInteractionService extends Service implements
}
public static void startRecentsActivityAsync(Intent intent, RecentsAnimationListener listener) {
- BACKGROUND_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance()
+ UI_HELPER_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance()
.startRecentsActivity(intent, null, listener, null, null));
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index a3bd348e2..411a8088c 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -479,8 +479,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
recentsAttachedToAppWindow = mIsShelfPeeking || mIsLikelyToStartNewTask;
if (animate) {
// Only animate if an adjacent task view is visible on screen.
- TaskView adjacentTask1 = mRecentsView.getTaskViewAt(runningTaskIndex + 1);
- TaskView adjacentTask2 = mRecentsView.getTaskViewAt(runningTaskIndex - 1);
+ TaskView adjacentTask1 = mRecentsView.getNextTaskView();
+ TaskView adjacentTask2 = mRecentsView.getPreviousTaskView();
float prevTranslationX = mRecentsView.getTranslationX();
mRecentsView.setTranslationX(0);
animate = (adjacentTask1 != null && adjacentTask1.getGlobalVisibleRect(TEMP_RECT))
@@ -590,8 +590,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
*/
private void updateSysUiFlags(float windowProgress) {
if (mRecentsView != null) {
- TaskView centermostTask = mRecentsView.getTaskViewAt(mRecentsView
- .getPageNearestToCenterOfScreen());
+ TaskView centermostTask = mRecentsView.getTaskViewNearestToCenterOfScreen();
int centermostTaskFlags = centermostTask == null ? 0
: centermostTask.getThumbnail().getSysUiStatusNavFlags();
boolean useHomeScreenFlags = windowProgress > 1 - UPDATE_SYSUI_FLAGS_THRESHOLD;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 2e9c0a3c4..7f1aae5e2 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -176,7 +176,7 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> {
protected void applyLoadPlan(ArrayList<Task> tasks) {
// When quick-switching on 3p-launcher, we add a "dummy" tile corresponding to Launcher
// as well. This tile is never shown as we have setCurrentTaskHidden, but allows use to
- // track the index of the next task appropriately, as it we are switching on any other app.
+ // track the index of the next task appropriately, as if we are switching on any other app.
if (mRunningTaskInfo != null && mRunningTaskInfo.taskId == mRunningTaskId) {
// Check if the task list has running task
boolean found = false;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index 3d763ab52..b24c78810 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -22,8 +22,9 @@ import static android.view.MotionEvent.ACTION_UP;
import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.launcher3.Utilities.squaredTouchSlop;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
-import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW;
+import static com.android.quickstep.TouchInteractionService.INTENT_EXTRA_LOG_TRACE_ID;
import static com.android.quickstep.TouchInteractionService.startRecentsActivityAsync;
+import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW;
import android.content.ComponentName;
import android.content.Context;
@@ -35,10 +36,10 @@ import android.graphics.RectF;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
-import android.view.WindowManager;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.util.DefaultDisplay;
import com.android.quickstep.LockScreenRecentsActivity;
import com.android.quickstep.MultiStateCallback;
import com.android.quickstep.SwipeSharedState;
@@ -76,6 +77,7 @@ public class DeviceLockedInputConsumer implements InputConsumer,
private final PointF mTouchDown = new PointF();
private final ClipAnimationHelper mClipAnimationHelper;
+ private int mLogId;
private final ClipAnimationHelper.TransformParams mTransformParams;
private final Point mDisplaySize;
private final MultiStateCallback mStateCallback;
@@ -90,19 +92,20 @@ public class DeviceLockedInputConsumer implements InputConsumer,
private SwipeAnimationTargetSet mTargetSet;
public DeviceLockedInputConsumer(Context context, SwipeSharedState swipeSharedState,
- InputMonitorCompat inputMonitorCompat, RectF swipeTouchRegion, int runningTaskId) {
+ InputMonitorCompat inputMonitorCompat, RectF swipeTouchRegion, int runningTaskId,
+ int logId) {
mContext = context;
mTouchSlopSquared = squaredTouchSlop(context);
mSwipeSharedState = swipeSharedState;
mClipAnimationHelper = new ClipAnimationHelper(context);
+ mLogId = logId;
mTransformParams = new ClipAnimationHelper.TransformParams();
mInputMonitorCompat = inputMonitorCompat;
mSwipeTouchRegion = swipeTouchRegion;
mRunningTaskId = runningTaskId;
// Do not use DeviceProfile as the user data might be locked
- mDisplaySize = new Point();
- context.getSystemService(WindowManager.class).getDefaultDisplay().getRealSize(mDisplaySize);
+ mDisplaySize = DefaultDisplay.INSTANCE.get(context).getInfo().realSize;
// Init states
mStateCallback = new MultiStateCallback(STATE_NAMES);
@@ -205,7 +208,8 @@ public class DeviceLockedInputConsumer implements InputConsumer,
Intent intent = new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_DEFAULT)
.setComponent(new ComponentName(mContext, LockScreenRecentsActivity.class))
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
+ .putExtra(INTENT_EXTRA_LOG_TRACE_ID, mLogId);
mInputMonitorCompat.pilferPointers();
startRecentsActivityAsync(intent, newListenerSet);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java
index 6ec1da0c4..e0ff8afe6 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java
@@ -50,7 +50,6 @@ import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.util.ObjectWrapper;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.SwipeAnimationTargetSet;
-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.ActivityManagerWrapper;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index 86766d99f..e41880df5 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -22,11 +22,11 @@ import static android.view.MotionEvent.ACTION_POINTER_DOWN;
import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;
import static android.view.MotionEvent.INVALID_POINTER_ID;
-
import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.launcher3.util.RaceConditionTracker.ENTER;
import static com.android.launcher3.util.RaceConditionTracker.EXIT;
+import static com.android.quickstep.TouchInteractionService.INTENT_EXTRA_LOG_TRACE_ID;
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
import static com.android.quickstep.TouchInteractionService.startRecentsActivityAsync;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
@@ -35,6 +35,7 @@ import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.Intent;
import android.graphics.PointF;
import android.graphics.RectF;
import android.os.Build;
@@ -43,12 +44,13 @@ import android.os.Looper;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
-
+import androidx.annotation.UiThread;
import com.android.launcher3.R;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.RaceConditionTracker;
import com.android.launcher3.util.TraceHelper;
import com.android.quickstep.BaseSwipeUpHandler;
+import com.android.quickstep.BaseSwipeUpHandler.Factory;
import com.android.quickstep.OverviewCallbacks;
import com.android.quickstep.SwipeSharedState;
import com.android.quickstep.SysUINavigationMode;
@@ -59,11 +61,8 @@ import com.android.quickstep.util.NavBarPosition;
import com.android.quickstep.util.RecentsAnimationListenerSet;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputMonitorCompat;
-
import java.util.function.Consumer;
-import androidx.annotation.UiThread;
-
/**
* Input consumer for handling events originating from an activity other than Launcher
*/
@@ -119,14 +118,16 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
ActivityManagerWrapper.getInstance().cancelRecentsAnimation(
true /* restoreHomeStackPosition */);
};
+ private int mLogId;
public OtherActivityInputConsumer(Context base, RunningTaskInfo runningTaskInfo,
boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks,
Consumer<OtherActivityInputConsumer> onCompleteCallback,
SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat,
RectF swipeTouchRegion, boolean disableHorizontalSwipe,
- BaseSwipeUpHandler.Factory handlerFactory) {
+ Factory handlerFactory, int logId) {
super(base);
+ mLogId = logId;
mMainThreadHandler = new Handler(Looper.getMainLooper());
mRunningTask = runningTaskInfo;
@@ -341,7 +342,9 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
RecentsAnimationListenerSet newListenerSet =
mSwipeSharedState.newRecentsAnimationListenerSet();
newListenerSet.addListener(handler);
- startRecentsActivityAsync(handler.getLaunchIntent(), newListenerSet);
+ Intent intent = handler.getLaunchIntent();
+ intent.putExtra(INTENT_EXTRA_LOG_TRACE_ID, mLogId);
+ startRecentsActivityAsync(intent, newListenerSet);
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java
index 3ce341d8c..bbb318a02 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java
@@ -21,9 +21,9 @@ import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import android.content.Context;
import android.view.Surface;
-import android.view.WindowManager;
import com.android.launcher3.graphics.RotationMode;
+import com.android.launcher3.util.DefaultDisplay;
import com.android.quickstep.SysUINavigationMode;
/**
@@ -36,8 +36,7 @@ public class NavBarPosition {
public NavBarPosition(Context context) {
mMode = SysUINavigationMode.getMode(context);
- mDisplayRotation = context.getSystemService(WindowManager.class)
- .getDefaultDisplay().getRotation();
+ mDisplayRotation = DefaultDisplay.INSTANCE.get(context).getInfo().rotation;
}
public boolean isRightEdge() {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java
index 14083dd95..b1999d716 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java
@@ -15,11 +15,13 @@
*/
package com.android.quickstep.util;
-import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.graphics.Rect;
import android.util.ArraySet;
+import androidx.annotation.UiThread;
+
import com.android.launcher3.Utilities;
import com.android.launcher3.util.Preconditions;
import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
@@ -31,8 +33,6 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import java.util.Set;
import java.util.function.Consumer;
-import androidx.annotation.UiThread;
-
/**
* Wrapper around {@link RecentsAnimationListener} which delegates callbacks to multiple listeners
* on the main thread
@@ -82,7 +82,7 @@ public class RecentsAnimationListenerSet implements RecentsAnimationListener {
if (mCancelled) {
targetSet.cancelAnimation();
} else {
- Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), () -> {
+ Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
for (SwipeAnimationListener listener : getListeners()) {
listener.onRecentsAnimationStart(targetSet);
}
@@ -92,14 +92,14 @@ public class RecentsAnimationListenerSet implements RecentsAnimationListener {
@Override
public final void onAnimationCanceled(ThumbnailData thumbnailData) {
- Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), () -> {
+ Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
for (SwipeAnimationListener listener : getListeners()) {
listener.onRecentsAnimationCanceled();
}
});
// TODO: handle the transition better instead of simply using a transition delay.
if (thumbnailData != null) {
- MAIN_THREAD_EXECUTOR.getHandler().postDelayed(() -> mController.cleanupScreenshot(),
+ MAIN_EXECUTOR.getHandler().postDelayed(() -> mController.cleanupScreenshot(),
TRANSITION_DELAY);
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java
index 381c27a28..3619d3a0e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java
@@ -15,8 +15,8 @@
*/
package com.android.quickstep.util;
-import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR;
-import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
import android.graphics.Rect;
@@ -68,25 +68,25 @@ public class SwipeAnimationTargetSet extends RemoteAnimationTargetSet {
public void finishController(boolean toRecents, Runnable callback, boolean sendUserLeaveHint) {
mOnFinishListener.accept(this);
- BACKGROUND_EXECUTOR.execute(() -> {
+ UI_HELPER_EXECUTOR.execute(() -> {
controller.setInputConsumerEnabled(false);
controller.finish(toRecents, sendUserLeaveHint);
if (callback != null) {
- MAIN_THREAD_EXECUTOR.execute(callback);
+ MAIN_EXECUTOR.execute(callback);
}
});
}
public void enableInputConsumer() {
- BACKGROUND_EXECUTOR.submit(() -> {
+ UI_HELPER_EXECUTOR.submit(() -> {
controller.hideCurrentInputMethod();
controller.setInputConsumerEnabled(true);
});
}
public void setWindowThresholdCrossed(boolean thresholdCrossed) {
- BACKGROUND_EXECUTOR.execute(() -> {
+ UI_HELPER_EXECUTOR.execute(() -> {
controller.setAnimationTargetsBehindSystemBars(!thresholdCrossed);
if (mShouldMinimizeSplitScreen && thresholdCrossed) {
// NOTE: As a workaround for conflicting animations (Launcher animating the task
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/DigitalWellBeingToast.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/DigitalWellBeingToast.java
index 7fac81385..b06d4bc35 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/DigitalWellBeingToast.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/DigitalWellBeingToast.java
@@ -19,6 +19,7 @@ package com.android.quickstep.views;
import static android.provider.Settings.ACTION_APP_USAGE_SETTINGS;
import static com.android.launcher3.Utilities.prefixTextWithIcon;
+import static com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR;
import android.annotation.TargetApi;
import android.app.ActivityOptions;
@@ -41,7 +42,6 @@ import androidx.annotation.StringRes;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.systemui.shared.recents.model.Task;
@@ -117,7 +117,7 @@ public final class DigitalWellBeingToast {
return;
}
- Utilities.THREAD_POOL_EXECUTOR.execute(() -> {
+ THREAD_POOL_EXECUTOR.execute(() -> {
final AppUsageLimit usageLimit = mLauncherApps.getAppUsageLimit(
task.getTopComponent().getPackageName(),
UserHandle.of(task.key.userId));
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
index 03441c87e..b601834f3 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -57,6 +57,8 @@ import com.android.quickstep.util.LayoutUtils;
@TargetApi(Build.VERSION_CODES.O)
public class LauncherRecentsView extends RecentsView<Launcher> implements StateListener {
+ private static final Rect sTempRect = new Rect();
+
private final TransformParams mTransformParams = new TransformParams();
public LauncherRecentsView(Context context) {
@@ -144,6 +146,25 @@ public class LauncherRecentsView extends RecentsView<Launcher> implements StateL
LayoutUtils.calculateLauncherTaskSize(getContext(), dp, outRect);
}
+ /**
+ * @return The translationX to apply to this view so that the first task is just offscreen.
+ */
+ public float getOffscreenTranslationX(float recentsScale) {
+ float offscreenX = NORMAL.getOverviewScaleAndTranslation(mActivity).translationX;
+ // Offset since scale pushes tasks outwards.
+ getTaskSize(sTempRect);
+ int taskWidth = sTempRect.width();
+ offscreenX += taskWidth * (recentsScale - 1) / 2;
+ if (mRunningTaskTileHidden) {
+ // The first task is hidden, so offset by its width.
+ offscreenX -= (taskWidth + getPageSpacing()) * recentsScale;
+ }
+ if (isRtl()) {
+ offscreenX = -offscreenX;
+ }
+ return offscreenX;
+ }
+
@Override
protected void onTaskLaunchAnimationUpdate(float progress, TaskView tv) {
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
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 d98ef425e..554f4372c 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
@@ -35,9 +35,9 @@ import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
import static com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController.SUCCESS_TRANSITION_PROGRESS;
import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.CLEAR_ALL_BUTTON;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
-import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR;
import android.animation.Animator;
import android.animation.AnimatorSet;
@@ -228,7 +228,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
return;
}
- BACKGROUND_EXECUTOR.execute(() -> {
+ UI_HELPER_EXECUTOR.execute(() -> {
TaskView taskView = getTaskView(taskId);
if (taskView == null) {
return;
@@ -272,7 +272,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
// Only valid until the launcher state changes to NORMAL
protected int mRunningTaskId = -1;
- private boolean mRunningTaskTileHidden;
+ protected boolean mRunningTaskTileHidden;
private Task mTmpRunningTask;
private boolean mRunningTaskIconScaledDown = false;
@@ -306,6 +306,9 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
private Layout mEmptyTextLayout;
private LiveTileOverlay mLiveTileOverlay;
+ // Keeps track of the index where the first TaskView should be
+ private int mTaskViewStartIndex = 0;
+
private BaseActivity.MultiWindowModeChangedListener mMultiWindowModeChangedListener =
(inMultiWindowMode) -> {
if (!inMultiWindowMode && mOverviewStateEnabled) {
@@ -329,7 +332,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
mClearAllButton = (ClearAllButton) LayoutInflater.from(context)
.inflate(R.layout.overview_clear_all_button, this, false);
mClearAllButton.setOnClickListener(this::dismissAllTasks);
-
mTaskViewPool = new ViewPool<>(context, this, R.layout.task, 20 /* max size */,
10 /* initial size */);
@@ -430,7 +432,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
super.onViewRemoved(child);
// Clear the task data for the removed child if it was visible
- if (child != mClearAllButton) {
+ if (child instanceof TaskView) {
TaskView taskView = (TaskView) child;
mHasVisibleTaskData.delete(taskView.getTask().key.id);
mTaskViewPool.recycle(taskView);
@@ -444,7 +446,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
public TaskView getTaskView(int taskId) {
for (int i = 0; i < getTaskViewCount(); i++) {
- TaskView tv = (TaskView) getChildAt(i);
+ TaskView tv = getTaskViewAt(i);
if (tv.getTask() != null && tv.getTask().key != null && tv.getTask().key.id == taskId) {
return tv;
}
@@ -536,28 +538,26 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
}
if (tasks == null || tasks.isEmpty()) {
- removeAllViews();
+ removeTasksViewsAndClearAllButton();
onTaskStackUpdated();
return;
}
- int oldChildCount = getChildCount();
-
// Unload existing visible task data
unloadVisibleTaskData();
- TaskView ignoreRestTaskView =
+ TaskView ignoreResetTaskView =
mIgnoreResetTaskId == -1 ? null : getTaskView(mIgnoreResetTaskId);
final int requiredTaskCount = tasks.size();
if (getTaskViewCount() != requiredTaskCount) {
- if (oldChildCount > 0) {
+ if (indexOfChild(mClearAllButton) != -1) {
removeView(mClearAllButton);
}
- for (int i = getChildCount(); i < requiredTaskCount; i++) {
+ for (int i = getTaskViewCount(); i < requiredTaskCount; i++) {
addView(mTaskViewPool.getView());
}
- while (getChildCount() > requiredTaskCount) {
+ while (getTaskViewCount() > requiredTaskCount) {
removeView(getChildAt(getChildCount() - 1));
}
if (requiredTaskCount > 0) {
@@ -567,17 +567,20 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
// Rebind and reset all task views
for (int i = requiredTaskCount - 1; i >= 0; i--) {
- final int pageIndex = requiredTaskCount - i - 1;
+ final int pageIndex = requiredTaskCount - i - 1 + mTaskViewStartIndex;
final Task task = tasks.get(i);
final TaskView taskView = (TaskView) getChildAt(pageIndex);
taskView.bind(task);
}
+
TaskView runningTaskView = getRunningTaskView();
if (runningTaskView != null) {
setCurrentPage(indexOfChild(runningTaskView));
+ } else if (getTaskViewCount() > 0) {
+ setCurrentPage(indexOfChild(getTaskViewAt(0)));
}
- if (mIgnoreResetTaskId != -1 && getTaskView(mIgnoreResetTaskId) != ignoreRestTaskView) {
+ if (mIgnoreResetTaskId != -1 && getTaskView(mIgnoreResetTaskId) != ignoreResetTaskView) {
// If the taskView mapping is changing, do not preserve the visuals. Since we are
// mostly preserving the first task, and new taskViews are added to the end, it should
// generally map to the same task.
@@ -588,17 +591,28 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
updateEnabledOverlays();
}
+ private void removeTasksViewsAndClearAllButton() {
+ for (int i = getTaskViewCount() - 1; i >= 0; i--) {
+ removeView(getTaskViewAt(i));
+ }
+ if (indexOfChild(mClearAllButton) != -1) {
+ removeView(mClearAllButton);
+ }
+ }
+
public int getTaskViewCount() {
- // Account for the clear all button.
- int childCount = getChildCount();
- return childCount == 0 ? 0 : childCount - 1;
+ int taskViewCount = getChildCount() - mTaskViewStartIndex;
+ if (indexOfChild(mClearAllButton) != -1) {
+ taskViewCount--;
+ }
+ return taskViewCount;
}
protected void onTaskStackUpdated() { }
public void resetTaskVisuals() {
for (int i = getTaskViewCount() - 1; i >= 0; i--) {
- TaskView taskView = (TaskView) getChildAt(i);
+ TaskView taskView = getTaskViewAt(i);
if (mIgnoreResetTaskId != taskView.getTask().key.id) {
taskView.resetVisualProperties();
taskView.setStableAlpha(mContentAlpha);
@@ -704,7 +718,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
}
/**
- * Iterates through all thet asks, and loads the associated task data for newly visible tasks,
+ * Iterates through all the tasks, and loads the associated task data for newly visible tasks,
* and unloads the associated task data for tasks that are no longer visible.
*/
public void loadVisibleTaskData() {
@@ -715,15 +729,16 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
}
int centerPageIndex = getPageNearestToCenterOfScreen();
- int numChildren = getTaskViewCount();
+ int numChildren = getChildCount();
int lower = Math.max(0, centerPageIndex - 2);
int upper = Math.min(centerPageIndex + 2, numChildren - 1);
// Update the task data for the in/visible children
- for (int i = 0; i < numChildren; i++) {
- TaskView taskView = (TaskView) getChildAt(i);
+ for (int i = 0; i < getTaskViewCount(); i++) {
+ TaskView taskView = getTaskViewAt(i);
Task task = taskView.getTask();
- boolean visible = lower <= i && i <= upper;
+ int index = indexOfChild(taskView);
+ boolean visible = lower <= index && index <= upper;
if (visible) {
if (task == mTmpRunningTask) {
// Skip loading if this is the task that we are animating into
@@ -798,6 +813,10 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
return tv == null ? -1 : indexOfChild(tv);
}
+ public int getTaskViewStartIndex() {
+ return mTaskViewStartIndex;
+ }
+
/**
* Reloads the view if anything in recents changed.
*/
@@ -853,10 +872,10 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
*/
public void showCurrentTask(int runningTaskId) {
if (getTaskView(runningTaskId) == null) {
- boolean wasEmpty = getChildCount() == 0;
+ boolean wasEmpty = getTaskViewCount() == 0;
// Add an empty view for now until the task plan is loaded and applied
final TaskView taskView = mTaskViewPool.getView();
- addView(taskView, 0);
+ addView(taskView, mTaskViewStartIndex);
if (wasEmpty) {
addView(mClearAllButton);
}
@@ -922,14 +941,13 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
if (runningTaskView == null) {
// Launch the first task
if (getTaskViewCount() > 0) {
- getTaskViewAt(0).launchTask(true /* animate */);
+ getTaskViewAt(0).launchTask(true);
}
} else {
- TaskView nextTaskView = getNextTaskView();
- if (nextTaskView != null) {
- nextTaskView.launchTask(true /* animate */);
+ if (getNextTaskView() != null) {
+ getNextTaskView().launchTask(true);
} else {
- runningTaskView.launchTask(true /* animate */);
+ runningTaskView.launchTask(true);
}
}
}
@@ -1193,7 +1211,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
int count = getTaskViewCount();
for (int i = 0; i < count; i++) {
- addDismissedTaskAnimations(getChildAt(i), anim, duration);
+ addDismissedTaskAnimations(getTaskViewAt(i), anim, duration);
}
mPendingAnimation = pendingAnimation;
@@ -1201,7 +1219,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
if (onEndListener.isSuccess) {
// Remove all the task views now
ActivityManagerWrapper.getInstance().removeAllRecentTasks();
- removeAllViews();
+ removeTasksViewsAndClearAllButton();
startHome();
}
mPendingAnimation = null;
@@ -1348,26 +1366,50 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
child.setAlpha(mContentAlpha);
}
- /**
- * @return The most recent task that is older than the currently running task. If there is
- * currently no running task or there is no task older than it, then return null.
- */
@Nullable
public TaskView getNextTaskView() {
- TaskView runningTaskView = getRunningTaskView();
- if (runningTaskView == null) {
- return null;
- }
- return getTaskViewAt(indexOfChild(runningTaskView) + 1);
+ return getTaskViewAtByAbsoluteIndex(getRunningTaskIndex() + 1);
}
+ @Nullable
+ public TaskView getPreviousTaskView() {
+ return getTaskViewAtByAbsoluteIndex(getRunningTaskIndex() - 1);
+ }
+
+ @Nullable
+ public TaskView getCurrentPageTaskView() {
+ return getTaskViewAtByAbsoluteIndex(getCurrentPage());
+ }
+
+ @Nullable
+ public TaskView getNextPageTaskView() {
+ return getTaskViewAtByAbsoluteIndex(getNextPage());
+ }
+
+ @Nullable
+ public TaskView getTaskViewNearestToCenterOfScreen() {
+ return getTaskViewAtByAbsoluteIndex(getPageNearestToCenterOfScreen());
+ }
+
+ /**
+ * Returns null instead of indexOutOfBoundsError when index is not in range
+ */
+ @Nullable
public TaskView getTaskViewAt(int index) {
- View child = getChildAt(index);
- return child == mClearAllButton ? null : (TaskView) child;
+ return getTaskViewAtByAbsoluteIndex(index + mTaskViewStartIndex);
+ }
+
+ @Nullable
+ private TaskView getTaskViewAtByAbsoluteIndex(int index) {
+ if (index < getChildCount() && index >= 0) {
+ View child = getChildAt(index);
+ return child instanceof TaskView ? (TaskView) child : null;
+ }
+ return null;
}
public void updateEmptyMessage() {
- boolean isEmpty = getChildCount() == 0;
+ boolean isEmpty = getTaskViewCount() == 0;
boolean hasSizeChanged = mLastMeasureSize.x != getWidth()
|| mLastMeasureSize.y != getHeight();
if (isEmpty == mShowEmptyMessage && !hasSizeChanged) {
@@ -1501,7 +1543,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
throw new IllegalStateException("Another pending animation is still running");
}
- int count = getChildCount();
+ int count = getTaskViewCount();
if (count == 0) {
return new PendingAnimation(new AnimatorSet());
}
@@ -1674,18 +1716,38 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
@Override
protected int computeMinScrollX() {
- if (mIsRtl && mDisallowScrollToClearAll) {
- // We aren't showing the clear all button, so use the leftmost task as the min scroll.
- return getScrollForPage(getTaskViewCount() - 1);
+ if (getTaskViewCount() > 0) {
+ if (mDisallowScrollToClearAll) {
+ // We aren't showing the clear all button,
+ // so use the leftmost task as the min scroll.
+ if (mIsRtl) {
+ return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)));
+ }
+ return getScrollForPage(mTaskViewStartIndex);
+ }
+ if (mIsRtl) {
+ return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)) + 1);
+ }
+ return getScrollForPage(mTaskViewStartIndex);
}
return super.computeMinScrollX();
}
@Override
protected int computeMaxScrollX() {
- if (!mIsRtl && mDisallowScrollToClearAll) {
- // We aren't showing the clear all button, so use the rightmost task as the max scroll.
- return getScrollForPage(getTaskViewCount() - 1);
+ if (getTaskViewCount() > 0) {
+ if (mDisallowScrollToClearAll) {
+ // We aren't showing the clear all button,
+ // so use the rightmost task as the min scroll.
+ if (mIsRtl) {
+ return getScrollForPage(mTaskViewStartIndex);
+ }
+ return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)));
+ }
+ if (mIsRtl) {
+ return getScrollForPage(mTaskViewStartIndex);
+ }
+ return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)) + 1);
}
return super.computeMaxScrollX();
}
@@ -1737,7 +1799,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
int overlayEnabledPage = mOverlayEnabled ? getNextPage() : -1;
int taskCount = getTaskViewCount();
for (int i = 0; i < taskCount; i++) {
- ((TaskView) getChildAt(i)).setOverlayEnabled(i == overlayEnabledPage);
+ getTaskViewAt(i).setOverlayEnabled(i == overlayEnabledPage);
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
index 7f1e8980b..044292aa6 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -39,24 +39,28 @@ import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.Property;
import android.view.View;
+import android.view.ViewGroup;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.Themes;
import com.android.quickstep.TaskOverlayFactory;
import com.android.quickstep.TaskOverlayFactory.TaskOverlay;
import com.android.quickstep.util.TaskCornerRadius;
+import com.android.systemui.plugins.OverviewScreenshotActions;
+import com.android.systemui.plugins.PluginListener;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
/**
* A task in the Recents view.
*/
-public class TaskThumbnailView extends View {
+public class TaskThumbnailView extends View implements PluginListener<OverviewScreenshotActions> {
private final static ColorMatrix COLOR_MATRIX = new ColorMatrix();
private final static ColorMatrix SATURATION_COLOR_MATRIX = new ColorMatrix();
@@ -100,6 +104,7 @@ public class TaskThumbnailView extends View {
private boolean mOverlayEnabled;
private boolean mRotated;
+ private OverviewScreenshotActions mOverviewScreenshotActionsPlugin;
public TaskThumbnailView(Context context) {
this(context, null);
@@ -147,6 +152,11 @@ public class TaskThumbnailView extends View {
mPaint.setShader(null);
mOverlay.reset();
}
+
+ if (mOverviewScreenshotActionsPlugin != null) {
+ mOverviewScreenshotActionsPlugin
+ .setupActions((ViewGroup) getTaskView(), getThumbnail(), mActivity);
+ }
updateThumbnailPaintFilter();
}
@@ -211,6 +221,33 @@ public class TaskThumbnailView extends View {
canvas.restore();
}
+ @Override
+ public void onPluginConnected(OverviewScreenshotActions overviewScreenshotActions,
+ Context context) {
+ mOverviewScreenshotActionsPlugin = overviewScreenshotActions;
+ mOverviewScreenshotActionsPlugin.setupActions(getTaskView(), getThumbnail(), mActivity);
+ }
+
+ @Override
+ public void onPluginDisconnected(OverviewScreenshotActions plugin) {
+ if (mOverviewScreenshotActionsPlugin != null) {
+ mOverviewScreenshotActionsPlugin = null;
+ }
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ PluginManagerWrapper.INSTANCE.get(getContext())
+ .addPluginListener(this, OverviewScreenshotActions.class);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ PluginManagerWrapper.INSTANCE.get(getContext()).removePluginListener(this);
+ }
+
public RectF getInsetsToDrawInFullscreen(boolean isMultiWindowMode) {
// Don't show insets in multi window mode.
return isMultiWindowMode ? EMPTY_RECT_F : mClippedInsets;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java
index 910fa0df6..7beb9db84 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java
@@ -14,16 +14,17 @@
package com.android.launcher3.uioverrides.plugins;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+
import android.content.Context;
import android.os.Looper;
-import com.android.launcher3.LauncherModel;
import com.android.systemui.shared.plugins.PluginInitializer;
public class PluginInitializerImpl implements PluginInitializer {
@Override
public Looper getBgLooper() {
- return LauncherModel.getWorkerLooper();
+ return MODEL_EXECUTOR.getLooper();
}
@Override
diff --git a/quickstep/src/com/android/quickstep/BaseRecentsActivity.java b/quickstep/src/com/android/quickstep/BaseRecentsActivity.java
index c84013257..1ac7ed4a3 100644
--- a/quickstep/src/com/android/quickstep/BaseRecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/BaseRecentsActivity.java
@@ -157,6 +157,6 @@ public abstract class BaseRecentsActivity extends BaseDraggingActivity {
public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
super.dump(prefix, fd, writer, args);
writer.println(prefix + "Misc:");
- dumpMisc(writer);
+ dumpMisc(prefix + "\t", writer);
}
}
diff --git a/quickstep/src/com/android/quickstep/OverviewInteractionState.java b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
index 78b48d77a..858c3b6b3 100644
--- a/quickstep/src/com/android/quickstep/OverviewInteractionState.java
+++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
@@ -15,20 +15,21 @@
*/
package com.android.quickstep;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
+import androidx.annotation.WorkerThread;
+
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.DiscoveryBounce;
import com.android.launcher3.util.MainThreadInitializedObject;
-import com.android.launcher3.util.UiThreadHelper;
import com.android.systemui.shared.recents.ISystemUiProxy;
-import androidx.annotation.WorkerThread;
-
/**
* Sets alpha for the back button
*/
@@ -62,7 +63,7 @@ public class OverviewInteractionState {
// because of its high send frequency and data may be very different than the previous value
// For example, send back alpha on uihandler to avoid flickering when setting its visibility
mUiHandler = new Handler(this::handleUiMessage);
- mBgHandler = new Handler(UiThreadHelper.getBackgroundLooper(), this::handleBgMessage);
+ mBgHandler = new Handler(UI_HELPER_EXECUTOR.getLooper(), this::handleBgMessage);
onNavigationModeChanged(SysUINavigationMode.INSTANCE.get(context)
.addModeChangeListener(this::onNavigationModeChanged));
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index e41dba94c..10f9febfb 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -16,19 +16,22 @@
package com.android.quickstep;
-import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import android.annotation.TargetApi;
import android.app.ActivityManager;
-import android.content.Context;
import android.os.Build;
import android.os.Process;
import android.util.SparseBooleanArray;
-import com.android.launcher3.MainThreadExecutor;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.launcher3.util.LooperExecutor;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.KeyguardManagerCompat;
import com.android.systemui.shared.system.TaskStackChangeListener;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -41,7 +44,8 @@ import java.util.function.Consumer;
public class RecentTasksList extends TaskStackChangeListener {
private final KeyguardManagerCompat mKeyguardManager;
- private final MainThreadExecutor mMainThreadExecutor;
+ private final LooperExecutor mMainThreadExecutor;
+ private final ActivityManagerWrapper mActivityManagerWrapper;
// The list change id, increments as the task list changes in the system
private int mChangeId;
@@ -52,11 +56,13 @@ public class RecentTasksList extends TaskStackChangeListener {
ArrayList<Task> mTasks = new ArrayList<>();
- public RecentTasksList(Context context) {
- mMainThreadExecutor = new MainThreadExecutor();
- mKeyguardManager = new KeyguardManagerCompat(context);
+ public RecentTasksList(LooperExecutor mainThreadExecutor,
+ KeyguardManagerCompat keyguardManager, ActivityManagerWrapper activityManagerWrapper) {
+ mMainThreadExecutor = mainThreadExecutor;
+ mKeyguardManager = keyguardManager;
mChangeId = 1;
- ActivityManagerWrapper.getInstance().registerTaskStackListener(this);
+ mActivityManagerWrapper = activityManagerWrapper;
+ mActivityManagerWrapper.registerTaskStackListener(this);
}
/**
@@ -64,7 +70,7 @@ public class RecentTasksList extends TaskStackChangeListener {
*/
public void getTaskKeys(int numTasks, Consumer<ArrayList<Task>> callback) {
// Kick off task loading in the background
- BACKGROUND_EXECUTOR.execute(() -> {
+ UI_HELPER_EXECUTOR.execute(() -> {
ArrayList<Task> tasks = loadTasksInBackground(numTasks, true /* loadKeysOnly */);
mMainThreadExecutor.execute(() -> callback.accept(tasks));
});
@@ -86,12 +92,12 @@ public class RecentTasksList extends TaskStackChangeListener {
if (mLastLoadedId == mChangeId && (!mLastLoadHadKeysOnly || loadKeysOnly)) {
// The list is up to date, send the callback on the next frame,
// so that requestID can be returned first.
- mMainThreadExecutor.getHandler().post(resultCallback);
+ mMainThreadExecutor.post(resultCallback);
return requestLoadId;
}
// Kick off task loading in the background
- BACKGROUND_EXECUTOR.execute(() -> {
+ UI_HELPER_EXECUTOR.execute(() -> {
ArrayList<Task> tasks = loadTasksInBackground(Integer.MAX_VALUE, loadKeysOnly);
mMainThreadExecutor.execute(() -> {
@@ -136,12 +142,13 @@ public class RecentTasksList extends TaskStackChangeListener {
/**
* Loads and creates a list of all the recent tasks.
*/
- private ArrayList<Task> loadTasksInBackground(int numTasks,
+ @VisibleForTesting
+ ArrayList<Task> loadTasksInBackground(int numTasks,
boolean loadKeysOnly) {
int currentUserId = Process.myUserHandle().getIdentifier();
ArrayList<Task> allTasks = new ArrayList<>();
List<ActivityManager.RecentTaskInfo> rawTasks =
- ActivityManagerWrapper.getInstance().getRecentTasks(numTasks, currentUserId);
+ mActivityManagerWrapper.getRecentTasks(numTasks, currentUserId);
// The raw tasks are given in most-recent to least-recent order, we need to reverse it
Collections.reverse(rawTasks);
diff --git a/quickstep/src/com/android/quickstep/RecentsActivityTracker.java b/quickstep/src/com/android/quickstep/RecentsActivityTracker.java
index f9d2f11cb..4d1d9ef8a 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivityTracker.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivityTracker.java
@@ -15,6 +15,8 @@
*/
package com.android.quickstep;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
@@ -22,7 +24,6 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
-import com.android.launcher3.MainThreadExecutor;
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
import com.android.quickstep.util.RemoteAnimationProvider;
@@ -92,14 +93,10 @@ public class RecentsActivityTracker<T extends BaseRecentsActivity> implements Ac
private static class Scheduler implements Runnable {
private WeakReference<RecentsActivityTracker> mPendingTracker = new WeakReference<>(null);
- private MainThreadExecutor mMainThreadExecutor;
public synchronized void schedule(RecentsActivityTracker tracker) {
mPendingTracker = new WeakReference<>(tracker);
- if (mMainThreadExecutor == null) {
- mMainThreadExecutor = new MainThreadExecutor();
- }
- mMainThreadExecutor.execute(this);
+ MAIN_EXECUTOR.execute(this);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index dfab43459..2e59ed5e4 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -15,6 +15,10 @@
*/
package com.android.quickstep;
+import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
+
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.Executors.createAndStartNewLooper;
import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
import android.annotation.TargetApi;
@@ -22,16 +26,20 @@ import android.app.ActivityManager;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.os.Build;
-import android.os.HandlerThread;
+import android.os.Looper;
import android.os.Process;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.util.Log;
+import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.compat.LauncherAppsCompat.OnAppsChangedCallbackCompat;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.systemui.shared.recents.ISystemUiProxy;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.KeyguardManagerCompat;
import com.android.systemui.shared.system.TaskStackChangeListener;
import java.util.ArrayList;
@@ -61,13 +69,14 @@ public class RecentsModel extends TaskStackChangeListener {
private RecentsModel(Context context) {
mContext = context;
- HandlerThread loaderThread = new HandlerThread("TaskThumbnailIconCache",
- Process.THREAD_PRIORITY_BACKGROUND);
- loaderThread.start();
- mTaskList = new RecentTasksList(context);
- mIconCache = new TaskIconCache(context, loaderThread.getLooper());
- mThumbnailCache = new TaskThumbnailCache(context, loaderThread.getLooper());
+ Looper looper =
+ createAndStartNewLooper("TaskThumbnailIconCache", THREAD_PRIORITY_BACKGROUND);
+ mTaskList = new RecentTasksList(MAIN_EXECUTOR,
+ new KeyguardManagerCompat(context), ActivityManagerWrapper.getInstance());
+ mIconCache = new TaskIconCache(context, looper);
+ mThumbnailCache = new TaskThumbnailCache(context, looper);
ActivityManagerWrapper.getInstance().registerTaskStackListener(this);
+ setupPackageListener();
}
public TaskIconCache getIconCache() {
@@ -166,6 +175,7 @@ public class RecentsModel extends TaskStackChangeListener {
public void onTaskRemoved(int taskId) {
Task.TaskKey dummyKey = new Task.TaskKey(taskId, 0, null, null, 0, 0);
mThumbnailCache.remove(dummyKey);
+ mIconCache.onTaskRemoved(dummyKey);
}
public void setSystemUiProxy(ISystemUiProxy systemUiProxy) {
@@ -200,6 +210,21 @@ public class RecentsModel extends TaskStackChangeListener {
}
}
+ private void setupPackageListener() {
+ LauncherAppsCompat.getInstance(mContext)
+ .addOnAppsChangedCallback(new OnAppsChangedCallbackCompat() {
+ @Override
+ public void onPackageRemoved(String packageName, UserHandle user) {
+ mIconCache.invalidatePackage(packageName);
+ }
+
+ @Override
+ public void onPackageChanged(String packageName, UserHandle user) {
+ mIconCache.invalidatePackage(packageName);
+ }
+ });
+ }
+
public void addThumbnailChangeListener(TaskThumbnailChangeListener listener) {
mThumbnailChangeListeners.add(listener);
}
diff --git a/quickstep/src/com/android/quickstep/TaskIconCache.java b/quickstep/src/com/android/quickstep/TaskIconCache.java
index 07af9b385..289a12970 100644
--- a/quickstep/src/com/android/quickstep/TaskIconCache.java
+++ b/quickstep/src/com/android/quickstep/TaskIconCache.java
@@ -16,6 +16,7 @@
package com.android.quickstep;
import static com.android.launcher3.uioverrides.RecentsUiFactory.GO_LOW_RAM_RECENTS_ENABLED;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.content.ComponentName;
import android.content.Context;
@@ -27,26 +28,25 @@ import android.os.Looper;
import android.util.LruCache;
import android.view.accessibility.AccessibilityManager;
-import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.icons.cache.HandlerRunnable;
-import com.android.launcher3.uioverrides.RecentsUiFactory;
import com.android.launcher3.util.Preconditions;
import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.recents.model.Task.TaskKey;
import com.android.systemui.shared.recents.model.TaskKeyLruCache;
import com.android.systemui.shared.system.ActivityManagerWrapper;
+import java.util.Map;
import java.util.function.Consumer;
/**
* Manages the caching of task icons and related data.
- * TODO: This class should later be merged into IconCache.
+ * TODO(b/138944598): This class should later be merged into IconCache.
*/
public class TaskIconCache {
private final Handler mBackgroundHandler;
- private final MainThreadExecutor mMainThreadExecutor;
private final AccessibilityManager mAccessibilityManager;
private final NormalizedIconLoader mIconLoader;
@@ -67,7 +67,6 @@ public class TaskIconCache {
public TaskIconCache(Context context, Looper backgroundLooper) {
mBackgroundHandler = new Handler(backgroundLooper);
- mMainThreadExecutor = new MainThreadExecutor();
mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
Resources res = context.getResources();
@@ -103,7 +102,7 @@ public class TaskIconCache {
// We don't call back to the provided callback in this case
return;
}
- mMainThreadExecutor.execute(() -> {
+ MAIN_EXECUTOR.execute(() -> {
task.icon = icon;
task.titleDescription = contentDescription;
callback.accept(task);
@@ -149,6 +148,21 @@ public class TaskIconCache {
return label;
}
+
+ void onTaskRemoved(TaskKey taskKey) {
+ mIconCache.remove(taskKey);
+ }
+
+ void invalidatePackage(String packageName) {
+ // TODO(b/138944598): Merge this class into IconCache so we can do this at the base level
+ Map<ComponentName, ActivityInfo> activityInfoCache = mActivityInfoCache.snapshot();
+ for (ComponentName cn : activityInfoCache.keySet()) {
+ if (cn.getPackageName().equals(packageName)) {
+ mActivityInfoCache.remove(cn);
+ }
+ }
+ }
+
public static abstract class IconLoadRequest extends HandlerRunnable {
IconLoadRequest(Handler handler) {
super(handler, null);
diff --git a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
index 57c5a2783..3b50c2623 100644
--- a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
+++ b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
@@ -15,12 +15,14 @@
*/
package com.android.quickstep;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Resources;
import android.os.Handler;
import android.os.Looper;
-import com.android.launcher3.MainThreadExecutor;
+
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.icons.cache.HandlerRunnable;
@@ -30,13 +32,13 @@ import com.android.systemui.shared.recents.model.Task.TaskKey;
import com.android.systemui.shared.recents.model.TaskKeyLruCache;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
+
import java.util.ArrayList;
import java.util.function.Consumer;
public class TaskThumbnailCache {
private final Handler mBackgroundHandler;
- private final MainThreadExecutor mMainThreadExecutor;
private final int mCacheSize;
private final ThumbnailCache mCache;
@@ -94,7 +96,6 @@ public class TaskThumbnailCache {
public TaskThumbnailCache(Context context, Looper backgroundLooper) {
mBackgroundHandler = new Handler(backgroundLooper);
- mMainThreadExecutor = new MainThreadExecutor();
mHighResLoadingState = new HighResLoadingState(context);
Resources res = context.getResources();
@@ -168,7 +169,7 @@ public class TaskThumbnailCache {
// We don't call back to the provided callback in this case
return;
}
- mMainThreadExecutor.execute(() -> {
+ MAIN_EXECUTOR.execute(() -> {
mCache.put(key, thumbnail);
callback.accept(thumbnail);
onEnd();
diff --git a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
index dc6b56eec..26e9eaf01 100644
--- a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
+++ b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
@@ -161,7 +161,7 @@ public class ShelfScrimView extends ScrimView implements NavigationModeChangeLis
mMidProgress = OVERVIEW.getVerticalProgress(mLauncher);
Rect hotseatPadding = dp.getHotseatLayoutPadding();
int hotseatSize = dp.hotseatBarSizePx + dp.getInsets().bottom
- - hotseatPadding.bottom - hotseatPadding.top;
+ + hotseatPadding.bottom + hotseatPadding.top;
float dragHandleTop =
Math.min(hotseatSize, OverviewState.getDefaultSwipeHeight(context, dp));
mDragHandleProgress = 1 - (dragHandleTop / mShiftRange);
diff --git a/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java b/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java
index d0956d1f6..7801775d4 100644
--- a/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java
+++ b/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java
@@ -150,10 +150,10 @@ public class AppPredictionsUITests extends AbstractQuickStepTest {
List<AppTarget> targets = new ArrayList<>(activities.length);
for (LauncherActivityInfo info : activities) {
ComponentName cn = info.getComponentName();
- AppTarget target =
- new AppTarget.Builder(new AppTargetId("app:" + cn), cn.getPackageName(), info.getUser())
- .setClassName(cn.getClassName())
- .build();
+ AppTarget target = new AppTarget.Builder(
+ new AppTargetId("app:" + cn), cn.getPackageName(), info.getUser())
+ .setClassName(cn.getClassName())
+ .build();
targets.add(target);
}
mCallback.onTargetsAvailable(targets);
diff --git a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
new file mode 100644
index 000000000..34eb7f817
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static junit.framework.TestCase.assertNull;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.launcher3.util.LooperExecutor;
+import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.KeyguardManagerCompat;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+@SmallTest
+public class RecentTasksListTest {
+
+ private ActivityManagerWrapper mockActivityManagerWrapper;
+
+ // Class under test
+ private RecentTasksList mRecentTasksList;
+
+ @Before
+ public void setup() {
+ LooperExecutor mockMainThreadExecutor = mock(LooperExecutor.class);
+ KeyguardManagerCompat mockKeyguardManagerCompat = mock(KeyguardManagerCompat.class);
+ mockActivityManagerWrapper = mock(ActivityManagerWrapper.class);
+ mRecentTasksList = new RecentTasksList(mockMainThreadExecutor, mockKeyguardManagerCompat,
+ mockActivityManagerWrapper);
+ }
+
+ @Test
+ public void onTaskRemoved_reloadsAllTasks() {
+ mRecentTasksList.onTaskRemoved(0);
+ verify(mockActivityManagerWrapper, times(1))
+ .getRecentTasks(anyInt(), anyInt());
+ }
+
+ @Test
+ public void onTaskStackChanged_doesNotFetchTasks() {
+ mRecentTasksList.onTaskStackChanged();
+ verify(mockActivityManagerWrapper, times(0))
+ .getRecentTasks(anyInt(), anyInt());
+ }
+
+ @Test
+ public void loadTasksInBackground_onlyKeys_noValidTaskDescription() {
+ ActivityManager.RecentTaskInfo recentTaskInfo = new ActivityManager.RecentTaskInfo();
+ when(mockActivityManagerWrapper.getRecentTasks(anyInt(), anyInt()))
+ .thenReturn(Collections.singletonList(recentTaskInfo));
+
+ List<Task> taskList = mRecentTasksList.loadTasksInBackground(Integer.MAX_VALUE, true);
+
+ assertEquals(1, taskList.size());
+ assertNull(taskList.get(0).taskDescription.getLabel());
+ }
+
+ @Test
+ public void loadTasksInBackground_moreThanKeys_hasValidTaskDescription() {
+ String taskDescription = "Wheeee!";
+ ActivityManager.RecentTaskInfo recentTaskInfo = new ActivityManager.RecentTaskInfo();
+ recentTaskInfo.taskDescription = new ActivityManager.TaskDescription(taskDescription);
+ when(mockActivityManagerWrapper.getRecentTasks(anyInt(), anyInt()))
+ .thenReturn(Collections.singletonList(recentTaskInfo));
+
+ List<Task> taskList = mRecentTasksList.loadTasksInBackground(Integer.MAX_VALUE, false);
+
+ assertEquals(1, taskList.size());
+ assertEquals(taskDescription, taskList.get(0).taskDescription.getLabel());
+ }
+}