Snap for 11697857 from c21b463a33 to 24Q3-release
Change-Id: I40cf37228c43e3110350ecd50e75848a9645b5cf
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
<string name="nav_handle_long_press_handler_class" translatable="false"></string>
|
||||
<string name="assist_utils_class" translatable="false"></string>
|
||||
<string name="assist_state_manager_class" translatable="false"></string>
|
||||
<string name="api_wrapper_class" translatable="false">com.android.launcher3.uioverrides.SystemApiWrapper</string>
|
||||
|
||||
<!-- The number of thumbnails and icons to keep in the cache. The thumbnail cache size also
|
||||
determines how many thumbnails will be fetched in the background. -->
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
<string name="recent_task_option_pin">Pin</string>
|
||||
<!-- Title for an option to enter freeform mode for a given app -->
|
||||
<string name="recent_task_option_freeform">Freeform</string>
|
||||
<!-- Title for an option to enter desktop windowing mode for a given app -->
|
||||
<string name="recent_task_option_desktop">Desktop</string>
|
||||
|
||||
<!-- Recents: The empty recents string. [CHAR LIMIT=NONE] -->
|
||||
<string name="recents_empty_message">No recent items</string>
|
||||
|
||||
@@ -240,7 +240,11 @@ public class PredictionRowView<T extends Context & ActivityContext>
|
||||
icon.reset();
|
||||
if (predictionCount > i) {
|
||||
icon.setVisibility(View.VISIBLE);
|
||||
icon.applyFromWorkspaceItem(mPredictedApps.get(i));
|
||||
WorkspaceItemInfo predictedItem = mPredictedApps.get(i);
|
||||
predictedItem.rank = i;
|
||||
predictedItem.cellX = i;
|
||||
predictedItem.cellY = 0;
|
||||
icon.applyFromWorkspaceItem(predictedItem);
|
||||
} else {
|
||||
icon.setVisibility(predictionCount == 0 ? GONE : INVISIBLE);
|
||||
}
|
||||
|
||||
@@ -56,6 +56,11 @@ class DesktopRecentsTransitionController(
|
||||
systemUiProxy.showDesktopApps(desktopTaskView.display.displayId, transition)
|
||||
}
|
||||
|
||||
/** Launch desktop tasks from recents view */
|
||||
fun moveToDesktop(taskId: Int) {
|
||||
systemUiProxy.moveToDesktop(taskId)
|
||||
}
|
||||
|
||||
private class RemoteDesktopLaunchTransitionRunner(
|
||||
private val desktopTaskView: DesktopTaskView,
|
||||
private val stateManager: StateManager<*>,
|
||||
@@ -99,8 +104,7 @@ class DesktopRecentsTransitionController(
|
||||
finishCallback: IRemoteTransitionFinishedCallback
|
||||
) {}
|
||||
|
||||
override fun onTransitionConsumed(transition: IBinder?, aborted: Boolean) {
|
||||
}
|
||||
override fun onTransitionConsumed(transition: IBinder?, aborted: Boolean) {}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -499,7 +499,7 @@ public class HotseatPredictionController implements DragController.DragListener,
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
dismissTaskMenuView(mTarget);
|
||||
dismissTaskMenuView();
|
||||
pinPrediction(mItemInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,6 @@ import androidx.annotation.MainThread;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.popup.RemoteActionShortcut;
|
||||
@@ -53,6 +52,7 @@ import com.android.launcher3.util.BgObjectWithLooper;
|
||||
import com.android.launcher3.util.MainThreadInitializedObject;
|
||||
import com.android.launcher3.util.Preconditions;
|
||||
import com.android.launcher3.util.SimpleBroadcastReceiver;
|
||||
import com.android.launcher3.views.ActivityContext;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@@ -147,7 +147,7 @@ public final class WellbeingModel extends BgObjectWithLooper {
|
||||
|
||||
@MainThread
|
||||
private SystemShortcut getShortcutForApp(String packageName, int userId,
|
||||
BaseDraggingActivity activity, ItemInfo info, View originalView) {
|
||||
Context context, ItemInfo info, View originalView) {
|
||||
Preconditions.assertUIThread();
|
||||
// Work profile apps are not recognized by digital wellbeing.
|
||||
if (userId != UserHandle.myUserId()) {
|
||||
@@ -171,7 +171,7 @@ public final class WellbeingModel extends BgObjectWithLooper {
|
||||
"getShortcutForApp [" + packageName + "]: action: '" + action.getTitle()
|
||||
+ "'");
|
||||
}
|
||||
return new RemoteActionShortcut(action, activity, info, originalView);
|
||||
return new RemoteActionShortcut(action, context, info, originalView);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,9 +305,10 @@ public final class WellbeingModel extends BgObjectWithLooper {
|
||||
/**
|
||||
* Shortcut factory for generating wellbeing action
|
||||
*/
|
||||
public static final SystemShortcut.Factory<BaseDraggingActivity> SHORTCUT_FACTORY =
|
||||
(activity, info, originalView) -> (info.getTargetComponent() == null) ? null
|
||||
: INSTANCE.get(activity).getShortcutForApp(
|
||||
public static final SystemShortcut.Factory<ActivityContext> SHORTCUT_FACTORY =
|
||||
(context, info, originalView) ->
|
||||
(info.getTargetComponent() == null) ? null
|
||||
: INSTANCE.get(originalView.getContext()).getShortcutForApp(
|
||||
info.getTargetComponent().getPackageName(), info.user.getIdentifier(),
|
||||
activity, info, originalView);
|
||||
originalView.getContext(), info, originalView);
|
||||
}
|
||||
|
||||
+28
-28
@@ -48,7 +48,7 @@ public class DesktopVisibilityController {
|
||||
"persist.wm.debug.desktop_stashing", false);
|
||||
private final Launcher mLauncher;
|
||||
|
||||
private int mVisibleFreeformTasksCount;
|
||||
private int mVisibleDesktopTasksCount;
|
||||
private boolean mInOverviewState;
|
||||
private boolean mBackgroundStateEnabled;
|
||||
private boolean mGestureInProgress;
|
||||
@@ -73,7 +73,7 @@ public class DesktopVisibilityController {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "desktop visible tasks count changed=" + visibleTasksCount);
|
||||
}
|
||||
setVisibleFreeformTasksCount(visibleTasksCount);
|
||||
setVisibleDesktopTasksCount(visibleTasksCount);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -108,51 +108,51 @@ public class DesktopVisibilityController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether freeform windows are visible in desktop mode.
|
||||
* Whether desktop tasks are visible in desktop mode.
|
||||
*/
|
||||
public boolean areFreeformTasksVisible() {
|
||||
boolean freeformTasksVisible = mVisibleFreeformTasksCount > 0;
|
||||
public boolean areDesktopTasksVisible() {
|
||||
boolean desktopTasksVisible = mVisibleDesktopTasksCount > 0;
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "areFreeformTasksVisible: freeformVisible=" + freeformTasksVisible
|
||||
Log.d(TAG, "areDesktopTasksVisible: desktopVisible=" + desktopTasksVisible
|
||||
+ " overview=" + mInOverviewState);
|
||||
}
|
||||
return freeformTasksVisible && !mInOverviewState;
|
||||
return desktopTasksVisible && !mInOverviewState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of visible freeform windows in desktop mode.
|
||||
* Number of visible desktop windows in desktop mode.
|
||||
*/
|
||||
public int getVisibleFreeformTasksCount() {
|
||||
return mVisibleFreeformTasksCount;
|
||||
public int getVisibleDesktopTasksCount() {
|
||||
return mVisibleDesktopTasksCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of freeform windows that are visible and updates launcher visibility based on
|
||||
* Sets the number of desktop windows that are visible and updates launcher visibility based on
|
||||
* it.
|
||||
*/
|
||||
public void setVisibleFreeformTasksCount(int visibleTasksCount) {
|
||||
public void setVisibleDesktopTasksCount(int visibleTasksCount) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "setVisibleFreeformTasksCount: visibleTasksCount=" + visibleTasksCount
|
||||
+ " currentValue=" + mVisibleFreeformTasksCount);
|
||||
Log.d(TAG, "setVisibleDesktopTasksCount: visibleTasksCount=" + visibleTasksCount
|
||||
+ " currentValue=" + mVisibleDesktopTasksCount);
|
||||
}
|
||||
|
||||
if (visibleTasksCount != mVisibleFreeformTasksCount) {
|
||||
final boolean wasVisible = mVisibleFreeformTasksCount > 0;
|
||||
if (visibleTasksCount != mVisibleDesktopTasksCount) {
|
||||
final boolean wasVisible = mVisibleDesktopTasksCount > 0;
|
||||
final boolean isVisible = visibleTasksCount > 0;
|
||||
mVisibleFreeformTasksCount = visibleTasksCount;
|
||||
mVisibleDesktopTasksCount = visibleTasksCount;
|
||||
|
||||
if (wasVisible != isVisible) {
|
||||
if (mVisibleFreeformTasksCount > 0) {
|
||||
if (mVisibleDesktopTasksCount > 0) {
|
||||
setLauncherViewsVisibility(View.INVISIBLE);
|
||||
if (!mInOverviewState) {
|
||||
// When freeform is visible & we're not in overview, we want launcher to
|
||||
// appear paused, this ensures that taskbar displays.
|
||||
// When desktop tasks are visible & we're not in overview, we want launcher
|
||||
// to appear paused, this ensures that taskbar displays.
|
||||
markLauncherPaused();
|
||||
}
|
||||
} else {
|
||||
setLauncherViewsVisibility(View.VISIBLE);
|
||||
// If freeform isn't visible ensure that launcher appears resumed to behave
|
||||
// normally.
|
||||
// If desktop tasks aren't visible, ensure that launcher appears resumed to
|
||||
// behave normally.
|
||||
markLauncherResumed();
|
||||
}
|
||||
}
|
||||
@@ -181,9 +181,9 @@ public class DesktopVisibilityController {
|
||||
if (mInOverviewState) {
|
||||
setLauncherViewsVisibility(View.VISIBLE);
|
||||
markLauncherResumed();
|
||||
} else if (areFreeformTasksVisible() && !mGestureInProgress) {
|
||||
} else if (areDesktopTasksVisible() && !mGestureInProgress) {
|
||||
// Switching out of overview state and gesture finished.
|
||||
// If freeform tasks are still visible, hide launcher again.
|
||||
// If desktop tasks are still visible, hide launcher again.
|
||||
setLauncherViewsVisibility(View.INVISIBLE);
|
||||
markLauncherPaused();
|
||||
}
|
||||
@@ -200,8 +200,8 @@ public class DesktopVisibilityController {
|
||||
if (mBackgroundStateEnabled) {
|
||||
setLauncherViewsVisibility(View.VISIBLE);
|
||||
markLauncherResumed();
|
||||
} else if (areFreeformTasksVisible() && !mGestureInProgress) {
|
||||
// Switching out of background state. If freeform tasks are visible, pause launcher.
|
||||
} else if (areDesktopTasksVisible() && !mGestureInProgress) {
|
||||
// Switching out of background state. If desktop tasks are visible, pause launcher.
|
||||
setLauncherViewsVisibility(View.INVISIBLE);
|
||||
markLauncherPaused();
|
||||
}
|
||||
@@ -251,7 +251,7 @@ public class DesktopVisibilityController {
|
||||
* Handle launcher moving to home due to home gesture or home button press.
|
||||
*/
|
||||
public void onHomeActionTriggered() {
|
||||
if (IS_STASHING_ENABLED && areFreeformTasksVisible()) {
|
||||
if (IS_STASHING_ENABLED && areDesktopTasksVisible()) {
|
||||
SystemUiProxy.INSTANCE.get(mLauncher).stashDesktopApps(mLauncher.getDisplayId());
|
||||
}
|
||||
}
|
||||
@@ -270,7 +270,7 @@ public class DesktopVisibilityController {
|
||||
dragLayer.setVisibility(visibility);
|
||||
}
|
||||
if (mLauncher instanceof QuickstepLauncher ql && ql.getTaskbarUIController() != null
|
||||
&& mVisibleFreeformTasksCount != 0) {
|
||||
&& mVisibleDesktopTasksCount != 0) {
|
||||
ql.getTaskbarUIController().onLauncherVisibilityChanged(visibility == VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ public final class KeyboardQuickSwitchController implements
|
||||
DesktopVisibilityController desktopController =
|
||||
LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
|
||||
final boolean onDesktop =
|
||||
desktopController != null && desktopController.areFreeformTasksVisible();
|
||||
desktopController != null && desktopController.areDesktopTasksVisible();
|
||||
|
||||
if (mModel.isTaskListValid(mTaskListChangeId)) {
|
||||
// When we are opening the KQS with no focus override, check if the first task is
|
||||
|
||||
@@ -219,7 +219,7 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
|
||||
DesktopVisibilityController desktopController =
|
||||
LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
|
||||
final boolean onDesktop =
|
||||
desktopController != null && desktopController.areFreeformTasksVisible();
|
||||
desktopController != null && desktopController.areDesktopTasksVisible();
|
||||
if (onDesktop) {
|
||||
isVisible = false;
|
||||
}
|
||||
@@ -425,15 +425,15 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInOverview() {
|
||||
return mTaskbarLauncherStateController.isInOverview();
|
||||
protected boolean isInOverviewUi() {
|
||||
return mTaskbarLauncherStateController.isInOverviewUi();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canToggleHomeAllApps() {
|
||||
return mLauncher.isResumed()
|
||||
&& !mTaskbarLauncherStateController.isInOverview()
|
||||
&& !mLauncher.areFreeformTasksVisible();
|
||||
&& !mTaskbarLauncherStateController.isInOverviewUi()
|
||||
&& !mLauncher.areDesktopTasksVisible();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -113,8 +113,8 @@ import com.android.launcher3.testing.TestLogging;
|
||||
import com.android.launcher3.testing.shared.TestProtocol;
|
||||
import com.android.launcher3.touch.ItemClickHandler;
|
||||
import com.android.launcher3.touch.ItemClickHandler.ItemClickProxy;
|
||||
import com.android.launcher3.uioverrides.ApiWrapper;
|
||||
import com.android.launcher3.util.ActivityOptionsWrapper;
|
||||
import com.android.launcher3.util.ApiWrapper;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
import com.android.launcher3.util.Executors;
|
||||
@@ -665,7 +665,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
|
||||
LauncherAtom.TaskBarContainer.Builder taskbarBuilder =
|
||||
LauncherAtom.TaskBarContainer.newBuilder();
|
||||
if (mControllers.uiController.isInOverview()) {
|
||||
if (mControllers.uiController.isInOverviewUi()) {
|
||||
taskbarBuilder.setTaskSwitcherContainer(
|
||||
LauncherAtom.TaskSwitcherContainer.newBuilder());
|
||||
}
|
||||
@@ -1120,7 +1120,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
} else if (info.isPromise()) {
|
||||
TestLogging.recordEvent(
|
||||
TestProtocol.SEQUENCE_MAIN, "start: taskbarPromiseIcon");
|
||||
intent = ApiWrapper.getAppMarketActivityIntent(this,
|
||||
intent = ApiWrapper.INSTANCE.get(this).getAppMarketActivityIntent(
|
||||
info.getTargetPackage(), Process.myUserHandle());
|
||||
startActivity(intent);
|
||||
|
||||
|
||||
@@ -375,7 +375,7 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas
|
||||
) {
|
||||
// Taskbar has some touchable elements, take over the full taskbar area
|
||||
if (
|
||||
controllers.uiController.isInOverview &&
|
||||
controllers.uiController.isInOverviewUi &&
|
||||
DisplayController.isTransientTaskbar(context)
|
||||
) {
|
||||
val region =
|
||||
|
||||
@@ -666,8 +666,8 @@ public class TaskbarLauncherStateController {
|
||||
&& !mLauncher.getWorkspace().isOverlayShown();
|
||||
}
|
||||
|
||||
boolean isInOverview() {
|
||||
return mLauncherState == LauncherState.OVERVIEW;
|
||||
boolean isInOverviewUi() {
|
||||
return mLauncherState.overviewUi;
|
||||
}
|
||||
|
||||
private void playStateTransitionAnim(AnimatorSet animatorSet, long duration,
|
||||
|
||||
@@ -58,6 +58,7 @@ import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
@@ -339,12 +340,12 @@ public class TaskbarManager {
|
||||
|
||||
/**
|
||||
* Toggles All Apps for Taskbar or Launcher depending on the current state.
|
||||
*
|
||||
* @param homeAllAppsIntent Intent used if Taskbar is not enabled or Launcher is resumed.
|
||||
*/
|
||||
public void toggleAllApps(Intent homeAllAppsIntent) {
|
||||
public void toggleAllApps() {
|
||||
if (mTaskbarActivityContext == null || mTaskbarActivityContext.canToggleHomeAllApps()) {
|
||||
mContext.startActivity(homeAllAppsIntent);
|
||||
// Home All Apps should be toggled from this class, because the controllers are not
|
||||
// initialized when Taskbar is disabled (i.e. TaskbarActivityContext is null).
|
||||
if (mActivity instanceof Launcher l) l.toggleAllAppsSearch();
|
||||
} else {
|
||||
mTaskbarActivityContext.toggleAllAppsSearch();
|
||||
}
|
||||
|
||||
@@ -985,7 +985,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
DesktopVisibilityController visibilityController =
|
||||
LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
|
||||
if (visibilityController != null && mActivity.isHardwareKeyboard()
|
||||
&& mActivity.isThreeButtonNav() && visibilityController.areFreeformTasksVisible()) {
|
||||
&& mActivity.isThreeButtonNav() && visibilityController.areDesktopTasksVisible()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -193,7 +193,7 @@ public class TaskbarUIController {
|
||||
}
|
||||
|
||||
/** Returns {@code true} if Taskbar is currently within overview. */
|
||||
protected boolean isInOverview() {
|
||||
protected boolean isInOverviewUi() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.launcher3.uioverrides;
|
||||
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Person;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentSender;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.LauncherActivityInfo;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.LauncherUserInfo;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.net.Uri;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.ArrayMap;
|
||||
import android.window.RemoteTransition;
|
||||
|
||||
import com.android.launcher3.Flags;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.proxy.ProxyActivityStarter;
|
||||
import com.android.launcher3.util.StartActivityParams;
|
||||
import com.android.launcher3.util.UserIconInfo;
|
||||
import com.android.quickstep.util.FadeOutRemoteTransition;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A wrapper for the hidden API calls
|
||||
*/
|
||||
public class ApiWrapper {
|
||||
|
||||
public static final boolean TASKBAR_DRAWN_IN_PROCESS = true;
|
||||
|
||||
public static Person[] getPersons(ShortcutInfo si) {
|
||||
Person[] persons = si.getPersons();
|
||||
return persons == null ? Utilities.EMPTY_PERSON_ARRAY : persons;
|
||||
}
|
||||
|
||||
public static Map<String, LauncherActivityInfo> getActivityOverrides(Context context) {
|
||||
return context.getSystemService(LauncherApps.class).getActivityOverrides();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ActivityOptions to play fade-out animation on closing targets
|
||||
*/
|
||||
public static ActivityOptions createFadeOutAnimOptions(Context context) {
|
||||
ActivityOptions options = ActivityOptions.makeBasic();
|
||||
options.setRemoteTransition(new RemoteTransition(new FadeOutRemoteTransition()));
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map of all users on the device to their corresponding UI properties
|
||||
*/
|
||||
public static Map<UserHandle, UserIconInfo> queryAllUsers(Context context) {
|
||||
UserManager um = context.getSystemService(UserManager.class);
|
||||
Map<UserHandle, UserIconInfo> users = new ArrayMap<>();
|
||||
List<UserHandle> usersActual = um.getUserProfiles();
|
||||
if (usersActual != null) {
|
||||
for (UserHandle user : usersActual) {
|
||||
if (android.os.Flags.allowPrivateProfile() && Flags.enablePrivateSpace()) {
|
||||
LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
|
||||
LauncherUserInfo launcherUserInfo = launcherApps.getLauncherUserInfo(user);
|
||||
if (launcherUserInfo == null) {
|
||||
continue;
|
||||
}
|
||||
// UserTypes not supported in Launcher are deemed to be the current
|
||||
// Foreground User.
|
||||
int userType = switch (launcherUserInfo.getUserType()) {
|
||||
case UserManager.USER_TYPE_PROFILE_MANAGED -> UserIconInfo.TYPE_WORK;
|
||||
case UserManager.USER_TYPE_PROFILE_CLONE -> UserIconInfo.TYPE_CLONED;
|
||||
case UserManager.USER_TYPE_PROFILE_PRIVATE -> UserIconInfo.TYPE_PRIVATE;
|
||||
default -> UserIconInfo.TYPE_MAIN;
|
||||
};
|
||||
long serial = launcherUserInfo.getUserSerialNumber();
|
||||
users.put(user, new UserIconInfo(user, userType, serial));
|
||||
} else {
|
||||
long serial = um.getSerialNumberForUser(user);
|
||||
|
||||
// Simple check to check if the provided user is work profile
|
||||
// TODO: Migrate to a better platform API
|
||||
NoopDrawable d = new NoopDrawable();
|
||||
boolean isWork = (d != context.getPackageManager().getUserBadgedIcon(d, user));
|
||||
UserIconInfo info = new UserIconInfo(
|
||||
user,
|
||||
isWork ? UserIconInfo.TYPE_WORK : UserIconInfo.TYPE_MAIN,
|
||||
serial);
|
||||
users.put(user, info);
|
||||
}
|
||||
}
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of the system packages that are installed at user creation.
|
||||
* An empty list denotes that all system packages are installed for that user at creation.
|
||||
*/
|
||||
public static List<String> getPreInstalledSystemPackages(Context context, UserHandle user) {
|
||||
LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
|
||||
if (android.os.Flags.allowPrivateProfile() && Flags.enablePrivateSpace()
|
||||
&& Flags.privateSpaceSysAppsSeparation()) {
|
||||
return launcherApps.getPreInstalledSystemPackages(user);
|
||||
} else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an intent which can be used to start the App Market activity (Installer
|
||||
* Activity).
|
||||
*/
|
||||
public static Intent getAppMarketActivityIntent(Context context, String packageName,
|
||||
UserHandle user) {
|
||||
LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
|
||||
if (android.os.Flags.allowPrivateProfile()
|
||||
&& Flags.enablePrivateSpace()
|
||||
&& (Flags.privateSpaceAppInstallerButton()
|
||||
|| Flags.enablePrivateSpaceInstallShortcut())) {
|
||||
StartActivityParams params = new StartActivityParams((PendingIntent) null, 0);
|
||||
params.intentSender = launcherApps.getAppMarketActivityIntent(packageName, user);
|
||||
ActivityOptions options = ActivityOptions.makeBasic()
|
||||
.setPendingIntentBackgroundActivityStartMode(ActivityOptions
|
||||
.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
|
||||
params.options = options.toBundle();
|
||||
params.requireActivityResult = false;
|
||||
return ProxyActivityStarter.getLaunchIntent(context, params);
|
||||
} else {
|
||||
return new Intent(Intent.ACTION_VIEW)
|
||||
.setData(new Uri.Builder()
|
||||
.scheme("market")
|
||||
.authority("details")
|
||||
.appendQueryParameter("id", packageName)
|
||||
.build())
|
||||
.putExtra(Intent.EXTRA_REFERRER, new Uri.Builder().scheme("android-app")
|
||||
.authority(context.getPackageName()).build());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an intent which can be used to open Private Space Settings.
|
||||
*/
|
||||
public static Intent getPrivateSpaceSettingsIntent(Context context) {
|
||||
if (android.os.Flags.allowPrivateProfile() && Flags.enablePrivateSpace()) {
|
||||
LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
|
||||
IntentSender intentSender = launcherApps.getPrivateSpaceSettingsIntent();
|
||||
if (intentSender == null) {
|
||||
return null;
|
||||
}
|
||||
StartActivityParams params = new StartActivityParams((PendingIntent) null, 0);
|
||||
params.intentSender = intentSender;
|
||||
ActivityOptions options = ActivityOptions.makeBasic()
|
||||
.setPendingIntentBackgroundActivityStartMode(ActivityOptions
|
||||
.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
|
||||
params.options = options.toBundle();
|
||||
params.requireActivityResult = false;
|
||||
return ProxyActivityStarter.getLaunchIntent(context, params);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an activity is flagged as non-resizeable.
|
||||
*/
|
||||
public static boolean isNonResizeableActivity(LauncherActivityInfo lai) {
|
||||
return lai.getActivityInfo().resizeMode == ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
|
||||
}
|
||||
|
||||
private static class NoopDrawable extends ColorDrawable {
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,6 +181,7 @@ import com.android.quickstep.util.unfold.ProxyUnfoldTransitionProvider;
|
||||
import com.android.quickstep.views.FloatingTaskView;
|
||||
import com.android.quickstep.views.OverviewActionsView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
@@ -204,7 +205,7 @@ import java.util.function.BiConsumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class QuickstepLauncher extends Launcher {
|
||||
public class QuickstepLauncher extends Launcher implements RecentsViewContainer {
|
||||
private static final boolean TRACE_LAYOUTS =
|
||||
SystemProperties.getBoolean("persist.debug.trace_layouts", false);
|
||||
private static final String TRACE_RELAYOUT_CLASS =
|
||||
@@ -218,7 +219,8 @@ public class QuickstepLauncher extends Launcher {
|
||||
private DepthController mDepthController;
|
||||
private @Nullable DesktopVisibilityController mDesktopVisibilityController;
|
||||
private QuickstepTransitionManager mAppTransitionManager;
|
||||
private OverviewActionsView mActionsView;
|
||||
|
||||
private OverviewActionsView<?> mActionsView;
|
||||
private TISBindHelper mTISBindHelper;
|
||||
private @Nullable LauncherTaskbarUIController mTaskbarUIController;
|
||||
// Will be updated when dragging from taskbar.
|
||||
@@ -244,12 +246,16 @@ public class QuickstepLauncher extends Launcher {
|
||||
|
||||
private boolean mIsPredictiveBackToHomeInProgress;
|
||||
|
||||
public static QuickstepLauncher getLauncher(Context context) {
|
||||
return fromContext(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupViews() {
|
||||
super.setupViews();
|
||||
|
||||
mActionsView = findViewById(R.id.overview_actions_view);
|
||||
RecentsView overviewPanel = getOverviewPanel();
|
||||
RecentsView<?,?> overviewPanel = getOverviewPanel();
|
||||
SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.get(this);
|
||||
mSplitSelectStateController =
|
||||
new SplitSelectStateController(this, mHandler, getStateManager(),
|
||||
@@ -937,7 +943,7 @@ public class QuickstepLauncher extends Launcher {
|
||||
@Override
|
||||
public void setResumed() {
|
||||
if (mDesktopVisibilityController != null
|
||||
&& mDesktopVisibilityController.areFreeformTasksVisible()
|
||||
&& mDesktopVisibilityController.areDesktopTasksVisible()
|
||||
&& !mDesktopVisibilityController.isRecentsGestureInProgress()) {
|
||||
// Return early to skip setting activity to appear as resumed
|
||||
// TODO(b/255649902): shouldn't be needed when we have a separate launcher state
|
||||
@@ -1055,8 +1061,9 @@ public class QuickstepLauncher extends Launcher {
|
||||
.playPlaceholderDismissAnim(this, splitDismissEvent);
|
||||
}
|
||||
|
||||
public <T extends OverviewActionsView> T getActionsView() {
|
||||
return (T) mActionsView;
|
||||
@Override
|
||||
public OverviewActionsView<?> getActionsView() {
|
||||
return mActionsView;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1284,9 +1291,9 @@ public class QuickstepLauncher extends Launcher {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areFreeformTasksVisible() {
|
||||
public boolean areDesktopTasksVisible() {
|
||||
if (mDesktopVisibilityController != null) {
|
||||
return mDesktopVisibilityController.areFreeformTasksVisible();
|
||||
return mDesktopVisibilityController.areDesktopTasksVisible();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1369,25 +1376,25 @@ public class QuickstepLauncher extends Launcher {
|
||||
}
|
||||
|
||||
private static final class LauncherTaskViewController extends
|
||||
TaskViewTouchController<Launcher> {
|
||||
TaskViewTouchController<QuickstepLauncher> {
|
||||
|
||||
LauncherTaskViewController(Launcher activity) {
|
||||
LauncherTaskViewController(QuickstepLauncher activity) {
|
||||
super(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isRecentsInteractive() {
|
||||
return mActivity.isInState(OVERVIEW) || mActivity.isInState(OVERVIEW_MODAL_TASK);
|
||||
return mContainer.isInState(OVERVIEW) || mContainer.isInState(OVERVIEW_MODAL_TASK);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isRecentsModal() {
|
||||
return mActivity.isInState(OVERVIEW_MODAL_TASK);
|
||||
return mContainer.isInState(OVERVIEW_MODAL_TASK);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onUserControlledAnimationCreated(AnimatorPlaybackController animController) {
|
||||
mActivity.getStateManager().setCurrentUserControlledAnimation(animController);
|
||||
mContainer.getStateManager().setCurrentUserControlledAnimation(animController);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.uioverrides
|
||||
|
||||
import android.app.ActivityOptions
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.content.pm.LauncherActivityInfo
|
||||
import android.content.pm.LauncherApps
|
||||
import android.content.pm.ShortcutInfo
|
||||
import android.os.Flags.allowPrivateProfile
|
||||
import android.os.UserHandle
|
||||
import android.os.UserManager
|
||||
import android.util.ArrayMap
|
||||
import android.window.RemoteTransition
|
||||
import com.android.launcher3.Flags.enablePrivateSpace
|
||||
import com.android.launcher3.Flags.enablePrivateSpaceInstallShortcut
|
||||
import com.android.launcher3.Flags.privateSpaceAppInstallerButton
|
||||
import com.android.launcher3.Flags.privateSpaceSysAppsSeparation
|
||||
import com.android.launcher3.Utilities
|
||||
import com.android.launcher3.proxy.ProxyActivityStarter
|
||||
import com.android.launcher3.util.ApiWrapper
|
||||
import com.android.launcher3.util.StartActivityParams
|
||||
import com.android.launcher3.util.UserIconInfo
|
||||
import com.android.quickstep.util.FadeOutRemoteTransition
|
||||
|
||||
/** A wrapper for the hidden API calls */
|
||||
class SystemApiWrapper(context: Context?) : ApiWrapper(context) {
|
||||
|
||||
override fun getPersons(si: ShortcutInfo) = si.persons ?: Utilities.EMPTY_PERSON_ARRAY
|
||||
|
||||
override fun getActivityOverrides(): Map<String, LauncherActivityInfo> =
|
||||
mContext.getSystemService(LauncherApps::class.java)!!.activityOverrides
|
||||
|
||||
override fun createFadeOutAnimOptions(): ActivityOptions =
|
||||
ActivityOptions.makeBasic().apply {
|
||||
remoteTransition = RemoteTransition(FadeOutRemoteTransition())
|
||||
}
|
||||
|
||||
override fun queryAllUsers(): Map<UserHandle, UserIconInfo> {
|
||||
if (!allowPrivateProfile() || !enablePrivateSpace()) {
|
||||
return super.queryAllUsers()
|
||||
}
|
||||
val users = ArrayMap<UserHandle, UserIconInfo>()
|
||||
mContext.getSystemService(UserManager::class.java)!!.userProfiles?.forEach { user ->
|
||||
mContext.getSystemService(LauncherApps::class.java)!!.getLauncherUserInfo(user)?.apply {
|
||||
users[user] =
|
||||
UserIconInfo(
|
||||
user,
|
||||
when (userType) {
|
||||
UserManager.USER_TYPE_PROFILE_MANAGED -> UserIconInfo.TYPE_WORK
|
||||
UserManager.USER_TYPE_PROFILE_CLONE -> UserIconInfo.TYPE_CLONED
|
||||
UserManager.USER_TYPE_PROFILE_PRIVATE -> UserIconInfo.TYPE_PRIVATE
|
||||
else -> UserIconInfo.TYPE_MAIN
|
||||
},
|
||||
userSerialNumber.toLong()
|
||||
)
|
||||
}
|
||||
}
|
||||
return users
|
||||
}
|
||||
|
||||
override fun getPreInstalledSystemPackages(user: UserHandle): List<String> =
|
||||
if (allowPrivateProfile() && enablePrivateSpace() && privateSpaceSysAppsSeparation())
|
||||
mContext
|
||||
.getSystemService(LauncherApps::class.java)!!
|
||||
.getPreInstalledSystemPackages(user)
|
||||
else ArrayList()
|
||||
|
||||
override fun getAppMarketActivityIntent(packageName: String, user: UserHandle): Intent =
|
||||
if (
|
||||
allowPrivateProfile() &&
|
||||
enablePrivateSpace() &&
|
||||
(privateSpaceAppInstallerButton() || enablePrivateSpaceInstallShortcut())
|
||||
)
|
||||
ProxyActivityStarter.getLaunchIntent(
|
||||
mContext,
|
||||
StartActivityParams(null as PendingIntent?, 0).apply {
|
||||
intentSender =
|
||||
mContext
|
||||
.getSystemService(LauncherApps::class.java)!!
|
||||
.getAppMarketActivityIntent(packageName, user)
|
||||
options =
|
||||
ActivityOptions.makeBasic()
|
||||
.setPendingIntentBackgroundActivityStartMode(
|
||||
ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
|
||||
)
|
||||
.toBundle()
|
||||
requireActivityResult = false
|
||||
}
|
||||
)
|
||||
else super.getAppMarketActivityIntent(packageName, user)
|
||||
|
||||
/** Returns an intent which can be used to open Private Space Settings. */
|
||||
override fun getPrivateSpaceSettingsIntent(): Intent? =
|
||||
if (allowPrivateProfile() && enablePrivateSpace())
|
||||
ProxyActivityStarter.getLaunchIntent(
|
||||
mContext,
|
||||
StartActivityParams(null as PendingIntent?, 0).apply {
|
||||
intentSender =
|
||||
mContext
|
||||
.getSystemService(LauncherApps::class.java)
|
||||
?.privateSpaceSettingsIntent
|
||||
?: return null
|
||||
options =
|
||||
ActivityOptions.makeBasic()
|
||||
.setPendingIntentBackgroundActivityStartMode(
|
||||
ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
|
||||
)
|
||||
.toBundle()
|
||||
requireActivityResult = false
|
||||
}
|
||||
)
|
||||
else null
|
||||
|
||||
override fun isNonResizeableActivity(lai: LauncherActivityInfo) =
|
||||
lai.activityInfo.resizeMode == ActivityInfo.RESIZE_MODE_UNRESIZEABLE
|
||||
}
|
||||
@@ -22,7 +22,6 @@ import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITION
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.allapps.AllAppsTransitionController;
|
||||
@@ -63,7 +62,7 @@ public class BackgroundAppState extends OverviewState {
|
||||
|
||||
@Override
|
||||
public float[] getOverviewScaleAndOffset(Launcher launcher) {
|
||||
return getOverviewScaleAndOffsetForBackgroundState(launcher);
|
||||
return getOverviewScaleAndOffsetForBackgroundState(launcher.getOverviewPanel());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -91,8 +90,8 @@ public class BackgroundAppState extends OverviewState {
|
||||
|
||||
@Override
|
||||
protected float getDepthUnchecked(Context context) {
|
||||
if (Launcher.getLauncher(context).areFreeformTasksVisible()) {
|
||||
// Don't blur the background while freeform tasks are visible
|
||||
if (Launcher.getLauncher(context).areDesktopTasksVisible()) {
|
||||
// Don't blur the background while desktop tasks are visible
|
||||
return BaseDepthController.DEPTH_0_PERCENT;
|
||||
} else if (enableScalingRevealHomeAnimation()) {
|
||||
return BaseDepthController.DEPTH_70_PERCENT;
|
||||
@@ -125,9 +124,7 @@ public class BackgroundAppState extends OverviewState {
|
||||
}
|
||||
|
||||
public static float[] getOverviewScaleAndOffsetForBackgroundState(
|
||||
BaseDraggingActivity activity) {
|
||||
return new float[] {
|
||||
((RecentsView) activity.getOverviewPanel()).getMaxScaleForFullScreen(),
|
||||
NO_OFFSET};
|
||||
RecentsView recentsView) {
|
||||
return new float[] {recentsView.getMaxScaleForFullScreen(), NO_OFFSET};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERV
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.Flags;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
@@ -51,7 +50,7 @@ public class OverviewModalTaskState extends OverviewState {
|
||||
|
||||
@Override
|
||||
public float[] getOverviewScaleAndOffset(Launcher launcher) {
|
||||
return getOverviewScaleAndOffsetForModalState(launcher);
|
||||
return getOverviewScaleAndOffsetForModalState(launcher.getOverviewPanel());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,8 +71,7 @@ public class OverviewModalTaskState extends OverviewState {
|
||||
return super.isTaskbarStashed(launcher);
|
||||
}
|
||||
|
||||
public static float[] getOverviewScaleAndOffsetForModalState(BaseDraggingActivity activity) {
|
||||
RecentsView recentsView = activity.<RecentsView>getOverviewPanel();
|
||||
public static float[] getOverviewScaleAndOffsetForModalState(RecentsView recentsView) {
|
||||
Rect taskSize = recentsView.getSelectedTaskBounds();
|
||||
Rect modalTaskSize = new Rect();
|
||||
recentsView.getModalTaskSize(modalTaskSize);
|
||||
|
||||
@@ -45,8 +45,8 @@ public class QuickSwitchState extends BackgroundAppState {
|
||||
|
||||
@Override
|
||||
public int getWorkspaceScrimColor(Launcher launcher) {
|
||||
if (launcher.areFreeformTasksVisible()) {
|
||||
// No scrim while freeform tasks are visible
|
||||
if (launcher.areDesktopTasksVisible()) {
|
||||
// No scrim while desktop tasks are visible
|
||||
return Color.TRANSPARENT;
|
||||
}
|
||||
DeviceProfile dp = launcher.getDeviceProfile();
|
||||
|
||||
+12
-12
@@ -94,7 +94,7 @@ public class QuickstepAtomicAnimationFactory extends
|
||||
@Override
|
||||
public void prepareForAtomicAnimation(LauncherState fromState, LauncherState toState,
|
||||
StateAnimationConfig config) {
|
||||
RecentsView overview = mActivity.getOverviewPanel();
|
||||
RecentsView overview = mContainer.getOverviewPanel();
|
||||
if ((fromState == OVERVIEW || fromState == OVERVIEW_SPLIT_SELECT) && toState == NORMAL) {
|
||||
overview.switchToScreenshot(() ->
|
||||
overview.finishRecentsAnimation(true /* toRecents */, null));
|
||||
@@ -118,7 +118,7 @@ public class QuickstepAtomicAnimationFactory extends
|
||||
config.setInterpolator(ANIM_WORKSPACE_SCALE, DECELERATE);
|
||||
config.setInterpolator(ANIM_WORKSPACE_FADE, ACCELERATE);
|
||||
|
||||
if (DisplayController.getNavigationMode(mActivity).hasGestures
|
||||
if (DisplayController.getNavigationMode(mContainer).hasGestures
|
||||
&& overview.getTaskViewCount() > 0) {
|
||||
// Overview is going offscreen, so keep it at its current scale and opacity.
|
||||
config.setInterpolator(ANIM_OVERVIEW_SCALE, FINAL_FRAME);
|
||||
@@ -136,7 +136,7 @@ public class QuickstepAtomicAnimationFactory extends
|
||||
config.duration = Math.max(config.duration, scrollDuration);
|
||||
|
||||
// Sync scroll so that it ends before or at the same time as the taskbar animation.
|
||||
if (mActivity.getDeviceProfile().isTaskbarPresent) {
|
||||
if (mContainer.getDeviceProfile().isTaskbarPresent) {
|
||||
config.duration = Math.min(
|
||||
config.duration, QuickstepTransitionManager.getTaskbarToHomeDuration());
|
||||
}
|
||||
@@ -147,7 +147,7 @@ public class QuickstepAtomicAnimationFactory extends
|
||||
config.setInterpolator(ANIM_OVERVIEW_FADE, DECELERATE_1_7);
|
||||
}
|
||||
|
||||
Workspace<?> workspace = mActivity.getWorkspace();
|
||||
Workspace<?> workspace = mContainer.getWorkspace();
|
||||
// Start from a higher workspace scale, but only if we're invisible so we don't jump.
|
||||
boolean isWorkspaceVisible = workspace.getVisibility() == VISIBLE;
|
||||
if (isWorkspaceVisible) {
|
||||
@@ -160,7 +160,7 @@ public class QuickstepAtomicAnimationFactory extends
|
||||
workspace.setScaleX(WORKSPACE_PREPARE_SCALE);
|
||||
workspace.setScaleY(WORKSPACE_PREPARE_SCALE);
|
||||
}
|
||||
Hotseat hotseat = mActivity.getHotseat();
|
||||
Hotseat hotseat = mContainer.getHotseat();
|
||||
boolean isHotseatVisible = hotseat.getVisibility() == VISIBLE && hotseat.getAlpha() > 0;
|
||||
if (!isHotseatVisible) {
|
||||
hotseat.setScaleX(WORKSPACE_PREPARE_SCALE);
|
||||
@@ -168,7 +168,7 @@ public class QuickstepAtomicAnimationFactory extends
|
||||
}
|
||||
} else if ((fromState == NORMAL || fromState == HINT_STATE
|
||||
|| fromState == HINT_STATE_TWO_BUTTON) && toState == OVERVIEW) {
|
||||
if (DisplayController.getNavigationMode(mActivity).hasGestures) {
|
||||
if (DisplayController.getNavigationMode(mContainer).hasGestures) {
|
||||
config.setInterpolator(ANIM_WORKSPACE_SCALE,
|
||||
fromState == NORMAL ? ACCELERATE : OVERSHOOT_1_2);
|
||||
config.setInterpolator(ANIM_WORKSPACE_TRANSLATE, ACCELERATE);
|
||||
@@ -201,18 +201,18 @@ public class QuickstepAtomicAnimationFactory extends
|
||||
} else if (fromState == HINT_STATE && toState == NORMAL) {
|
||||
config.setInterpolator(ANIM_DEPTH, DECELERATE_3);
|
||||
if (mHintToNormalDuration == -1) {
|
||||
ValueAnimator va = getWorkspaceSpringScaleAnimator(mActivity,
|
||||
mActivity.getWorkspace(),
|
||||
toState.getWorkspaceScaleAndTranslation(mActivity).scale);
|
||||
ValueAnimator va = getWorkspaceSpringScaleAnimator(mContainer,
|
||||
mContainer.getWorkspace(),
|
||||
toState.getWorkspaceScaleAndTranslation(mContainer).scale);
|
||||
mHintToNormalDuration = (int) va.getDuration();
|
||||
}
|
||||
config.duration = Math.max(config.duration, mHintToNormalDuration);
|
||||
} else if (fromState == ALL_APPS && toState == NORMAL) {
|
||||
AllAppsSwipeController.applyAllAppsToNormalConfig(mActivity, config);
|
||||
AllAppsSwipeController.applyAllAppsToNormalConfig(mContainer, config);
|
||||
} else if (fromState == NORMAL && toState == ALL_APPS) {
|
||||
AllAppsSwipeController.applyNormalToAllAppsAnimConfig(mActivity, config);
|
||||
AllAppsSwipeController.applyNormalToAllAppsAnimConfig(mContainer, config);
|
||||
} else if (fromState == OVERVIEW && toState == OVERVIEW_SPLIT_SELECT) {
|
||||
SplitAnimationTimings timings = mActivity.getDeviceProfile().isTablet
|
||||
SplitAnimationTimings timings = mContainer.getDeviceProfile().isTablet
|
||||
? SplitAnimationTimings.TABLET_OVERVIEW_TO_SPLIT
|
||||
: SplitAnimationTimings.PHONE_OVERVIEW_TO_SPLIT;
|
||||
config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, clampToProgress(LINEAR,
|
||||
|
||||
+1
@@ -47,6 +47,7 @@ import com.android.launcher3.compat.AccessibilityManagerCompat;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
import com.android.launcher3.touch.SingleAxisSwipeDetector;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
import com.android.launcher3.util.TouchController;
|
||||
import com.android.quickstep.TaskUtils;
|
||||
|
||||
+1
-2
@@ -84,7 +84,6 @@ import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.quickstep.util.MotionPauseDetector;
|
||||
import com.android.quickstep.util.WorkspaceRevealAnim;
|
||||
import com.android.quickstep.views.LauncherRecentsView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
|
||||
|
||||
@@ -108,7 +107,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
|
||||
private final float mMaxYProgress;
|
||||
private final MotionPauseDetector mMotionPauseDetector;
|
||||
private final float mMotionPauseMinDisplacement;
|
||||
private final LauncherRecentsView mRecentsView;
|
||||
private final RecentsView mRecentsView;
|
||||
protected final AnimatorListener mClearStateOnCancelListener =
|
||||
newCancelListener(this::clearState);
|
||||
|
||||
|
||||
+4
-3
@@ -38,12 +38,12 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_O
|
||||
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.touch.AbstractStateChangeTouchController;
|
||||
import com.android.launcher3.touch.SingleAxisSwipeDetector;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
import com.android.launcher3.util.NavigationMode;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
@@ -58,11 +58,12 @@ public class QuickSwitchTouchController extends AbstractStateChangeTouchControll
|
||||
|
||||
protected final RecentsView mOverviewPanel;
|
||||
|
||||
public QuickSwitchTouchController(Launcher launcher) {
|
||||
public QuickSwitchTouchController(QuickstepLauncher launcher) {
|
||||
this(launcher, SingleAxisSwipeDetector.HORIZONTAL);
|
||||
}
|
||||
|
||||
protected QuickSwitchTouchController(Launcher l, SingleAxisSwipeDetector.Direction dir) {
|
||||
protected QuickSwitchTouchController(QuickstepLauncher l,
|
||||
SingleAxisSwipeDetector.Direction dir) {
|
||||
super(l, dir);
|
||||
mOverviewPanel = l.getOverviewPanel();
|
||||
}
|
||||
|
||||
+15
-14
@@ -21,6 +21,7 @@ import static com.android.launcher3.touch.SingleAxisSwipeDetector.DIRECTION_BOTH
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.content.Context;
|
||||
import android.os.VibrationEffect;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@@ -28,7 +29,6 @@ import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.app.animation.Interpolators;
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.LauncherAnimUtils;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
@@ -44,12 +44,13 @@ import com.android.launcher3.views.BaseDragLayer;
|
||||
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
|
||||
import com.android.quickstep.util.VibrationConstants;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
|
||||
/**
|
||||
* Touch controller for handling task view card swipes
|
||||
*/
|
||||
public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
|
||||
public abstract class TaskViewTouchController<CONTAINER extends Context & RecentsViewContainer>
|
||||
extends AnimatorListenerAdapter implements TouchController,
|
||||
SingleAxisSwipeDetector.Listener {
|
||||
|
||||
@@ -63,7 +64,7 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
|
||||
public static final VibrationEffect TASK_DISMISS_VIBRATION_FALLBACK =
|
||||
VibrationConstants.EFFECT_TEXTURE_TICK;
|
||||
|
||||
protected final T mActivity;
|
||||
protected final CONTAINER mContainer;
|
||||
private final SingleAxisSwipeDetector mDetector;
|
||||
private final RecentsView mRecentsView;
|
||||
private final int[] mTempCords = new int[2];
|
||||
@@ -87,13 +88,13 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
|
||||
|
||||
private boolean mIsDismissHapticRunning = false;
|
||||
|
||||
public TaskViewTouchController(T activity) {
|
||||
mActivity = activity;
|
||||
mRecentsView = activity.getOverviewPanel();
|
||||
mIsRtl = Utilities.isRtl(activity.getResources());
|
||||
public TaskViewTouchController(CONTAINER container) {
|
||||
mContainer = container;
|
||||
mRecentsView = container.getOverviewPanel();
|
||||
mIsRtl = Utilities.isRtl(container.getResources());
|
||||
SingleAxisSwipeDetector.Direction dir =
|
||||
mRecentsView.getPagedOrientationHandler().getUpDownSwipeDirection();
|
||||
mDetector = new SingleAxisSwipeDetector(activity, this, dir);
|
||||
mDetector = new SingleAxisSwipeDetector(container, this, dir);
|
||||
}
|
||||
|
||||
private boolean canInterceptTouch(MotionEvent ev) {
|
||||
@@ -113,7 +114,7 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
|
||||
return true;
|
||||
}
|
||||
if (AbstractFloatingView.getTopOpenViewWithType(
|
||||
mActivity, TYPE_TOUCH_CONTROLLER_NO_INTERCEPT) != null) {
|
||||
mContainer, TYPE_TOUCH_CONTROLLER_NO_INTERCEPT) != null) {
|
||||
return false;
|
||||
}
|
||||
return isRecentsInteractive();
|
||||
@@ -159,7 +160,7 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
|
||||
for (int i = 0; i < mRecentsView.getTaskViewCount(); i++) {
|
||||
TaskView view = mRecentsView.getTaskViewAt(i);
|
||||
|
||||
if (mRecentsView.isTaskViewVisible(view) && mActivity.getDragLayer()
|
||||
if (mRecentsView.isTaskViewVisible(view) && mContainer.getDragLayer()
|
||||
.isEventOverView(view, ev)) {
|
||||
// Disable swiping up and down if the task overlay is modal.
|
||||
if (isRecentsModal()) {
|
||||
@@ -179,7 +180,7 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
|
||||
// - It's the focused task if in grid view
|
||||
// - The task is snapped
|
||||
mAllowGoingDown = i == mRecentsView.getCurrentPage()
|
||||
&& DisplayController.getNavigationMode(mActivity).hasGestures
|
||||
&& DisplayController.getNavigationMode(mContainer).hasGestures
|
||||
&& (!mRecentsView.showAsGrid() || mTaskBeingDragged.isFocusedTask())
|
||||
&& mRecentsView.isTaskInExpectedScrollPosition(i);
|
||||
|
||||
@@ -228,7 +229,7 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
|
||||
RecentsPagedOrientationHandler orientationHandler =
|
||||
mRecentsView.getPagedOrientationHandler();
|
||||
mCurrentAnimationIsGoingUp = goingUp;
|
||||
BaseDragLayer dl = mActivity.getDragLayer();
|
||||
BaseDragLayer dl = mContainer.getDragLayer();
|
||||
final int secondaryLayerDimension = orientationHandler.getSecondaryDimension(dl);
|
||||
long maxDuration = 2 * secondaryLayerDimension;
|
||||
int verticalFactor = orientationHandler.getTaskDragDisplacementFactor(mIsRtl);
|
||||
@@ -372,10 +373,10 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
|
||||
MIN_TASK_DISMISS_ANIMATION_DURATION, MAX_TASK_DISMISS_ANIMATION_DURATION);
|
||||
|
||||
mCurrentAnimation.setEndAction(this::clearState);
|
||||
mCurrentAnimation.startWithVelocity(mActivity, goingToEnd, Math.abs(velocity),
|
||||
mCurrentAnimation.startWithVelocity(mContainer, goingToEnd, Math.abs(velocity),
|
||||
mEndDisplacement, animationDuration);
|
||||
if (goingUp && goingToEnd && !mIsDismissHapticRunning) {
|
||||
VibratorWrapper.INSTANCE.get(mActivity).vibrate(TASK_DISMISS_VIBRATION_PRIMITIVE,
|
||||
VibratorWrapper.INSTANCE.get(mContainer).vibrate(TASK_DISMISS_VIBRATION_PRIMITIVE,
|
||||
TASK_DISMISS_VIBRATION_PRIMITIVE_SCALE, TASK_DISMISS_VIBRATION_FALLBACK);
|
||||
mIsDismissHapticRunning = true;
|
||||
}
|
||||
|
||||
+2
-2
@@ -15,13 +15,13 @@
|
||||
*/
|
||||
package com.android.launcher3.uioverrides.touchcontrollers;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.touch.SingleAxisSwipeDetector;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
|
||||
public class TransposedQuickSwitchTouchController extends QuickSwitchTouchController {
|
||||
|
||||
public TransposedQuickSwitchTouchController(Launcher launcher) {
|
||||
public TransposedQuickSwitchTouchController(QuickstepLauncher launcher) {
|
||||
super(launcher, SingleAxisSwipeDetector.VERTICAL);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -27,10 +27,10 @@ import android.os.SystemClock;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.touch.AbstractStateChangeTouchController;
|
||||
import com.android.launcher3.touch.SingleAxisSwipeDetector;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.quickstep.views.AllAppsEduView;
|
||||
@@ -51,7 +51,7 @@ public class TwoButtonNavbarTouchController extends AbstractStateChangeTouchCont
|
||||
|
||||
private int mContinuousTouchCount = 0;
|
||||
|
||||
public TwoButtonNavbarTouchController(Launcher l) {
|
||||
public TwoButtonNavbarTouchController(QuickstepLauncher l) {
|
||||
super(l, l.getDeviceProfile().isVerticalBarLayout()
|
||||
? SingleAxisSwipeDetector.HORIZONTAL : SingleAxisSwipeDetector.VERTICAL);
|
||||
mIsTransposed = l.getDeviceProfile().isVerticalBarLayout();
|
||||
|
||||
@@ -108,7 +108,6 @@ import com.android.launcher3.logging.StatsLogManager;
|
||||
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
|
||||
import com.android.launcher3.statehandlers.DesktopVisibilityController;
|
||||
import com.android.launcher3.statemanager.BaseState;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.launcher3.taskbar.TaskbarThresholdUtils;
|
||||
import com.android.launcher3.taskbar.TaskbarUIController;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
@@ -136,6 +135,7 @@ import com.android.quickstep.util.SwipePipToHomeAnimator;
|
||||
import com.android.quickstep.util.TaskViewSimulator;
|
||||
import com.android.quickstep.util.TransformParams;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.quickstep.views.TaskView.TaskIdAttributeContainer;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
@@ -160,7 +160,7 @@ import java.util.function.Consumer;
|
||||
/**
|
||||
* Handles the navigation gestures when Launcher is the default home activity.
|
||||
*/
|
||||
public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
public abstract class AbsSwipeUpHandler<T extends RecentsViewContainer,
|
||||
Q extends RecentsView, S extends BaseState<S>>
|
||||
extends SwipeUpAnimationLogic implements OnApplyWindowInsetsListener,
|
||||
RecentsAnimationCallbacks.RecentsAnimationListener {
|
||||
@@ -171,7 +171,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
// Fraction of the scroll and transform animation in which the current task fades out
|
||||
private static final float KQS_TASK_FADE_ANIMATION_FRACTION = 0.4f;
|
||||
|
||||
protected final BaseActivityInterface<S, T> mActivityInterface;
|
||||
protected final BaseContainerInterface<S, T> mContainerInterface;
|
||||
protected final InputConsumerProxy mInputConsumerProxy;
|
||||
protected final ActivityInitListener mActivityInitListener;
|
||||
// Callbacks to be made once the recents animation starts
|
||||
@@ -182,7 +182,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
protected @Nullable RecentsAnimationController mRecentsAnimationController;
|
||||
protected @Nullable RecentsAnimationController mDeferredCleanupRecentsAnimationController;
|
||||
protected RecentsAnimationTargets mRecentsAnimationTargets;
|
||||
protected @Nullable T mActivity;
|
||||
protected @Nullable T mContainer;
|
||||
protected @Nullable Q mRecentsView;
|
||||
protected Runnable mGestureEndCallback;
|
||||
protected MultiStateCallback mStateCallback;
|
||||
@@ -192,7 +192,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
private final Runnable mLauncherOnDestroyCallback = () -> {
|
||||
ActiveGestureLog.INSTANCE.addLog("Launcher destroyed", LAUNCHER_DESTROYED);
|
||||
mRecentsView = null;
|
||||
mActivity = null;
|
||||
mContainer = null;
|
||||
mStateCallback.clearState(STATE_LAUNCHER_PRESENT);
|
||||
};
|
||||
|
||||
@@ -347,8 +347,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
long touchTimeMs, boolean continuingLastGesture,
|
||||
InputConsumerController inputConsumer) {
|
||||
super(context, deviceState, gestureState);
|
||||
mActivityInterface = gestureState.getActivityInterface();
|
||||
mActivityInitListener = mActivityInterface.createActivityInitListener(this::onActivityInit);
|
||||
mContainerInterface = gestureState.getContainerInterface();
|
||||
mActivityInitListener =
|
||||
mContainerInterface.createActivityInitListener(this::onActivityInit);
|
||||
mInputConsumerProxy =
|
||||
new InputConsumerProxy(context, /* rotationSupplier = */ () -> {
|
||||
if (mRecentsView == null) {
|
||||
@@ -358,7 +359,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
}, inputConsumer, /* onTouchDownCallback = */ () -> {
|
||||
endRunningWindowAnim(mGestureState.getEndTarget() == HOME /* cancel */);
|
||||
endLauncherTransitionController();
|
||||
}, new InputProxyHandlerFactory(mActivityInterface, mGestureState));
|
||||
}, new InputProxyHandlerFactory(mContainerInterface, mGestureState));
|
||||
mTaskAnimationManager = taskAnimationManager;
|
||||
mTouchTimeMs = touchTimeMs;
|
||||
mContinuingLastGesture = continuingLastGesture;
|
||||
@@ -375,8 +376,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
initStateCallbacks();
|
||||
|
||||
mIsTransientTaskbar = mDp.isTaskbarPresent
|
||||
&& DisplayController.isTransientTaskbar(mActivity);
|
||||
TaskbarUIController controller = mActivityInterface.getTaskbarController();
|
||||
&& DisplayController.isTransientTaskbar(context);
|
||||
TaskbarUIController controller = mContainerInterface.getTaskbarController();
|
||||
mTaskbarAlreadyOpen = controller != null && !controller.isTaskbarStashed();
|
||||
mIsTaskbarAllAppsOpen = controller != null && controller.isTaskbarAllAppsOpen();
|
||||
mTaskbarAppWindowThreshold =
|
||||
@@ -473,16 +474,16 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
return false;
|
||||
}
|
||||
|
||||
T createdActivity = mActivityInterface.getCreatedActivity();
|
||||
if (createdActivity != null) {
|
||||
initTransitionEndpoints(createdActivity.getDeviceProfile());
|
||||
T createdContainer = (T) mContainerInterface.getCreatedContainer();
|
||||
if (createdContainer != null) {
|
||||
initTransitionEndpoints(createdContainer.getDeviceProfile());
|
||||
}
|
||||
final T activity = mActivityInterface.getCreatedActivity();
|
||||
if (mActivity == activity) {
|
||||
final T container = (T) mContainerInterface.getCreatedContainer();
|
||||
if (mContainer == container) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mActivity != null) {
|
||||
if (mContainer != null) {
|
||||
if (mStateCallback.hasStates(STATE_GESTURE_COMPLETED)) {
|
||||
// If the activity has restarted between setting the page scroll settling callback
|
||||
// and actually receiving the callback, just mark the gesture completed
|
||||
@@ -497,23 +498,23 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
mStateCallback.setState(oldState);
|
||||
}
|
||||
mWasLauncherAlreadyVisible = alreadyOnHome;
|
||||
mActivity = activity;
|
||||
mContainer = container;
|
||||
// Override the visibility of the activity until the gesture actually starts and we swipe
|
||||
// up, or until we transition home and the home animation is composed
|
||||
if (alreadyOnHome) {
|
||||
mActivity.clearForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS);
|
||||
mContainer.clearForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS);
|
||||
} else {
|
||||
mActivity.addForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS);
|
||||
mContainer.addForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS);
|
||||
}
|
||||
|
||||
mRecentsView = activity.getOverviewPanel();
|
||||
mRecentsView = container.getOverviewPanel();
|
||||
mRecentsView.setOnPageTransitionEndCallback(null);
|
||||
|
||||
mStateCallback.setState(STATE_LAUNCHER_PRESENT);
|
||||
if (alreadyOnHome) {
|
||||
onLauncherStart();
|
||||
} else {
|
||||
activity.addEventCallback(EVENT_STARTED, mLauncherOnStartCallback);
|
||||
container.addEventCallback(EVENT_STARTED, mLauncherOnStartCallback);
|
||||
}
|
||||
|
||||
// Set up a entire animation lifecycle callback to notify the current recents view when
|
||||
@@ -538,8 +539,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
|
||||
setupRecentsViewUi();
|
||||
mRecentsView.runOnPageScrollsInitialized(this::linkRecentsViewScroll);
|
||||
mActivity.runOnBindToTouchInteractionService(this::onLauncherBindToService);
|
||||
mActivity.addEventCallback(EVENT_DESTROYED, mLauncherOnDestroyCallback);
|
||||
mContainer.runOnBindToTouchInteractionService(this::onLauncherBindToService);
|
||||
mContainer.addEventCallback(EVENT_DESTROYED, mLauncherOnDestroyCallback);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -551,8 +552,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
}
|
||||
|
||||
private void onLauncherStart() {
|
||||
final T activity = mActivityInterface.getCreatedActivity();
|
||||
if (activity == null || mActivity != activity) {
|
||||
final T container = (T) mContainerInterface.getCreatedContainer();
|
||||
if (container == null || mContainer != container) {
|
||||
return;
|
||||
}
|
||||
if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) {
|
||||
@@ -568,7 +569,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
// as that will set the state as BACKGROUND_APP, overriding the animation to NORMAL.
|
||||
if (mGestureState.getEndTarget() != HOME) {
|
||||
Runnable initAnimFactory = () -> {
|
||||
mAnimationFactory = mActivityInterface.prepareRecentsUI(mDeviceState,
|
||||
mAnimationFactory = mContainerInterface.prepareRecentsUI(mDeviceState,
|
||||
mWasLauncherAlreadyVisible, this::onAnimatorPlaybackControllerCreated);
|
||||
maybeUpdateRecentsAttachedState(false /* animate */);
|
||||
if (mGestureState.getEndTarget() != null) {
|
||||
@@ -585,14 +586,14 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
initAnimFactory.run();
|
||||
}
|
||||
}
|
||||
AbstractFloatingView.closeAllOpenViewsExcept(activity, mWasLauncherAlreadyVisible,
|
||||
AbstractFloatingView.closeAllOpenViewsExcept(container, mWasLauncherAlreadyVisible,
|
||||
AbstractFloatingView.TYPE_LISTENER);
|
||||
|
||||
if (mWasLauncherAlreadyVisible) {
|
||||
mStateCallback.setState(STATE_LAUNCHER_DRAWN);
|
||||
} else {
|
||||
SafeCloseable traceToken = TraceHelper.INSTANCE.beginAsyncSection("WTS-init");
|
||||
View dragLayer = activity.getDragLayer();
|
||||
View dragLayer = container.getDragLayer();
|
||||
dragLayer.getViewTreeObserver().addOnDrawListener(new OnDrawListener() {
|
||||
boolean mHandled = false;
|
||||
|
||||
@@ -606,7 +607,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
traceToken.close();
|
||||
dragLayer.post(() ->
|
||||
dragLayer.getViewTreeObserver().removeOnDrawListener(this));
|
||||
if (activity != mActivity) {
|
||||
if (container != mContainer) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -615,7 +616,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
});
|
||||
}
|
||||
|
||||
activity.getRootView().setOnApplyWindowInsetsListener(this);
|
||||
container.getRootView().setOnApplyWindowInsetsListener(this);
|
||||
mStateCallback.setState(STATE_LAUNCHER_STARTED);
|
||||
}
|
||||
|
||||
@@ -631,21 +632,21 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
|
||||
// For the duration of the gesture, in cases where an activity is launched while the
|
||||
// activity is not yet resumed, finish the animation to ensure we get resumed
|
||||
mGestureState.getActivityInterface().setOnDeferredActivityLaunchCallback(
|
||||
mGestureState.getContainerInterface().setOnDeferredActivityLaunchCallback(
|
||||
mOnDeferredActivityLaunch);
|
||||
|
||||
mGestureState.runOnceAtState(STATE_END_TARGET_SET,
|
||||
() -> {
|
||||
mDeviceState.getRotationTouchHelper()
|
||||
.onEndTargetCalculated(mGestureState.getEndTarget(),
|
||||
mActivityInterface);
|
||||
mContainerInterface);
|
||||
});
|
||||
|
||||
notifyGestureStarted();
|
||||
}
|
||||
|
||||
private void onDeferredActivityLaunch() {
|
||||
mActivityInterface.switchRunningTaskViewToScreenshot(
|
||||
mContainerInterface.switchRunningTaskViewToScreenshot(
|
||||
null, () -> {
|
||||
mTaskAnimationManager.finishRunningRecentsAnimation(true /* toHome */);
|
||||
});
|
||||
@@ -706,7 +707,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
public void onMotionPauseDetected() {
|
||||
mHasMotionEverBeenPaused = true;
|
||||
maybeUpdateRecentsAttachedState(true/* animate */, true/* moveRunningTask */);
|
||||
Optional.ofNullable(mActivityInterface.getTaskbarController())
|
||||
Optional.ofNullable(mContainerInterface.getTaskbarController())
|
||||
.ifPresent(TaskbarUIController::startTranslationSpring);
|
||||
if (!mIsInAllAppsRegion) {
|
||||
performHapticFeedback();
|
||||
@@ -812,7 +813,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
*/
|
||||
private void setIsInAllAppsRegion(boolean isInAllAppsRegion) {
|
||||
if (mIsInAllAppsRegion == isInAllAppsRegion
|
||||
|| !mActivityInterface.allowAllAppsFromOverview()) {
|
||||
|| !mContainerInterface.allowAllAppsFromOverview()) {
|
||||
return;
|
||||
}
|
||||
mIsInAllAppsRegion = isInAllAppsRegion;
|
||||
@@ -821,8 +822,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
VibratorWrapper.INSTANCE.get(mContext).vibrate(OVERVIEW_HAPTIC);
|
||||
maybeUpdateRecentsAttachedState(true);
|
||||
|
||||
if (mActivity != null) {
|
||||
mActivity.getAppsView().getSearchUiManager().prepareToFocusEditText(mIsInAllAppsRegion);
|
||||
if (mContainer != null) {
|
||||
mContainer.getAppsView().getSearchUiManager()
|
||||
.prepareToFocusEditText(mIsInAllAppsRegion);
|
||||
}
|
||||
|
||||
// Draw active task below Launcher so that All Apps can appear over it.
|
||||
@@ -835,7 +837,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
if (!canCreateNewOrUpdateExistingLauncherTransitionController()) {
|
||||
return;
|
||||
}
|
||||
initTransitionEndpoints(mActivity.getDeviceProfile());
|
||||
initTransitionEndpoints(mContainer.getDeviceProfile());
|
||||
mAnimationFactory.createActivityInterface(mTransitionDragLength);
|
||||
}
|
||||
|
||||
@@ -846,7 +848,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
*/
|
||||
private boolean canCreateNewOrUpdateExistingLauncherTransitionController() {
|
||||
return mGestureState.getEndTarget() != HOME
|
||||
&& !mHasEndedLauncherTransition && mActivity != null;
|
||||
&& !mHasEndedLauncherTransition && mContainer != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -930,11 +932,11 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
// needs to be canceled
|
||||
mRecentsAnimationController.setWillFinishToHome(swipeUpThresholdPassed);
|
||||
|
||||
if (mActivity == null) return;
|
||||
if (mContainer == null) return;
|
||||
if (swipeUpThresholdPassed) {
|
||||
mActivity.getSystemUiController().updateUiState(UI_STATE_FULLSCREEN_TASK, 0);
|
||||
mContainer.getSystemUiController().updateUiState(UI_STATE_FULLSCREEN_TASK, 0);
|
||||
} else {
|
||||
mActivity.getSystemUiController().updateUiState(
|
||||
mContainer.getSystemUiController().updateUiState(
|
||||
UI_STATE_FULLSCREEN_TASK, centermostTaskFlags);
|
||||
}
|
||||
}
|
||||
@@ -962,7 +964,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
|
||||
// Only initialize the device profile, if it has not been initialized before, as in some
|
||||
// configurations targets.homeContentInsets may not be correct.
|
||||
if (mActivity == null) {
|
||||
if (mContainer == null) {
|
||||
RemoteAnimationTarget primaryTaskTarget = targets.apps[0];
|
||||
// orientation state is independent of which remote target handle we use since both
|
||||
// should be pointing to the same one. Just choose index 0 for now since that works for
|
||||
@@ -971,7 +973,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
.getOrientationState();
|
||||
DeviceProfile dp = orientationState.getLauncherDeviceProfile();
|
||||
if (targets.minimizedHomeBounds != null && primaryTaskTarget != null) {
|
||||
Rect overviewStackBounds = mActivityInterface
|
||||
Rect overviewStackBounds = mContainerInterface
|
||||
.getOverviewWindowBounds(targets.minimizedHomeBounds, primaryTaskTarget);
|
||||
dp = dp.getMultiWindowProfile(mContext,
|
||||
new WindowBounds(overviewStackBounds, targets.homeContentInsets));
|
||||
@@ -1014,7 +1016,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
|
||||
@UiThread
|
||||
public void onGestureStarted(boolean isLikelyToStartNewTask) {
|
||||
mActivityInterface.closeOverlay();
|
||||
mContainerInterface.closeOverlay();
|
||||
TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
|
||||
|
||||
if (mRecentsView != null) {
|
||||
@@ -1074,11 +1076,11 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
*/
|
||||
@UiThread
|
||||
private void notifyGestureStarted() {
|
||||
final T curActivity = mActivity;
|
||||
final T curActivity = mContainer;
|
||||
if (curActivity != null) {
|
||||
// Once the gesture starts, we can no longer transition home through the button, so
|
||||
// reset the force override of the activity visibility
|
||||
mActivity.clearForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS);
|
||||
mContainer.clearForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1147,7 +1149,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
maybeUpdateRecentsAttachedState(false);
|
||||
final GestureEndTarget endTarget = mGestureState.getEndTarget();
|
||||
// Wait until the given View (if supplied) draws before resuming the last task.
|
||||
View postResumeLastTask = mActivityInterface.onSettledOnEndTarget(endTarget);
|
||||
View postResumeLastTask = mContainerInterface.onSettledOnEndTarget(endTarget);
|
||||
|
||||
if (endTarget != NEW_TASK) {
|
||||
InteractionJankMonitorWrapper.cancel(Cuj.CUJ_LAUNCHER_QUICK_SWITCH);
|
||||
@@ -1168,7 +1170,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
// Notify the SysUI to use fade-in animation when entering PiP
|
||||
SystemUiProxy.INSTANCE.get(mContext).setPipAnimationTypeToAlpha();
|
||||
DesktopVisibilityController desktopVisibilityController =
|
||||
mActivityInterface.getDesktopVisibilityController();
|
||||
mContainerInterface.getDesktopVisibilityController();
|
||||
if (desktopVisibilityController != null) {
|
||||
// Notify the SysUI to stash desktop apps if they are visible
|
||||
desktopVisibilityController.onHomeActionTriggered();
|
||||
@@ -1357,7 +1359,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
}
|
||||
}
|
||||
Interpolator interpolator;
|
||||
S state = mActivityInterface.stateFromGestureEndTarget(endTarget);
|
||||
S state = mContainerInterface.stateFromGestureEndTarget(endTarget);
|
||||
if (isKeyboardTaskFocusPending()) {
|
||||
interpolator = EMPHASIZED;
|
||||
} else if (state.displayOverviewTasksAsGrid(mDp)) {
|
||||
@@ -1372,7 +1374,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
mInputConsumerProxy.enable();
|
||||
}
|
||||
if (endTarget == HOME) {
|
||||
duration = mActivity != null && mActivity.getDeviceProfile().isTaskbarPresent
|
||||
duration = mContainer != null && mContainer.getDeviceProfile().isTaskbarPresent
|
||||
? StaggeredWorkspaceAnim.DURATION_TASKBAR_MS
|
||||
: StaggeredWorkspaceAnim.DURATION_MS;
|
||||
// Early detach the nav bar once the endTarget is determined as HOME
|
||||
@@ -1509,14 +1511,14 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
if (mGestureState.getEndTarget().isLauncher) {
|
||||
// This is also called when the launcher is resumed, in order to clear the pending
|
||||
// widgets that have yet to be configured.
|
||||
if (mActivity != null) {
|
||||
DragView.removeAllViews(mActivity);
|
||||
if (mContainer != null) {
|
||||
DragView.removeAllViews(mContainer);
|
||||
}
|
||||
|
||||
TaskStackChangeListeners.getInstance().registerTaskStackListener(
|
||||
mActivityRestartListener);
|
||||
|
||||
mParallelRunningAnim = mActivityInterface.getParallelAnimationToLauncher(
|
||||
mParallelRunningAnim = mContainerInterface.getParallelAnimationToLauncher(
|
||||
mGestureState.getEndTarget(), duration,
|
||||
mTaskAnimationManager.getCurrentCallbacks());
|
||||
if (mParallelRunningAnim != null) {
|
||||
@@ -1614,7 +1616,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
if (windowAnimation == null) {
|
||||
continue;
|
||||
}
|
||||
DeviceProfile dp = mActivity == null ? null : mActivity.getDeviceProfile();
|
||||
DeviceProfile dp = mContainer == null ? null : mContainer.getDeviceProfile();
|
||||
windowAnimation.start(mContext, dp, velocityPxPerMs);
|
||||
mRunningWindowAnim[i] = RunningWindowAnim.wrap(windowAnimation);
|
||||
}
|
||||
@@ -1867,7 +1869,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
}
|
||||
// Make sure recents is in its final state
|
||||
maybeUpdateRecentsAttachedState(false);
|
||||
mActivityInterface.onSwipeUpToHomeComplete(mDeviceState);
|
||||
mContainerInterface.onSwipeUpToHomeComplete(mDeviceState);
|
||||
}
|
||||
});
|
||||
if (mRecentsAnimationTargets != null) {
|
||||
@@ -1941,8 +1943,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
|
||||
private void reset() {
|
||||
mStateCallback.setStateOnUiThread(STATE_HANDLER_INVALIDATED);
|
||||
if (mActivity != null) {
|
||||
mActivity.removeEventCallback(EVENT_DESTROYED, mLauncherOnDestroyCallback);
|
||||
if (mContainer != null) {
|
||||
mContainer.removeEventCallback(EVENT_DESTROYED, mLauncherOnDestroyCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1966,7 +1968,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
}
|
||||
|
||||
private void invalidateHandler() {
|
||||
if (!mActivityInterface.isInLiveTileMode() || mGestureState.getEndTarget() != RECENTS) {
|
||||
if (!mContainerInterface.isInLiveTileMode() || mGestureState.getEndTarget() != RECENTS) {
|
||||
mInputConsumerProxy.destroy();
|
||||
mTaskAnimationManager.setLiveTileCleanUpHandler(null);
|
||||
}
|
||||
@@ -2013,11 +2015,11 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
* continued quick switch gesture, which cancels the previous handler but doesn't invalidate it.
|
||||
*/
|
||||
private void resetLauncherListeners() {
|
||||
if (mActivity != null) {
|
||||
mActivity.removeEventCallback(EVENT_STARTED, mLauncherOnStartCallback);
|
||||
mActivity.removeEventCallback(EVENT_DESTROYED, mLauncherOnDestroyCallback);
|
||||
if (mContainer != null) {
|
||||
mContainer.removeEventCallback(EVENT_STARTED, mLauncherOnStartCallback);
|
||||
mContainer.removeEventCallback(EVENT_DESTROYED, mLauncherOnDestroyCallback);
|
||||
|
||||
mActivity.getRootView().setOnApplyWindowInsetsListener(null);
|
||||
mContainer.getRootView().setOnApplyWindowInsetsListener(null);
|
||||
}
|
||||
if (mRecentsView != null) {
|
||||
mRecentsView.removeOnScrollChangedListener(mOnRecentsScrollListener);
|
||||
@@ -2026,11 +2028,11 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
|
||||
private void resetStateForAnimationCancel() {
|
||||
boolean wasVisible = mWasLauncherAlreadyVisible || mGestureStarted;
|
||||
mActivityInterface.onTransitionCancelled(wasVisible, mGestureState.getEndTarget());
|
||||
mContainerInterface.onTransitionCancelled(wasVisible, mGestureState.getEndTarget());
|
||||
|
||||
// Leave the pending invisible flag, as it may be used by wallpaper open animation.
|
||||
if (mActivity != null) {
|
||||
mActivity.clearForceInvisibleFlag(INVISIBLE_BY_STATE_HANDLER);
|
||||
if (mContainer != null) {
|
||||
mContainer.clearForceInvisibleFlag(INVISIBLE_BY_STATE_HANDLER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2296,14 +2298,14 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
onRestartPreviouslyAppearedTask();
|
||||
}
|
||||
} else {
|
||||
mActivityInterface.onLaunchTaskFailed();
|
||||
mContainerInterface.onLaunchTaskFailed();
|
||||
if (mRecentsAnimationController != null) {
|
||||
mRecentsAnimationController.finish(true /* toRecents */, null);
|
||||
}
|
||||
}
|
||||
}, true /* freezeTaskList */);
|
||||
} else {
|
||||
mActivityInterface.onLaunchTaskFailed();
|
||||
mContainerInterface.onLaunchTaskFailed();
|
||||
Toast.makeText(mContext, R.string.activity_not_available, LENGTH_SHORT).show();
|
||||
if (mRecentsAnimationController != null) {
|
||||
mRecentsAnimationController.finish(true /* toRecents */, null);
|
||||
@@ -2395,12 +2397,12 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
finishRecentsAnimationOnTasksAppeared(null /* onFinishComplete */);
|
||||
return;
|
||||
}
|
||||
if (mActivity == null) {
|
||||
if (mContainer == null) {
|
||||
ActiveGestureLog.INSTANCE.addLog("Activity destroyed");
|
||||
finishRecentsAnimationOnTasksAppeared(null /* onFinishComplete */);
|
||||
return;
|
||||
}
|
||||
animateSplashScreenExit(mActivity, appearedTaskTargets, taskTarget.leash);
|
||||
animateSplashScreenExit(mContainer, appearedTaskTargets, taskTarget.leash);
|
||||
}
|
||||
|
||||
private void animateSplashScreenExit(
|
||||
@@ -2515,7 +2517,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
transaction.setAlpha(app.leash, 1f - fadeProgress);
|
||||
transaction.setPosition(app.leash,
|
||||
/* x= */ app.startBounds.left
|
||||
+ (mActivity.getDeviceProfile().overviewPageSpacing
|
||||
+ (mContainer.getDeviceProfile().overviewPageSpacing
|
||||
* (mRecentsView.isRtl() ? fadeProgress : -fadeProgress)),
|
||||
/* y= */ 0f);
|
||||
transaction.setScale(app.leash, 1f, 1f);
|
||||
@@ -2566,7 +2568,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
|
||||
// Scaling of RecentsView during quick switch based on amount of recents scroll
|
||||
private float getScaleProgressDueToScroll() {
|
||||
if (mActivity == null || !mActivity.getDeviceProfile().isTablet || mRecentsView == null
|
||||
if (mContainer == null || !mContainer.getDeviceProfile().isTablet || mRecentsView == null
|
||||
|| !shouldLinkRecentsViewScroll()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -18,11 +18,9 @@ package com.android.quickstep;
|
||||
import static com.android.app.animation.Interpolators.ACCELERATE_2;
|
||||
import static com.android.app.animation.Interpolators.INSTANT;
|
||||
import static com.android.app.animation.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
|
||||
import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe;
|
||||
import static com.android.quickstep.AbsSwipeUpHandler.RECENTS_ATTACH_DURATION;
|
||||
import static com.android.quickstep.GestureState.GestureEndTarget.LAST_TASK;
|
||||
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
|
||||
import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_FADE_ANIM;
|
||||
import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_TRANSLATE_X_ANIM;
|
||||
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
|
||||
@@ -33,23 +31,12 @@ import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.RemoteAnimationTarget;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Flags;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.statehandlers.DepthController;
|
||||
@@ -57,29 +44,23 @@ import com.android.launcher3.statehandlers.DesktopVisibilityController;
|
||||
import com.android.launcher3.statemanager.BaseState;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.launcher3.taskbar.TaskbarUIController;
|
||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
import com.android.launcher3.util.NavigationMode;
|
||||
import com.android.launcher3.views.ScrimView;
|
||||
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
|
||||
import com.android.quickstep.util.ActivityInitListener;
|
||||
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Utility class which abstracts out the logical differences between Launcher and RecentsActivity.
|
||||
*/
|
||||
public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_TYPE>,
|
||||
ACTIVITY_TYPE extends StatefulActivity<STATE_TYPE>> {
|
||||
|
||||
public final boolean rotationSupportedByActivity;
|
||||
|
||||
ACTIVITY_TYPE extends StatefulActivity<STATE_TYPE> & RecentsViewContainer> extends
|
||||
BaseContainerInterface<STATE_TYPE, ACTIVITY_TYPE> {
|
||||
private final STATE_TYPE mBackgroundState;
|
||||
|
||||
private STATE_TYPE mTargetState;
|
||||
@@ -100,7 +81,7 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
*/
|
||||
public void onTransitionCancelled(boolean activityVisible,
|
||||
@Nullable GestureState.GestureEndTarget endTarget) {
|
||||
ACTIVITY_TYPE activity = getCreatedActivity();
|
||||
ACTIVITY_TYPE activity = getCreatedContainer();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
@@ -109,12 +90,12 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
// We were on our way to this state when we got canceled, end there instead.
|
||||
startState = stateFromGestureEndTarget(endTarget);
|
||||
DesktopVisibilityController controller = getDesktopVisibilityController();
|
||||
if (controller != null && controller.areFreeformTasksVisible()
|
||||
if (controller != null && controller.areDesktopTasksVisible()
|
||||
&& endTarget == LAST_TASK) {
|
||||
// When we are cancelling the transition and going back to last task, move to
|
||||
// rest state instead when desktop tasks are visible.
|
||||
// If a fullscreen task is visible, launcher goes to normal state when the
|
||||
// activity is stopped. This does not happen when freeform tasks are visible
|
||||
// activity is stopped. This does not happen when desktop tasks are visible
|
||||
// on top of launcher. Force the launcher state to rest state here.
|
||||
startState = activity.getStateManager().getRestState();
|
||||
// Do not animate the transition
|
||||
@@ -124,49 +105,21 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
activity.getStateManager().goToState(startState, activityVisible);
|
||||
}
|
||||
|
||||
public abstract int getSwipeUpDestinationAndLength(
|
||||
DeviceProfile dp, Context context, Rect outRect,
|
||||
RecentsPagedOrientationHandler orientationHandler);
|
||||
|
||||
/** Called when the animation to home has fully settled. */
|
||||
public void onSwipeUpToHomeComplete(RecentsAnimationDeviceState deviceState) {}
|
||||
|
||||
public abstract void onAssistantVisibilityChanged(float visibility);
|
||||
|
||||
public abstract AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
|
||||
boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback);
|
||||
|
||||
public abstract ActivityInitListener createActivityInitListener(
|
||||
Predicate<Boolean> onInitListener);
|
||||
|
||||
/**
|
||||
* Sets a callback to be run when an activity launch happens while launcher is not yet resumed.
|
||||
*/
|
||||
public void setOnDeferredActivityLaunchCallback(Runnable r) {}
|
||||
|
||||
@Nullable
|
||||
public abstract ACTIVITY_TYPE getCreatedActivity();
|
||||
public abstract ACTIVITY_TYPE getCreatedContainer();
|
||||
|
||||
@Nullable
|
||||
public DepthController getDepthController() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public DesktopVisibilityController getDesktopVisibilityController() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public abstract TaskbarUIController getTaskbarController();
|
||||
|
||||
public final boolean isResumed() {
|
||||
ACTIVITY_TYPE activity = getCreatedActivity();
|
||||
ACTIVITY_TYPE activity = getCreatedContainer();
|
||||
return activity != null && activity.hasBeenResumed();
|
||||
}
|
||||
|
||||
public final boolean isStarted() {
|
||||
ACTIVITY_TYPE activity = getCreatedActivity();
|
||||
ACTIVITY_TYPE activity = getCreatedContainer();
|
||||
return activity != null && activity.isStarted();
|
||||
}
|
||||
|
||||
@@ -177,14 +130,6 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
@UiThread
|
||||
public abstract boolean switchToRecentsIfVisible(Animator.AnimatorListener animatorListener);
|
||||
|
||||
public abstract Rect getOverviewWindowBounds(
|
||||
Rect homeBounds, RemoteAnimationTarget target);
|
||||
|
||||
public abstract boolean allowMinimizeSplitScreen();
|
||||
|
||||
/** @return whether to allow going to All Apps from Overview. */
|
||||
public abstract boolean allowAllAppsFromOverview();
|
||||
|
||||
public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
|
||||
TaskbarUIController controller = getTaskbarController();
|
||||
boolean isEventOverBubbleBarStashHandle =
|
||||
@@ -193,20 +138,6 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
|| isTrackpadMultiFingerSwipe(ev) || isEventOverBubbleBarStashHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the gesture in progress should be cancelled.
|
||||
*/
|
||||
public boolean shouldCancelCurrentGesture() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract void onExitOverview(RotationTouchHelper deviceState,
|
||||
Runnable exitRunnable);
|
||||
|
||||
public abstract boolean isInLiveTileMode();
|
||||
|
||||
public abstract void onLaunchTaskFailed();
|
||||
|
||||
/**
|
||||
* Closes any overlays.
|
||||
*/
|
||||
@@ -217,7 +148,7 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
|
||||
public void switchRunningTaskViewToScreenshot(HashMap<Integer, ThumbnailData> thumbnailDatas,
|
||||
Runnable runnable) {
|
||||
ACTIVITY_TYPE activity = getCreatedActivity();
|
||||
ACTIVITY_TYPE activity = getCreatedContainer();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
@@ -231,230 +162,9 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
recentsView.switchToScreenshot(thumbnailDatas, runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the taskView size for the provided device configuration.
|
||||
*/
|
||||
public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect,
|
||||
PagedOrientationHandler orientedState) {
|
||||
if (dp.isTablet) {
|
||||
if (Flags.enableGridOnlyOverview()) {
|
||||
calculateGridTaskSize(context, dp, outRect, orientedState);
|
||||
} else {
|
||||
calculateFocusTaskSize(context, dp, outRect);
|
||||
}
|
||||
} else {
|
||||
Resources res = context.getResources();
|
||||
float maxScale = res.getFloat(R.dimen.overview_max_scale);
|
||||
int taskMargin = dp.overviewTaskMarginPx;
|
||||
calculateTaskSizeInternal(
|
||||
context,
|
||||
dp,
|
||||
dp.overviewTaskThumbnailTopMarginPx,
|
||||
dp.getOverviewActionsClaimedSpace(),
|
||||
res.getDimensionPixelSize(R.dimen.overview_minimum_next_prev_size) + taskMargin,
|
||||
maxScale,
|
||||
Gravity.CENTER,
|
||||
outRect);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the taskView size for carousel during app to overview animation on tablets.
|
||||
*/
|
||||
public final void calculateCarouselTaskSize(Context context, DeviceProfile dp, Rect outRect,
|
||||
PagedOrientationHandler orientedState) {
|
||||
if (dp.isTablet && dp.isGestureMode) {
|
||||
Resources res = context.getResources();
|
||||
float minScale = res.getFloat(R.dimen.overview_carousel_min_scale);
|
||||
Rect gridRect = new Rect();
|
||||
calculateGridSize(dp, context, gridRect);
|
||||
calculateTaskSizeInternal(context, dp, gridRect, minScale, Gravity.CENTER | Gravity.TOP,
|
||||
outRect);
|
||||
} else {
|
||||
calculateTaskSize(context, dp, outRect, orientedState);
|
||||
}
|
||||
}
|
||||
|
||||
private void calculateFocusTaskSize(Context context, DeviceProfile dp, Rect outRect) {
|
||||
Resources res = context.getResources();
|
||||
float maxScale = res.getFloat(R.dimen.overview_max_scale);
|
||||
Rect gridRect = new Rect();
|
||||
calculateGridSize(dp, context, gridRect);
|
||||
calculateTaskSizeInternal(context, dp, gridRect, maxScale, Gravity.CENTER, outRect);
|
||||
}
|
||||
|
||||
private void calculateTaskSizeInternal(Context context, DeviceProfile dp, int claimedSpaceAbove,
|
||||
int claimedSpaceBelow, int minimumHorizontalPadding, float maxScale, int gravity,
|
||||
Rect outRect) {
|
||||
Rect insets = dp.getInsets();
|
||||
|
||||
Rect potentialTaskRect = new Rect(0, 0, dp.widthPx, dp.heightPx);
|
||||
potentialTaskRect.inset(insets.left, insets.top, insets.right, insets.bottom);
|
||||
potentialTaskRect.inset(
|
||||
minimumHorizontalPadding,
|
||||
claimedSpaceAbove,
|
||||
minimumHorizontalPadding,
|
||||
claimedSpaceBelow);
|
||||
|
||||
calculateTaskSizeInternal(context, dp, potentialTaskRect, maxScale, gravity, outRect);
|
||||
}
|
||||
|
||||
private void calculateTaskSizeInternal(Context context, DeviceProfile dp,
|
||||
Rect potentialTaskRect, float targetScale, int gravity, Rect outRect) {
|
||||
PointF taskDimension = getTaskDimension(context, dp);
|
||||
|
||||
float scale = Math.min(
|
||||
potentialTaskRect.width() / taskDimension.x,
|
||||
potentialTaskRect.height() / taskDimension.y);
|
||||
scale = Math.min(scale, targetScale);
|
||||
int outWidth = Math.round(scale * taskDimension.x);
|
||||
int outHeight = Math.round(scale * taskDimension.y);
|
||||
|
||||
Gravity.apply(gravity, outWidth, outHeight, potentialTaskRect, outRect);
|
||||
}
|
||||
|
||||
private static PointF getTaskDimension(Context context, DeviceProfile dp) {
|
||||
PointF dimension = new PointF();
|
||||
getTaskDimension(context, dp, dimension);
|
||||
return dimension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the dimension of the task in the current system state.
|
||||
*/
|
||||
public static void getTaskDimension(Context context, DeviceProfile dp, PointF out) {
|
||||
out.x = dp.widthPx;
|
||||
out.y = dp.heightPx;
|
||||
if (dp.isTablet && !DisplayController.isTransientTaskbar(context)) {
|
||||
out.y -= dp.taskbarHeight;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the overview grid size for the provided device configuration.
|
||||
*/
|
||||
public final void calculateGridSize(DeviceProfile dp, Context context, Rect outRect) {
|
||||
Rect insets = dp.getInsets();
|
||||
int topMargin = dp.overviewTaskThumbnailTopMarginPx;
|
||||
int bottomMargin = dp.getOverviewActionsClaimedSpace();
|
||||
if (dp.isTaskbarPresent && Flags.enableGridOnlyOverview()) {
|
||||
topMargin += context.getResources().getDimensionPixelSize(
|
||||
R.dimen.overview_top_margin_grid_only);
|
||||
bottomMargin += context.getResources().getDimensionPixelSize(
|
||||
R.dimen.overview_bottom_margin_grid_only);
|
||||
}
|
||||
int sideMargin = dp.overviewGridSideMargin;
|
||||
|
||||
outRect.set(0, 0, dp.widthPx, dp.heightPx);
|
||||
outRect.inset(Math.max(insets.left, sideMargin), insets.top + topMargin,
|
||||
Math.max(insets.right, sideMargin), Math.max(insets.bottom, bottomMargin));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the overview grid non-focused task size for the provided device configuration.
|
||||
*/
|
||||
public final void calculateGridTaskSize(Context context, DeviceProfile dp, Rect outRect,
|
||||
PagedOrientationHandler orientedState) {
|
||||
Resources res = context.getResources();
|
||||
Rect potentialTaskRect = new Rect();
|
||||
if (Flags.enableGridOnlyOverview()) {
|
||||
calculateGridSize(dp, context, potentialTaskRect);
|
||||
} else {
|
||||
calculateFocusTaskSize(context, dp, potentialTaskRect);
|
||||
}
|
||||
|
||||
float rowHeight = (potentialTaskRect.height() + dp.overviewTaskThumbnailTopMarginPx
|
||||
- dp.overviewRowSpacing) / 2f;
|
||||
|
||||
PointF taskDimension = getTaskDimension(context, dp);
|
||||
float scale = (rowHeight - dp.overviewTaskThumbnailTopMarginPx) / taskDimension.y;
|
||||
int outWidth = Math.round(scale * taskDimension.x);
|
||||
int outHeight = Math.round(scale * taskDimension.y);
|
||||
|
||||
int gravity = Gravity.TOP;
|
||||
gravity |= orientedState.getRecentsRtlSetting(res) ? Gravity.RIGHT : Gravity.LEFT;
|
||||
Gravity.apply(gravity, outWidth, outHeight, potentialTaskRect, outRect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the modal taskView size for the provided device configuration
|
||||
*/
|
||||
public final void calculateModalTaskSize(Context context, DeviceProfile dp, Rect outRect,
|
||||
PagedOrientationHandler orientedState) {
|
||||
calculateTaskSize(context, dp, outRect, orientedState);
|
||||
boolean isGridOnlyOverview = dp.isTablet && Flags.enableGridOnlyOverview();
|
||||
int claimedSpaceBelow = isGridOnlyOverview
|
||||
? dp.overviewActionsTopMarginPx + dp.overviewActionsHeight + dp.stashedTaskbarHeight
|
||||
: (dp.heightPx - outRect.bottom - dp.getInsets().bottom);
|
||||
int minimumHorizontalPadding = 0;
|
||||
if (!isGridOnlyOverview) {
|
||||
float maxScale = context.getResources().getFloat(R.dimen.overview_modal_max_scale);
|
||||
minimumHorizontalPadding =
|
||||
Math.round((dp.availableWidthPx - outRect.width() * maxScale) / 2);
|
||||
}
|
||||
calculateTaskSizeInternal(
|
||||
context,
|
||||
dp,
|
||||
dp.overviewTaskMarginPx,
|
||||
claimedSpaceBelow,
|
||||
minimumHorizontalPadding,
|
||||
1f /*maxScale*/,
|
||||
Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM,
|
||||
outRect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the gesture ends and the animation starts towards the given target. Used to add
|
||||
* an optional additional animation with the same duration.
|
||||
*/
|
||||
public @Nullable Animator getParallelAnimationToLauncher(
|
||||
GestureState.GestureEndTarget endTarget, long duration,
|
||||
RecentsAnimationCallbacks callbacks) {
|
||||
if (endTarget == RECENTS) {
|
||||
ACTIVITY_TYPE activity = getCreatedActivity();
|
||||
if (activity == null) {
|
||||
return null;
|
||||
}
|
||||
RecentsView recentsView = activity.getOverviewPanel();
|
||||
STATE_TYPE state = stateFromGestureEndTarget(endTarget);
|
||||
ScrimView scrimView = activity.getScrimView();
|
||||
ObjectAnimator anim = ObjectAnimator.ofArgb(scrimView, VIEW_BACKGROUND_COLOR,
|
||||
getOverviewScrimColorForState(activity, state));
|
||||
anim.setDuration(duration);
|
||||
anim.setInterpolator(recentsView == null || !recentsView.isKeyboardTaskFocusPending()
|
||||
? LINEAR : INSTANT);
|
||||
return anim;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color of the scrim behind overview when at rest in this state.
|
||||
* Return {@link Color#TRANSPARENT} for no scrim.
|
||||
*/
|
||||
protected abstract int getOverviewScrimColorForState(ACTIVITY_TYPE activity, STATE_TYPE state);
|
||||
|
||||
/**
|
||||
* Returns the expected STATE_TYPE from the provided GestureEndTarget.
|
||||
*/
|
||||
public abstract STATE_TYPE stateFromGestureEndTarget(GestureState.GestureEndTarget endTarget);
|
||||
|
||||
/**
|
||||
* Called when the animation to the target has finished, but right before updating the state.
|
||||
* @return A View that needs to draw before ending the recents animation to LAST_TASK.
|
||||
* (This is a hack to ensure Taskbar draws its background first to avoid flickering.)
|
||||
*/
|
||||
public @Nullable View onSettledOnEndTarget(GestureState.GestureEndTarget endTarget) {
|
||||
TaskbarUIController taskbarUIController = getTaskbarController();
|
||||
if (taskbarUIController != null) {
|
||||
taskbarUIController.setSystemGestureInProgress(false);
|
||||
return taskbarUIController.getRootView();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void runOnInitBackgroundStateUI(Runnable callback) {
|
||||
ACTIVITY_TYPE activity = getCreatedActivity();
|
||||
ACTIVITY_TYPE activity = getCreatedContainer();
|
||||
if (activity != null && activity.getStateManager().getState() == mBackgroundState) {
|
||||
callback.run();
|
||||
onInitBackgroundStateUI();
|
||||
@@ -505,7 +215,7 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
DefaultAnimationFactory(Consumer<AnimatorControllerWithResistance> callback) {
|
||||
mCallback = callback;
|
||||
|
||||
mActivity = getCreatedActivity();
|
||||
mActivity = getCreatedContainer();
|
||||
mStartState = mActivity.getStateManager().getState();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,377 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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 com.android.app.animation.Interpolators.INSTANT;
|
||||
import static com.android.app.animation.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
|
||||
import static com.android.quickstep.GestureState.GestureEndTarget.LAST_TASK;
|
||||
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.RemoteAnimationTarget;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Flags;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.statehandlers.DesktopVisibilityController;
|
||||
import com.android.launcher3.statemanager.BaseState;
|
||||
import com.android.launcher3.taskbar.TaskbarUIController;
|
||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
import com.android.launcher3.views.ScrimView;
|
||||
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
|
||||
import com.android.quickstep.util.ActivityInitListener;
|
||||
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public abstract class BaseContainerInterface<STATE_TYPE extends BaseState<STATE_TYPE>,
|
||||
CONTAINER_TYPE extends RecentsViewContainer> {
|
||||
|
||||
public boolean rotationSupportedByActivity = false;
|
||||
|
||||
@Nullable
|
||||
public abstract CONTAINER_TYPE getCreatedContainer();
|
||||
|
||||
public abstract boolean isInLiveTileMode();
|
||||
|
||||
public abstract void onAssistantVisibilityChanged(float assistantVisibility);
|
||||
|
||||
public abstract boolean allowMinimizeSplitScreen();
|
||||
|
||||
public abstract boolean isResumed();
|
||||
|
||||
public abstract boolean isStarted();
|
||||
public abstract boolean deferStartingActivity(RecentsAnimationDeviceState deviceState,
|
||||
MotionEvent ev);
|
||||
|
||||
/** @return whether to allow going to All Apps from Overview. */
|
||||
public abstract boolean allowAllAppsFromOverview();
|
||||
|
||||
/**
|
||||
* Returns the color of the scrim behind overview when at rest in this state.
|
||||
* Return {@link Color#TRANSPARENT} for no scrim.
|
||||
*/
|
||||
protected abstract int getOverviewScrimColorForState(CONTAINER_TYPE container,
|
||||
STATE_TYPE state);
|
||||
|
||||
public abstract int getSwipeUpDestinationAndLength(
|
||||
DeviceProfile dp, Context context, Rect outRect,
|
||||
RecentsPagedOrientationHandler orientationHandler);
|
||||
|
||||
@Nullable
|
||||
public abstract TaskbarUIController getTaskbarController();
|
||||
|
||||
public abstract BaseActivityInterface.AnimationFactory prepareRecentsUI(
|
||||
RecentsAnimationDeviceState deviceState, boolean activityVisible,
|
||||
Consumer<AnimatorControllerWithResistance> callback);
|
||||
|
||||
public abstract ActivityInitListener createActivityInitListener(
|
||||
Predicate<Boolean> onInitListener);
|
||||
/**
|
||||
* Returns the expected STATE_TYPE from the provided GestureEndTarget.
|
||||
*/
|
||||
public abstract STATE_TYPE stateFromGestureEndTarget(GestureState.GestureEndTarget endTarget);
|
||||
|
||||
public abstract void switchRunningTaskViewToScreenshot(HashMap<Integer,
|
||||
ThumbnailData> thumbnailDatas, Runnable runnable);
|
||||
|
||||
public abstract void closeOverlay();
|
||||
|
||||
public abstract Rect getOverviewWindowBounds(
|
||||
Rect homeBounds, RemoteAnimationTarget target);
|
||||
|
||||
public abstract void onLaunchTaskFailed();
|
||||
|
||||
public abstract void onExitOverview(RotationTouchHelper deviceState,
|
||||
Runnable exitRunnable);
|
||||
|
||||
/** Called when the animation to home has fully settled. */
|
||||
public void onSwipeUpToHomeComplete(RecentsAnimationDeviceState deviceState) {}
|
||||
|
||||
/**
|
||||
* Sets a callback to be run when an activity launch happens while launcher is not yet resumed.
|
||||
*/
|
||||
public void setOnDeferredActivityLaunchCallback(Runnable r) {}
|
||||
/**
|
||||
* @return Whether the gesture in progress should be cancelled.
|
||||
*/
|
||||
public boolean shouldCancelCurrentGesture() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public DesktopVisibilityController getDesktopVisibilityController() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the gesture ends and the animation starts towards the given target. Used to add
|
||||
* an optional additional animation with the same duration.
|
||||
*/
|
||||
public @Nullable Animator getParallelAnimationToLauncher(
|
||||
GestureState.GestureEndTarget endTarget, long duration,
|
||||
RecentsAnimationCallbacks callbacks) {
|
||||
if (endTarget == RECENTS) {
|
||||
CONTAINER_TYPE container = getCreatedContainer();
|
||||
if (container == null) {
|
||||
return null;
|
||||
}
|
||||
RecentsView recentsView = container.getOverviewPanel();
|
||||
STATE_TYPE state = stateFromGestureEndTarget(endTarget);
|
||||
ScrimView scrimView = container.getScrimView();
|
||||
ObjectAnimator anim = ObjectAnimator.ofArgb(scrimView, VIEW_BACKGROUND_COLOR,
|
||||
getOverviewScrimColorForState(container, state));
|
||||
anim.setDuration(duration);
|
||||
anim.setInterpolator(recentsView == null || !recentsView.isKeyboardTaskFocusPending()
|
||||
? LINEAR : INSTANT);
|
||||
return anim;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the animation to the target has finished, but right before updating the state.
|
||||
* @return A View that needs to draw before ending the recents animation to LAST_TASK.
|
||||
* (This is a hack to ensure Taskbar draws its background first to avoid flickering.)
|
||||
*/
|
||||
public @Nullable View onSettledOnEndTarget(GestureState.GestureEndTarget endTarget) {
|
||||
TaskbarUIController taskbarUIController = getTaskbarController();
|
||||
if (taskbarUIController != null) {
|
||||
taskbarUIController.setSystemGestureInProgress(false);
|
||||
return taskbarUIController.getRootView();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the current gesture transition is cancelled.
|
||||
* @param activityVisible Whether the user can see the changes we make here, so try to animate.
|
||||
* @param endTarget If the gesture ended before we got cancelled, where we were headed.
|
||||
*/
|
||||
public void onTransitionCancelled(boolean activityVisible,
|
||||
@Nullable GestureState.GestureEndTarget endTarget) {
|
||||
RecentsViewContainer container = getCreatedContainer();
|
||||
if (container == null) {
|
||||
return;
|
||||
}
|
||||
RecentsView recentsView = container.getOverviewPanel();
|
||||
BaseState startState = recentsView.getStateManager().getRestState();
|
||||
if (endTarget != null) {
|
||||
// We were on our way to this state when we got canceled, end there instead.
|
||||
startState = stateFromGestureEndTarget(endTarget);
|
||||
DesktopVisibilityController controller = getDesktopVisibilityController();
|
||||
if (controller != null && controller.areDesktopTasksVisible()
|
||||
&& endTarget == LAST_TASK) {
|
||||
// When we are cancelling the transition and going back to last task, move to
|
||||
// rest state instead when desktop tasks are visible.
|
||||
// If a fullscreen task is visible, launcher goes to normal state when the
|
||||
// activity is stopped. This does not happen when desktop tasks are visible
|
||||
// on top of launcher. Force the launcher state to rest state here.
|
||||
startState = recentsView.getStateManager().getRestState();
|
||||
// Do not animate the transition
|
||||
activityVisible = false;
|
||||
}
|
||||
}
|
||||
recentsView.getStateManager().goToState(startState, activityVisible);
|
||||
}
|
||||
|
||||
public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect,
|
||||
PagedOrientationHandler orientedState) {
|
||||
if (dp.isTablet) {
|
||||
if (Flags.enableGridOnlyOverview()) {
|
||||
calculateGridTaskSize(context, dp, outRect, orientedState);
|
||||
} else {
|
||||
calculateFocusTaskSize(context, dp, outRect);
|
||||
}
|
||||
} else {
|
||||
Resources res = context.getResources();
|
||||
float maxScale = res.getFloat(R.dimen.overview_max_scale);
|
||||
int taskMargin = dp.overviewTaskMarginPx;
|
||||
calculateTaskSizeInternal(
|
||||
context,
|
||||
dp,
|
||||
dp.overviewTaskThumbnailTopMarginPx,
|
||||
dp.getOverviewActionsClaimedSpace(),
|
||||
res.getDimensionPixelSize(R.dimen.overview_minimum_next_prev_size) + taskMargin,
|
||||
maxScale,
|
||||
Gravity.CENTER,
|
||||
outRect);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the taskView size for carousel during app to overview animation on tablets.
|
||||
*/
|
||||
public final void calculateCarouselTaskSize(Context context, DeviceProfile dp, Rect outRect,
|
||||
PagedOrientationHandler orientedState) {
|
||||
if (dp.isTablet && dp.isGestureMode) {
|
||||
Resources res = context.getResources();
|
||||
float minScale = res.getFloat(R.dimen.overview_carousel_min_scale);
|
||||
Rect gridRect = new Rect();
|
||||
calculateGridSize(dp, context, gridRect);
|
||||
calculateTaskSizeInternal(context, dp, gridRect, minScale, Gravity.CENTER | Gravity.TOP,
|
||||
outRect);
|
||||
} else {
|
||||
calculateTaskSize(context, dp, outRect, orientedState);
|
||||
}
|
||||
}
|
||||
|
||||
private void calculateFocusTaskSize(Context context, DeviceProfile dp, Rect outRect) {
|
||||
Resources res = context.getResources();
|
||||
float maxScale = res.getFloat(R.dimen.overview_max_scale);
|
||||
Rect gridRect = new Rect();
|
||||
calculateGridSize(dp, context, gridRect);
|
||||
calculateTaskSizeInternal(context, dp, gridRect, maxScale, Gravity.CENTER, outRect);
|
||||
}
|
||||
|
||||
private void calculateTaskSizeInternal(Context context, DeviceProfile dp, int claimedSpaceAbove,
|
||||
int claimedSpaceBelow, int minimumHorizontalPadding, float maxScale, int gravity,
|
||||
Rect outRect) {
|
||||
Rect insets = dp.getInsets();
|
||||
|
||||
Rect potentialTaskRect = new Rect(0, 0, dp.widthPx, dp.heightPx);
|
||||
potentialTaskRect.inset(insets.left, insets.top, insets.right, insets.bottom);
|
||||
potentialTaskRect.inset(
|
||||
minimumHorizontalPadding,
|
||||
claimedSpaceAbove,
|
||||
minimumHorizontalPadding,
|
||||
claimedSpaceBelow);
|
||||
|
||||
calculateTaskSizeInternal(context, dp, potentialTaskRect, maxScale, gravity, outRect);
|
||||
}
|
||||
|
||||
private void calculateTaskSizeInternal(Context context, DeviceProfile dp,
|
||||
Rect potentialTaskRect, float targetScale, int gravity, Rect outRect) {
|
||||
PointF taskDimension = getTaskDimension(context, dp);
|
||||
|
||||
float scale = Math.min(
|
||||
potentialTaskRect.width() / taskDimension.x,
|
||||
potentialTaskRect.height() / taskDimension.y);
|
||||
scale = Math.min(scale, targetScale);
|
||||
int outWidth = Math.round(scale * taskDimension.x);
|
||||
int outHeight = Math.round(scale * taskDimension.y);
|
||||
|
||||
Gravity.apply(gravity, outWidth, outHeight, potentialTaskRect, outRect);
|
||||
}
|
||||
|
||||
private static PointF getTaskDimension(Context context, DeviceProfile dp) {
|
||||
PointF dimension = new PointF();
|
||||
getTaskDimension(context, dp, dimension);
|
||||
return dimension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the dimension of the task in the current system state.
|
||||
*/
|
||||
public static void getTaskDimension(Context context, DeviceProfile dp, PointF out) {
|
||||
out.x = dp.widthPx;
|
||||
out.y = dp.heightPx;
|
||||
if (dp.isTablet && !DisplayController.isTransientTaskbar(context)) {
|
||||
out.y -= dp.taskbarHeight;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the overview grid size for the provided device configuration.
|
||||
*/
|
||||
public final void calculateGridSize(DeviceProfile dp, Context context, Rect outRect) {
|
||||
Rect insets = dp.getInsets();
|
||||
int topMargin = dp.overviewTaskThumbnailTopMarginPx;
|
||||
int bottomMargin = dp.getOverviewActionsClaimedSpace();
|
||||
if (dp.isTaskbarPresent && Flags.enableGridOnlyOverview()) {
|
||||
topMargin += context.getResources().getDimensionPixelSize(
|
||||
R.dimen.overview_top_margin_grid_only);
|
||||
bottomMargin += context.getResources().getDimensionPixelSize(
|
||||
R.dimen.overview_bottom_margin_grid_only);
|
||||
}
|
||||
int sideMargin = dp.overviewGridSideMargin;
|
||||
|
||||
outRect.set(0, 0, dp.widthPx, dp.heightPx);
|
||||
outRect.inset(Math.max(insets.left, sideMargin), insets.top + topMargin,
|
||||
Math.max(insets.right, sideMargin), Math.max(insets.bottom, bottomMargin));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the overview grid non-focused task size for the provided device configuration.
|
||||
*/
|
||||
public final void calculateGridTaskSize(Context context, DeviceProfile dp, Rect outRect,
|
||||
PagedOrientationHandler orientedState) {
|
||||
Resources res = context.getResources();
|
||||
Rect potentialTaskRect = new Rect();
|
||||
if (Flags.enableGridOnlyOverview()) {
|
||||
calculateGridSize(dp, context, potentialTaskRect);
|
||||
} else {
|
||||
calculateFocusTaskSize(context, dp, potentialTaskRect);
|
||||
}
|
||||
|
||||
float rowHeight = (potentialTaskRect.height() + dp.overviewTaskThumbnailTopMarginPx
|
||||
- dp.overviewRowSpacing) / 2f;
|
||||
|
||||
PointF taskDimension = getTaskDimension(context, dp);
|
||||
float scale = (rowHeight - dp.overviewTaskThumbnailTopMarginPx) / taskDimension.y;
|
||||
int outWidth = Math.round(scale * taskDimension.x);
|
||||
int outHeight = Math.round(scale * taskDimension.y);
|
||||
|
||||
int gravity = Gravity.TOP;
|
||||
gravity |= orientedState.getRecentsRtlSetting(res) ? Gravity.RIGHT : Gravity.LEFT;
|
||||
Gravity.apply(gravity, outWidth, outHeight, potentialTaskRect, outRect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the modal taskView size for the provided device configuration
|
||||
*/
|
||||
public final void calculateModalTaskSize(Context context, DeviceProfile dp, Rect outRect,
|
||||
PagedOrientationHandler orientedState) {
|
||||
calculateTaskSize(context, dp, outRect, orientedState);
|
||||
boolean isGridOnlyOverview = dp.isTablet && Flags.enableGridOnlyOverview();
|
||||
int claimedSpaceBelow = isGridOnlyOverview
|
||||
? dp.overviewActionsTopMarginPx + dp.overviewActionsHeight + dp.stashedTaskbarHeight
|
||||
: (dp.heightPx - outRect.bottom - dp.getInsets().bottom);
|
||||
int minimumHorizontalPadding = 0;
|
||||
if (!isGridOnlyOverview) {
|
||||
float maxScale = context.getResources().getFloat(R.dimen.overview_modal_max_scale);
|
||||
minimumHorizontalPadding =
|
||||
Math.round((dp.availableWidthPx - outRect.width() * maxScale) / 2);
|
||||
}
|
||||
calculateTaskSizeInternal(
|
||||
context,
|
||||
dp,
|
||||
dp.overviewTaskMarginPx,
|
||||
claimedSpaceBelow,
|
||||
minimumHorizontalPadding,
|
||||
1f /*maxScale*/,
|
||||
Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM,
|
||||
outRect);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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 android.view.View
|
||||
import com.android.launcher3.AbstractFloatingViewHelper
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.logging.StatsLogManager.LauncherEvent
|
||||
import com.android.launcher3.popup.SystemShortcut
|
||||
import com.android.quickstep.views.RecentsView
|
||||
import com.android.quickstep.views.RecentsViewContainer
|
||||
import com.android.quickstep.views.TaskView.TaskIdAttributeContainer
|
||||
import com.android.window.flags.Flags
|
||||
|
||||
/** A menu item, "Desktop", that allows the user to bring the current app into Desktop Windowing. */
|
||||
class DesktopSystemShortcut(
|
||||
container: RecentsViewContainer,
|
||||
private val mTaskContainer: TaskIdAttributeContainer,
|
||||
abstractFloatingViewHelper: AbstractFloatingViewHelper
|
||||
) :
|
||||
SystemShortcut<RecentsViewContainer>(
|
||||
R.drawable.ic_caption_desktop_button_foreground,
|
||||
R.string.recent_task_option_desktop,
|
||||
container,
|
||||
mTaskContainer.itemInfo,
|
||||
mTaskContainer.taskView,
|
||||
abstractFloatingViewHelper
|
||||
) {
|
||||
override fun onClick(view: View) {
|
||||
dismissTaskMenuView()
|
||||
val recentsView = mTarget!!.getOverviewPanel<RecentsView<*, *>>()
|
||||
recentsView.moveTaskToDesktop(mTaskContainer) {
|
||||
mTarget.statsLogManager
|
||||
.logger()
|
||||
.withItemInfo(mTaskContainer.itemInfo)
|
||||
.log(LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_DESKTOP_TAP)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
/** Creates a factory for creating Desktop system shorcuts. */
|
||||
@JvmOverloads
|
||||
fun createFactory(
|
||||
abstractFloatingViewHelper: AbstractFloatingViewHelper = AbstractFloatingViewHelper()
|
||||
): TaskShortcutFactory {
|
||||
return object : TaskShortcutFactory {
|
||||
override fun getShortcuts(
|
||||
container: RecentsViewContainer,
|
||||
taskContainer: TaskIdAttributeContainer
|
||||
): List<DesktopSystemShortcut>? {
|
||||
return if (!Flags.enableDesktopWindowingMode()) null
|
||||
else if (!taskContainer.task.isDockable) null
|
||||
else
|
||||
listOf(
|
||||
DesktopSystemShortcut(
|
||||
container,
|
||||
taskContainer,
|
||||
abstractFloatingViewHelper
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun showForSplitscreen() = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,9 +44,26 @@ class DeviceConfigWrapper private constructor(propReader: PropReader) {
|
||||
"Enable AGSA override for LPNH and LPH timeout and touch slop"
|
||||
)
|
||||
|
||||
val lpnhTimeoutMs =
|
||||
propReader.get("LPNH_TIMEOUT_MS", 450, "Controls lpnh timeout in milliseconds")
|
||||
|
||||
val lpnhSlopPercentage =
|
||||
propReader.get("LPNH_SLOP_PERCENTAGE", 100, "Controls touch slop percentage for lpnh")
|
||||
|
||||
val enableLpnhTwoStages =
|
||||
propReader.get(
|
||||
"ENABLE_LPNH_TWO_STAGES",
|
||||
false,
|
||||
"Enable two stage for LPNH duration and touch slop"
|
||||
)
|
||||
|
||||
val twoStageMultiplier =
|
||||
propReader.get(
|
||||
"TWO_STAGE_MULTIPLIER",
|
||||
2,
|
||||
"Extends the duration and touch slop if the initial slop is passed"
|
||||
)
|
||||
|
||||
val animateLpnh = propReader.get("ANIMATE_LPNH", false, "Animates navbar when long pressing")
|
||||
|
||||
val shrinkNavHandleOnPress =
|
||||
@@ -56,9 +73,6 @@ class DeviceConfigWrapper private constructor(propReader: PropReader) {
|
||||
"Shrinks navbar when long pressing if ANIMATE_LPNH is enabled"
|
||||
)
|
||||
|
||||
val lpnhTimeoutMs =
|
||||
propReader.get("LPNH_TIMEOUT_MS", 450, "Controls lpnh timeout in milliseconds")
|
||||
|
||||
val enableLongPressNavHandle =
|
||||
propReader.get(
|
||||
"ENABLE_LONG_PRESS_NAV_HANDLE",
|
||||
|
||||
@@ -96,13 +96,13 @@ public final class FallbackActivityInterface extends
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public RecentsActivity getCreatedActivity() {
|
||||
public RecentsActivity getCreatedContainer() {
|
||||
return RecentsActivity.ACTIVITY_TRACKER.getCreatedActivity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FallbackTaskbarUIController getTaskbarController() {
|
||||
RecentsActivity activity = getCreatedActivity();
|
||||
RecentsActivity activity = getCreatedContainer();
|
||||
if (activity == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -112,7 +112,7 @@ public final class FallbackActivityInterface extends
|
||||
@Nullable
|
||||
@Override
|
||||
public RecentsView getVisibleRecentsView() {
|
||||
RecentsActivity activity = getCreatedActivity();
|
||||
RecentsActivity activity = getCreatedContainer();
|
||||
if (activity != null) {
|
||||
if (activity.hasBeenResumed() || isInLiveTileMode()) {
|
||||
return activity.getOverviewPanel();
|
||||
@@ -154,7 +154,7 @@ public final class FallbackActivityInterface extends
|
||||
|
||||
@Override
|
||||
public void onExitOverview(RotationTouchHelper deviceState, Runnable exitRunnable) {
|
||||
final StateManager<RecentsState> stateManager = getCreatedActivity().getStateManager();
|
||||
final StateManager<RecentsState> stateManager = getCreatedContainer().getStateManager();
|
||||
if (stateManager.getState() == HOME) {
|
||||
exitRunnable.run();
|
||||
notifyRecentsOfOrientation(deviceState);
|
||||
@@ -177,7 +177,7 @@ public final class FallbackActivityInterface extends
|
||||
|
||||
@Override
|
||||
public boolean isInLiveTileMode() {
|
||||
RecentsActivity activity = getCreatedActivity();
|
||||
RecentsActivity activity = getCreatedContainer();
|
||||
return activity != null && activity.getStateManager().getState() == DEFAULT &&
|
||||
activity.isStarted();
|
||||
}
|
||||
@@ -185,7 +185,7 @@ public final class FallbackActivityInterface extends
|
||||
@Override
|
||||
public void onLaunchTaskFailed() {
|
||||
// TODO: probably go back to overview instead.
|
||||
RecentsActivity activity = getCreatedActivity();
|
||||
RecentsActivity activity = getCreatedContainer();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
@@ -209,7 +209,7 @@ public final class FallbackActivityInterface extends
|
||||
|
||||
private void notifyRecentsOfOrientation(RotationTouchHelper rotationTouchHelper) {
|
||||
// reset layout on swipe to home
|
||||
RecentsView recentsView = getCreatedActivity().getOverviewPanel();
|
||||
RecentsView recentsView = getCreatedContainer().getOverviewPanel();
|
||||
recentsView.setLayoutRotation(rotationTouchHelper.getCurrentActiveRotation(),
|
||||
rotationTouchHelper.getDisplayRotation());
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ public class FallbackSwipeHandler extends
|
||||
public AnimatorPlaybackController createActivityAnimationToHome() {
|
||||
// copied from {@link LauncherSwipeHandlerV2.LauncherHomeAnimationFactory}
|
||||
long accuracy = 2 * Math.max(mDp.widthPx, mDp.heightPx);
|
||||
return mActivity.getStateManager().createAnimationToNewWorkspace(
|
||||
return mContainer.getStateManager().createAnimationToNewWorkspace(
|
||||
RecentsState.HOME, accuracy, StateAnimationConfig.SKIP_ALL_ANIMATIONS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,10 +37,10 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.statemanager.BaseState;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
|
||||
import com.android.quickstep.util.ActiveGestureErrorDetector;
|
||||
import com.android.quickstep.util.ActiveGestureLog;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -151,7 +151,7 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
||||
// Needed to interact with the current activity
|
||||
private final Intent mHomeIntent;
|
||||
private final Intent mOverviewIntent;
|
||||
private final BaseActivityInterface mActivityInterface;
|
||||
private final BaseContainerInterface mContainerInterface;
|
||||
private final MultiStateCallback mStateCallback;
|
||||
private final int mGestureId;
|
||||
|
||||
@@ -189,7 +189,7 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
||||
public GestureState(OverviewComponentObserver componentObserver, int gestureId) {
|
||||
mHomeIntent = componentObserver.getHomeIntent();
|
||||
mOverviewIntent = componentObserver.getOverviewIntent();
|
||||
mActivityInterface = componentObserver.getActivityInterface();
|
||||
mContainerInterface = componentObserver.getActivityInterface();
|
||||
mStateCallback = new MultiStateCallback(
|
||||
STATE_NAMES.toArray(new String[0]), GestureState::getTrackedEventForState);
|
||||
mGestureId = gestureId;
|
||||
@@ -198,7 +198,7 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
||||
public GestureState(GestureState other) {
|
||||
mHomeIntent = other.mHomeIntent;
|
||||
mOverviewIntent = other.mOverviewIntent;
|
||||
mActivityInterface = other.mActivityInterface;
|
||||
mContainerInterface = other.mContainerInterface;
|
||||
mStateCallback = other.mStateCallback;
|
||||
mGestureId = other.mGestureId;
|
||||
mRunningTask = other.mRunningTask;
|
||||
@@ -212,7 +212,7 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
||||
// Do nothing, only used for initializing the gesture state prior to user unlock
|
||||
mHomeIntent = new Intent();
|
||||
mOverviewIntent = new Intent();
|
||||
mActivityInterface = null;
|
||||
mContainerInterface = null;
|
||||
mStateCallback = new MultiStateCallback(
|
||||
STATE_NAMES.toArray(new String[0]), GestureState::getTrackedEventForState);
|
||||
mGestureId = -1;
|
||||
@@ -268,9 +268,9 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
||||
/**
|
||||
* @return the interface to the activity handing the UI updates for this gesture.
|
||||
*/
|
||||
public <S extends BaseState<S>,
|
||||
T extends StatefulActivity<S>> BaseActivityInterface<S, T> getActivityInterface() {
|
||||
return mActivityInterface;
|
||||
public <S extends BaseState<S>, T extends RecentsViewContainer>
|
||||
BaseContainerInterface<S, T> getContainerInterface() {
|
||||
return mContainerInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,7 +36,6 @@ import androidx.annotation.UiThread;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Flags;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAnimUtils;
|
||||
import com.android.launcher3.LauncherInitListener;
|
||||
import com.android.launcher3.LauncherState;
|
||||
@@ -86,7 +85,7 @@ public final class LauncherActivityInterface extends
|
||||
|
||||
@Override
|
||||
public void onSwipeUpToHomeComplete(RecentsAnimationDeviceState deviceState) {
|
||||
Launcher launcher = getCreatedActivity();
|
||||
QuickstepLauncher launcher = getCreatedContainer();
|
||||
if (launcher == null) {
|
||||
return;
|
||||
}
|
||||
@@ -103,7 +102,7 @@ public final class LauncherActivityInterface extends
|
||||
|
||||
@Override
|
||||
public void onAssistantVisibilityChanged(float visibility) {
|
||||
Launcher launcher = getCreatedActivity();
|
||||
QuickstepLauncher launcher = getCreatedContainer();
|
||||
if (launcher == null) {
|
||||
return;
|
||||
}
|
||||
@@ -145,7 +144,7 @@ public final class LauncherActivityInterface extends
|
||||
|
||||
@Override
|
||||
public void setOnDeferredActivityLaunchCallback(Runnable r) {
|
||||
Launcher launcher = getCreatedActivity();
|
||||
QuickstepLauncher launcher = getCreatedContainer();
|
||||
if (launcher == null) {
|
||||
return;
|
||||
}
|
||||
@@ -154,14 +153,14 @@ public final class LauncherActivityInterface extends
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public QuickstepLauncher getCreatedActivity() {
|
||||
public QuickstepLauncher getCreatedContainer() {
|
||||
return QuickstepLauncher.ACTIVITY_TRACKER.getCreatedActivity();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public DepthController getDepthController() {
|
||||
QuickstepLauncher launcher = getCreatedActivity();
|
||||
QuickstepLauncher launcher = getCreatedContainer();
|
||||
if (launcher == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -171,7 +170,7 @@ public final class LauncherActivityInterface extends
|
||||
@Nullable
|
||||
@Override
|
||||
public DesktopVisibilityController getDesktopVisibilityController() {
|
||||
QuickstepLauncher launcher = getCreatedActivity();
|
||||
QuickstepLauncher launcher = getCreatedContainer();
|
||||
if (launcher == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -181,7 +180,7 @@ public final class LauncherActivityInterface extends
|
||||
@Nullable
|
||||
@Override
|
||||
public LauncherTaskbarUIController getTaskbarController() {
|
||||
QuickstepLauncher launcher = getCreatedActivity();
|
||||
QuickstepLauncher launcher = getCreatedContainer();
|
||||
if (launcher == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -191,7 +190,7 @@ public final class LauncherActivityInterface extends
|
||||
@Nullable
|
||||
@Override
|
||||
public RecentsView getVisibleRecentsView() {
|
||||
Launcher launcher = getVisibleLauncher();
|
||||
QuickstepLauncher launcher = getVisibleLauncher();
|
||||
RecentsView recentsView =
|
||||
launcher != null && launcher.getStateManager().getState().overviewUi
|
||||
? launcher.getOverviewPanel() : null;
|
||||
@@ -205,8 +204,8 @@ public final class LauncherActivityInterface extends
|
||||
|
||||
@Nullable
|
||||
@UiThread
|
||||
private Launcher getVisibleLauncher() {
|
||||
Launcher launcher = getCreatedActivity();
|
||||
private QuickstepLauncher getVisibleLauncher() {
|
||||
QuickstepLauncher launcher = getCreatedContainer();
|
||||
if (launcher == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -222,7 +221,7 @@ public final class LauncherActivityInterface extends
|
||||
|
||||
@Override
|
||||
public boolean switchToRecentsIfVisible(Animator.AnimatorListener animatorListener) {
|
||||
Launcher launcher = getVisibleLauncher();
|
||||
QuickstepLauncher launcher = getVisibleLauncher();
|
||||
if (launcher == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -243,7 +242,7 @@ public final class LauncherActivityInterface extends
|
||||
|
||||
@Override
|
||||
public void onExitOverview(RotationTouchHelper deviceState, Runnable exitRunnable) {
|
||||
final StateManager<LauncherState> stateManager = getCreatedActivity().getStateManager();
|
||||
final StateManager<LauncherState> stateManager = getCreatedContainer().getStateManager();
|
||||
stateManager.addStateListener(
|
||||
new StateManager.StateListener<LauncherState>() {
|
||||
@Override
|
||||
@@ -260,7 +259,7 @@ public final class LauncherActivityInterface extends
|
||||
|
||||
private void notifyRecentsOfOrientation(RotationTouchHelper rotationTouchHelper) {
|
||||
// reset layout on swipe to home
|
||||
RecentsView recentsView = getCreatedActivity().getOverviewPanel();
|
||||
RecentsView recentsView = getCreatedContainer().getOverviewPanel();
|
||||
recentsView.setLayoutRotation(rotationTouchHelper.getCurrentActiveRotation(),
|
||||
rotationTouchHelper.getDisplayRotation());
|
||||
}
|
||||
@@ -279,12 +278,12 @@ public final class LauncherActivityInterface extends
|
||||
public boolean allowAllAppsFromOverview() {
|
||||
return FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get()
|
||||
// If floating search bar would not show in overview, don't allow all apps gesture.
|
||||
&& OVERVIEW.areElementsVisible(getCreatedActivity(), FLOATING_SEARCH_BAR);
|
||||
&& OVERVIEW.areElementsVisible(getCreatedContainer(), FLOATING_SEARCH_BAR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInLiveTileMode() {
|
||||
Launcher launcher = getCreatedActivity();
|
||||
QuickstepLauncher launcher = getCreatedContainer();
|
||||
|
||||
return launcher != null
|
||||
&& launcher.getStateManager().getState() == OVERVIEW
|
||||
@@ -294,7 +293,7 @@ public final class LauncherActivityInterface extends
|
||||
|
||||
@Override
|
||||
public void onLaunchTaskFailed() {
|
||||
Launcher launcher = getCreatedActivity();
|
||||
QuickstepLauncher launcher = getCreatedContainer();
|
||||
if (launcher == null) {
|
||||
return;
|
||||
}
|
||||
@@ -304,7 +303,7 @@ public final class LauncherActivityInterface extends
|
||||
@Override
|
||||
public void closeOverlay() {
|
||||
super.closeOverlay();
|
||||
Launcher launcher = getCreatedActivity();
|
||||
QuickstepLauncher launcher = getCreatedContainer();
|
||||
if (launcher == null) {
|
||||
return;
|
||||
}
|
||||
@@ -337,9 +336,8 @@ public final class LauncherActivityInterface extends
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getOverviewScrimColorForState(QuickstepLauncher launcher,
|
||||
LauncherState state) {
|
||||
return state.getWorkspaceScrimColor(launcher);
|
||||
protected int getOverviewScrimColorForState(QuickstepLauncher activity, LauncherState state) {
|
||||
return state.getWorkspaceScrimColor(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -75,7 +75,7 @@ public class LauncherSwipeHandlerV2 extends
|
||||
protected HomeAnimationFactory createHomeAnimationFactory(ArrayList<IBinder> launchCookies,
|
||||
long duration, boolean isTargetTranslucent, boolean appCanEnterPip,
|
||||
RemoteAnimationTarget runningTaskTarget) {
|
||||
if (mActivity == null) {
|
||||
if (mContainer == null) {
|
||||
mStateCallback.addChangeListener(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
|
||||
isPresent -> mRecentsView.startHome());
|
||||
return new HomeAnimationFactory() {
|
||||
@@ -91,9 +91,9 @@ public class LauncherSwipeHandlerV2 extends
|
||||
boolean canUseWorkspaceView = workspaceView != null && workspaceView.isAttachedToWindow()
|
||||
&& workspaceView.getHeight() > 0;
|
||||
|
||||
mActivity.getRootView().setForceHideBackArrow(true);
|
||||
mContainer.getRootView().setForceHideBackArrow(true);
|
||||
if (!TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
|
||||
mActivity.setHintUserWillBeActive();
|
||||
mContainer.setHintUserWillBeActive();
|
||||
}
|
||||
|
||||
if (!canUseWorkspaceView || appCanEnterPip || mIsSwipeForSplit) {
|
||||
@@ -108,10 +108,10 @@ public class LauncherSwipeHandlerV2 extends
|
||||
|
||||
private HomeAnimationFactory createIconHomeAnimationFactory(View workspaceView) {
|
||||
RectF iconLocation = new RectF();
|
||||
FloatingIconView floatingIconView = getFloatingIconView(mActivity, workspaceView, null,
|
||||
mActivity.getTaskbarUIController() == null
|
||||
FloatingIconView floatingIconView = getFloatingIconView(mContainer, workspaceView, null,
|
||||
mContainer.getTaskbarUIController() == null
|
||||
? null
|
||||
: mActivity.getTaskbarUIController().findMatchingView(workspaceView),
|
||||
: mContainer.getTaskbarUIController().findMatchingView(workspaceView),
|
||||
true /* hideOriginal */, iconLocation, false /* isOpening */);
|
||||
|
||||
// We want the window alpha to be 0 once this threshold is met, so that the
|
||||
@@ -171,7 +171,7 @@ public class LauncherSwipeHandlerV2 extends
|
||||
Size windowSize = new Size(crop.width(), crop.height());
|
||||
int fallbackBackgroundColor =
|
||||
FloatingWidgetView.getDefaultBackgroundColor(mContext, runningTaskTarget);
|
||||
FloatingWidgetView floatingWidgetView = FloatingWidgetView.getFloatingWidgetView(mActivity,
|
||||
FloatingWidgetView floatingWidgetView = FloatingWidgetView.getFloatingWidgetView(mContainer,
|
||||
hostView, backgroundLocation, windowSize, tvs.getCurrentCornerRadius(),
|
||||
isTargetTranslucent, fallbackBackgroundColor);
|
||||
|
||||
@@ -248,7 +248,7 @@ public class LauncherSwipeHandlerV2 extends
|
||||
}
|
||||
}
|
||||
|
||||
return mActivity.getFirstMatchForAppClose(launchCookieItemId,
|
||||
return mContainer.getFirstMatchForAppClose(launchCookieItemId,
|
||||
runningTaskView.getTask().key.getComponent().getPackageName(),
|
||||
UserHandle.of(runningTaskView.getTask().key.userId),
|
||||
false /* supportsAllAppsState */);
|
||||
@@ -292,18 +292,18 @@ public class LauncherSwipeHandlerV2 extends
|
||||
// Return an empty APC here since we have an non-user controlled animation
|
||||
// to home.
|
||||
long accuracy = 2 * Math.max(mDp.widthPx, mDp.heightPx);
|
||||
return mActivity.getStateManager().createAnimationToNewWorkspace(
|
||||
return mContainer.getStateManager().createAnimationToNewWorkspace(
|
||||
NORMAL, accuracy, StateAnimationConfig.SKIP_ALL_ANIMATIONS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playAtomicAnimation(float velocity) {
|
||||
if (enableScalingRevealHomeAnimation()) {
|
||||
if (mActivity != null) {
|
||||
new ScalingWorkspaceRevealAnim(mActivity).start();
|
||||
if (mContainer != null) {
|
||||
new ScalingWorkspaceRevealAnim(mContainer).start();
|
||||
}
|
||||
} else {
|
||||
new StaggeredWorkspaceAnim(mActivity, velocity, true /* animateOverviewScrim */,
|
||||
new StaggeredWorkspaceAnim(mContainer, velocity, true /* animateOverviewScrim */,
|
||||
getViewIgnoredInWorkspaceRevealAnimation())
|
||||
.start();
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ import com.android.launcher3.util.RunnableList;
|
||||
import com.android.quickstep.RecentsAnimationCallbacks.RecentsAnimationListener;
|
||||
import com.android.quickstep.util.ActiveGestureLog;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
|
||||
@@ -191,7 +192,8 @@ public class OverviewCommandHelper {
|
||||
* Executes the task and returns true if next task can be executed. If false, then the next
|
||||
* task is deferred until {@link #scheduleNextTask} is called
|
||||
*/
|
||||
private <T extends StatefulActivity<?>> boolean executeCommand(CommandInfo cmd) {
|
||||
private <T extends StatefulActivity<?> & RecentsViewContainer> boolean executeCommand(
|
||||
CommandInfo cmd) {
|
||||
if (mWaitForToggleCommandComplete && cmd.type == TYPE_TOGGLE) {
|
||||
return true;
|
||||
}
|
||||
@@ -200,7 +202,7 @@ public class OverviewCommandHelper {
|
||||
RecentsView visibleRecentsView = activityInterface.getVisibleRecentsView();
|
||||
RecentsView createdRecentsView;
|
||||
if (visibleRecentsView == null) {
|
||||
T activity = activityInterface.getCreatedActivity();
|
||||
T activity = activityInterface.getCreatedContainer();
|
||||
createdRecentsView = activity == null ? null : activity.getOverviewPanel();
|
||||
DeviceProfile dp = activity == null ? null : activity.getDeviceProfile();
|
||||
TaskbarUIController uiController = activityInterface.getTaskbarController();
|
||||
@@ -296,7 +298,7 @@ public class OverviewCommandHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
final T activity = activityInterface.getCreatedActivity();
|
||||
final T activity = activityInterface.getCreatedContainer();
|
||||
if (activity != null) {
|
||||
InteractionJankMonitorWrapper.begin(
|
||||
activity.getRootView(),
|
||||
@@ -327,7 +329,7 @@ public class OverviewCommandHelper {
|
||||
interactionHandler.onGestureCancelled();
|
||||
cmd.removeListener(this);
|
||||
|
||||
T createdActivity = activityInterface.getCreatedActivity();
|
||||
T createdActivity = activityInterface.getCreatedContainer();
|
||||
if (createdActivity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ public class QuickstepTestInformationHandler extends TestInformationHandler {
|
||||
RecentsAnimationDeviceState rads = new RecentsAnimationDeviceState(mContext);
|
||||
OverviewComponentObserver observer = new OverviewComponentObserver(mContext, rads);
|
||||
try {
|
||||
return observer.getActivityInterface().getCreatedActivity();
|
||||
return observer.getActivityInterface().getCreatedContainer();
|
||||
} finally {
|
||||
observer.onDestroy();
|
||||
rads.destroy();
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.app.ActivityOptions;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
@@ -85,6 +86,7 @@ import com.android.quickstep.util.SplitSelectStateController;
|
||||
import com.android.quickstep.util.TISBindHelper;
|
||||
import com.android.quickstep.views.OverviewActionsView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
@@ -95,7 +97,8 @@ import java.util.List;
|
||||
* A recents activity that shows the recently launched tasks as swipable task cards.
|
||||
* See {@link com.android.quickstep.views.RecentsView}.
|
||||
*/
|
||||
public final class RecentsActivity extends StatefulActivity<RecentsState> {
|
||||
public final class RecentsActivity extends StatefulActivity<RecentsState> implements
|
||||
RecentsViewContainer {
|
||||
private static final String TAG = "RecentsActivity";
|
||||
|
||||
public static final ActivityTracker<RecentsActivity> ACTIVITY_TRACKER =
|
||||
@@ -109,7 +112,7 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
|
||||
private RecentsDragLayer mDragLayer;
|
||||
private ScrimView mScrimView;
|
||||
private FallbackRecentsView mFallbackRecentsView;
|
||||
private OverviewActionsView mActionsView;
|
||||
private OverviewActionsView<?> mActionsView;
|
||||
private TISBindHelper mTISBindHelper;
|
||||
private @Nullable FallbackTaskbarUIController mTaskbarUIController;
|
||||
|
||||
@@ -224,11 +227,12 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends View> T getOverviewPanel() {
|
||||
return (T) mFallbackRecentsView;
|
||||
public FallbackRecentsView getOverviewPanel() {
|
||||
return mFallbackRecentsView;
|
||||
}
|
||||
|
||||
public OverviewActionsView getActionsView() {
|
||||
@Override
|
||||
public OverviewActionsView<?> getActionsView() {
|
||||
return mActionsView;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ import com.android.launcher3.util.NavigationMode;
|
||||
import com.android.launcher3.util.SettingsCache;
|
||||
import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
|
||||
import com.android.quickstep.util.ActiveGestureLog;
|
||||
import com.android.quickstep.util.AssistStateManager;
|
||||
import com.android.quickstep.util.GestureExclusionManager;
|
||||
import com.android.quickstep.util.GestureExclusionManager.ExclusionListener;
|
||||
import com.android.quickstep.util.NavBarPosition;
|
||||
@@ -96,7 +97,7 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
|
||||
private final DisplayController mDisplayController;
|
||||
|
||||
private final GestureExclusionManager mExclusionManager;
|
||||
|
||||
private final AssistStateManager mAssistStateManager;
|
||||
|
||||
private final RotationTouchHelper mRotationTouchHelper;
|
||||
private final TaskStackChangeListener mPipListener;
|
||||
@@ -147,6 +148,7 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
|
||||
mContext = context;
|
||||
mDisplayController = DisplayController.INSTANCE.get(context);
|
||||
mExclusionManager = exclusionManager;
|
||||
mAssistStateManager = AssistStateManager.INSTANCE.get(context);
|
||||
mIsOneHandedModeSupported = SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false);
|
||||
mRotationTouchHelper = RotationTouchHelper.INSTANCE.get(context);
|
||||
if (isInstanceForTouches) {
|
||||
@@ -587,8 +589,8 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
|
||||
: QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON;
|
||||
float touchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
|
||||
|
||||
if (DeviceConfigWrapper.get().getCustomLpnhThresholds()) {
|
||||
float customSlopMultiplier = DeviceConfigWrapper.get().getLpnhSlopPercentage() / 100f;
|
||||
if (mAssistStateManager.getLPNHCustomSlopMultiplier().isPresent()) {
|
||||
float customSlopMultiplier = mAssistStateManager.getLPNHCustomSlopMultiplier().get();
|
||||
return customSlopMultiplier * slopMultiplier * touchSlop;
|
||||
} else {
|
||||
return slopMultiplier * touchSlop;
|
||||
|
||||
@@ -57,7 +57,7 @@ public class RemoteTargetGluer {
|
||||
/**
|
||||
* Use this constructor if remote targets are split-screen independent
|
||||
*/
|
||||
public RemoteTargetGluer(Context context, BaseActivityInterface sizingStrategy,
|
||||
public RemoteTargetGluer(Context context, BaseContainerInterface sizingStrategy,
|
||||
RemoteAnimationTargets targets, boolean forDesktop) {
|
||||
init(context, sizingStrategy, targets.apps.length, forDesktop);
|
||||
}
|
||||
@@ -66,11 +66,11 @@ public class RemoteTargetGluer {
|
||||
* Use this constructor if you want the number of handles created to match the number of active
|
||||
* running tasks
|
||||
*/
|
||||
public RemoteTargetGluer(Context context, BaseActivityInterface sizingStrategy) {
|
||||
public RemoteTargetGluer(Context context, BaseContainerInterface sizingStrategy) {
|
||||
DesktopVisibilityController desktopVisibilityController =
|
||||
LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
|
||||
if (desktopVisibilityController != null) {
|
||||
int visibleTasksCount = desktopVisibilityController.getVisibleFreeformTasksCount();
|
||||
int visibleTasksCount = desktopVisibilityController.getVisibleDesktopTasksCount();
|
||||
if (visibleTasksCount > 0) {
|
||||
// Allocate +1 to account for a new task added to the desktop mode
|
||||
int numHandles = visibleTasksCount + 1;
|
||||
@@ -84,13 +84,13 @@ public class RemoteTargetGluer {
|
||||
init(context, sizingStrategy, DEFAULT_NUM_HANDLES, false /* forDesktop */);
|
||||
}
|
||||
|
||||
private void init(Context context, BaseActivityInterface sizingStrategy, int numHandles,
|
||||
private void init(Context context, BaseContainerInterface sizingStrategy, int numHandles,
|
||||
boolean forDesktop) {
|
||||
mRemoteTargetHandles = createHandles(context, sizingStrategy, numHandles, forDesktop);
|
||||
}
|
||||
|
||||
private RemoteTargetHandle[] createHandles(Context context,
|
||||
BaseActivityInterface sizingStrategy, int numHandles, boolean forDesktop) {
|
||||
BaseContainerInterface sizingStrategy, int numHandles, boolean forDesktop) {
|
||||
RemoteTargetHandle[] handles = new RemoteTargetHandle[numHandles];
|
||||
for (int i = 0; i < numHandles; i++) {
|
||||
TaskViewSimulator tvs = new TaskViewSimulator(context, sizingStrategy);
|
||||
|
||||
@@ -345,14 +345,14 @@ public class RotationTouchHelper implements DisplayInfoChangeListener {
|
||||
}
|
||||
|
||||
void onEndTargetCalculated(GestureState.GestureEndTarget endTarget,
|
||||
BaseActivityInterface activityInterface) {
|
||||
BaseContainerInterface containerInterface) {
|
||||
if (endTarget == GestureState.GestureEndTarget.RECENTS) {
|
||||
mInOverview = true;
|
||||
if (!mTaskListFrozen) {
|
||||
// If we're in landscape w/o ever quickswitching, show the navbar in landscape
|
||||
enableMultipleRegions(true);
|
||||
}
|
||||
activityInterface.onExitOverview(this, mExitOverviewRunnable);
|
||||
containerInterface.onExitOverview(this, mExitOverviewRunnable);
|
||||
} else if (endTarget == GestureState.GestureEndTarget.HOME
|
||||
|| endTarget == GestureState.GestureEndTarget.ALL_APPS) {
|
||||
enableMultipleRegions(false);
|
||||
|
||||
@@ -86,7 +86,7 @@ public abstract class SwipeUpAnimationLogic implements
|
||||
updateIsGestureForSplit(TopTaskTracker.INSTANCE.get(context)
|
||||
.getRunningSplitTaskIds().length);
|
||||
|
||||
mTargetGluer = new RemoteTargetGluer(mContext, mGestureState.getActivityInterface());
|
||||
mTargetGluer = new RemoteTargetGluer(mContext, mGestureState.getContainerInterface());
|
||||
mRemoteTargetHandles = mTargetGluer.getRemoteTargetHandles();
|
||||
runActionOnRemoteHandles(remoteTargetHandle ->
|
||||
remoteTargetHandle.getTaskViewSimulator().getOrientationState().update(
|
||||
@@ -97,9 +97,10 @@ public abstract class SwipeUpAnimationLogic implements
|
||||
|
||||
protected void initTransitionEndpoints(DeviceProfile dp) {
|
||||
mDp = dp;
|
||||
mTransitionDragLength = mGestureState.getActivityInterface().getSwipeUpDestinationAndLength(
|
||||
dp, mContext, TEMP_RECT, mRemoteTargetHandles[0].getTaskViewSimulator()
|
||||
.getOrientationState().getOrientationHandler());
|
||||
mTransitionDragLength = mGestureState.getContainerInterface()
|
||||
.getSwipeUpDestinationAndLength(dp, mContext, TEMP_RECT,
|
||||
mRemoteTargetHandles[0].getTaskViewSimulator().getOrientationState()
|
||||
.getOrientationHandler());
|
||||
mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength;
|
||||
|
||||
for (RemoteTargetHandle remoteHandle : mRemoteTargetHandles) {
|
||||
|
||||
@@ -1475,6 +1475,17 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle {
|
||||
}
|
||||
}
|
||||
|
||||
/** Call shell to move a task with given `taskId` to desktop */
|
||||
public void moveToDesktop(int taskId) {
|
||||
if (mDesktopMode != null) {
|
||||
try {
|
||||
mDesktopMode.moveToDesktop(taskId);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed call moveToDesktop", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Unfold transition
|
||||
//
|
||||
|
||||
@@ -77,10 +77,11 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
mLiveTileRestartListener);
|
||||
return;
|
||||
}
|
||||
BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface();
|
||||
if (activityInterface.isInLiveTileMode()
|
||||
&& activityInterface.getCreatedActivity() != null) {
|
||||
RecentsView recentsView = activityInterface.getCreatedActivity().getOverviewPanel();
|
||||
BaseContainerInterface containerInterface = mLastGestureState.getContainerInterface();
|
||||
if (containerInterface.isInLiveTileMode()
|
||||
&& containerInterface.getCreatedContainer() != null) {
|
||||
RecentsView recentsView = containerInterface.getCreatedContainer()
|
||||
.getOverviewPanel();
|
||||
if (recentsView != null) {
|
||||
recentsView.launchSideTaskInLiveTileModeForRestartedApp(task.taskId);
|
||||
TaskStackChangeListeners.getInstance().unregisterTaskStackListener(
|
||||
@@ -135,10 +136,10 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
cleanUpRecentsAnimation(mCallbacks);
|
||||
}
|
||||
|
||||
final BaseActivityInterface activityInterface = gestureState.getActivityInterface();
|
||||
final BaseContainerInterface containerInterface = gestureState.getContainerInterface();
|
||||
mLastGestureState = gestureState;
|
||||
RecentsAnimationCallbacks newCallbacks = new RecentsAnimationCallbacks(
|
||||
SystemUiProxy.INSTANCE.get(mCtx), activityInterface.allowMinimizeSplitScreen());
|
||||
SystemUiProxy.INSTANCE.get(mCtx), containerInterface.allowMinimizeSplitScreen());
|
||||
mCallbacks = newCallbacks;
|
||||
mCallbacks.addListener(new RecentsAnimationCallbacks.RecentsAnimationListener() {
|
||||
@Override
|
||||
@@ -208,17 +209,18 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
@Override
|
||||
public void onTasksAppeared(RemoteAnimationTarget[] appearedTaskTargets) {
|
||||
RemoteAnimationTarget appearedTaskTarget = appearedTaskTargets[0];
|
||||
BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface();
|
||||
BaseContainerInterface containerInterface =
|
||||
mLastGestureState.getContainerInterface();
|
||||
|
||||
for (RemoteAnimationTarget compat : appearedTaskTargets) {
|
||||
if (compat.windowConfiguration.getActivityType() == ACTIVITY_TYPE_HOME
|
||||
&& activityInterface.getCreatedActivity() instanceof RecentsActivity
|
||||
&& containerInterface.getCreatedContainer() instanceof RecentsActivity
|
||||
&& DisplayController.getNavigationMode(mCtx) != NO_BUTTON) {
|
||||
// The only time we get onTasksAppeared() in button navigation with a
|
||||
// 3p launcher is if the user goes to overview first, and in this case we
|
||||
// can immediately finish the transition
|
||||
RecentsView recentsView =
|
||||
activityInterface.getCreatedActivity().getOverviewPanel();
|
||||
containerInterface.getCreatedContainer().getOverviewPanel();
|
||||
if (recentsView != null) {
|
||||
recentsView.finishRecentsAnimation(true, null);
|
||||
}
|
||||
@@ -232,12 +234,12 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
if (nonAppTargets == null) {
|
||||
nonAppTargets = new RemoteAnimationTarget[0];
|
||||
}
|
||||
if ((activityInterface.isInLiveTileMode()
|
||||
if ((containerInterface.isInLiveTileMode()
|
||||
|| mLastGestureState.getEndTarget() == RECENTS
|
||||
|| isNonRecentsStartedTasksAppeared(appearedTaskTargets))
|
||||
&& activityInterface.getCreatedActivity() != null) {
|
||||
&& containerInterface.getCreatedContainer() != null) {
|
||||
RecentsView recentsView =
|
||||
activityInterface.getCreatedActivity().getOverviewPanel();
|
||||
containerInterface.getCreatedContainer().getOverviewPanel();
|
||||
if (recentsView != null) {
|
||||
ActiveGestureLog.INSTANCE.addLog(
|
||||
new ActiveGestureLog.CompoundString("Launching side task id=")
|
||||
@@ -272,13 +274,13 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
|
||||
@Override
|
||||
public boolean onSwitchToScreenshot(Runnable onFinished) {
|
||||
if (!activityInterface.isInLiveTileMode()
|
||||
|| activityInterface.getCreatedActivity() == null) {
|
||||
if (!containerInterface.isInLiveTileMode()
|
||||
|| containerInterface.getCreatedContainer() == null) {
|
||||
// No need to switch since tile is already a screenshot.
|
||||
onFinished.run();
|
||||
} else {
|
||||
final RecentsView recentsView =
|
||||
activityInterface.getCreatedActivity().getOverviewPanel();
|
||||
containerInterface.getCreatedContainer().getOverviewPanel();
|
||||
if (recentsView != null) {
|
||||
recentsView.switchToScreenshot(onFinished);
|
||||
} else {
|
||||
@@ -295,7 +297,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
if (ENABLE_SHELL_TRANSITIONS) {
|
||||
final ActivityOptions options = ActivityOptions.makeBasic();
|
||||
// Use regular (non-transient) launch for all apps page to control IME.
|
||||
if (!activityInterface.allowAllAppsFromOverview()) {
|
||||
if (!containerInterface.allowAllAppsFromOverview()) {
|
||||
options.setTransientLaunch();
|
||||
}
|
||||
options.setSourceInfo(ActivityOptions.SourceInfo.TYPE_RECENTS_ANIMATION, eventTime);
|
||||
@@ -332,10 +334,10 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
if (mLastGestureState == null) {
|
||||
return;
|
||||
}
|
||||
BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface();
|
||||
if (activityInterface.isInLiveTileMode()
|
||||
&& activityInterface.getCreatedActivity() != null) {
|
||||
RecentsView recentsView = activityInterface.getCreatedActivity().getOverviewPanel();
|
||||
BaseContainerInterface containerInterface = mLastGestureState.getContainerInterface();
|
||||
if (containerInterface.isInLiveTileMode()
|
||||
&& containerInterface.getCreatedContainer() != null) {
|
||||
RecentsView recentsView = containerInterface.getCreatedContainer().getOverviewPanel();
|
||||
if (recentsView != null) {
|
||||
recentsView.switchToScreenshot(null,
|
||||
() -> recentsView.finishRecentsAnimation(true /* toRecents */,
|
||||
|
||||
@@ -33,7 +33,6 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.Flags;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
@@ -46,6 +45,7 @@ import com.android.quickstep.util.RecentsOrientedState;
|
||||
import com.android.quickstep.views.GroupedTaskView;
|
||||
import com.android.quickstep.views.OverviewActionsView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
import com.android.quickstep.views.TaskThumbnailView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.quickstep.views.TaskView.TaskIdAttributeContainer;
|
||||
@@ -63,14 +63,15 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
public static List<SystemShortcut> getEnabledShortcuts(TaskView taskView,
|
||||
TaskIdAttributeContainer taskContainer) {
|
||||
final ArrayList<SystemShortcut> shortcuts = new ArrayList<>();
|
||||
final BaseDraggingActivity activity = BaseActivity.fromContext(taskView.getContext());
|
||||
final RecentsViewContainer container =
|
||||
RecentsViewContainer.containerFromContext(taskView.getContext());
|
||||
boolean hasMultipleTasks = taskView.getTaskIds()[1] != -1;
|
||||
for (TaskShortcutFactory menuOption : MENU_OPTIONS) {
|
||||
if (hasMultipleTasks && !menuOption.showForSplitscreen()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<SystemShortcut> menuShortcuts = menuOption.getShortcuts(activity, taskContainer);
|
||||
List<SystemShortcut> menuShortcuts = menuOption.getShortcuts(container, taskContainer);
|
||||
if (menuShortcuts == null) {
|
||||
continue;
|
||||
}
|
||||
@@ -79,15 +80,16 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
RecentsOrientedState orientedState = taskView.getRecentsView().getPagedViewOrientedState();
|
||||
boolean canLauncherRotate = orientedState.isRecentsActivityRotationAllowed();
|
||||
boolean isInLandscape = orientedState.getTouchRotation() != ROTATION_0;
|
||||
boolean isTablet = activity.getDeviceProfile().isTablet;
|
||||
boolean isTablet = container.getDeviceProfile().isTablet;
|
||||
|
||||
boolean isGridOnlyOverview = isTablet && Flags.enableGridOnlyOverview();
|
||||
// Add overview actions to the menu when in in-place rotate landscape mode, or in
|
||||
// grid-only overview.
|
||||
if ((!canLauncherRotate && isInLandscape) || isGridOnlyOverview) {
|
||||
// Add overview actions to the menu when:
|
||||
// - single task is showing
|
||||
// - in in-place rotate landscape mode, or in grid-only overview.
|
||||
if (!hasMultipleTasks && ((!canLauncherRotate && isInLandscape) || isGridOnlyOverview)) {
|
||||
// Add screenshot action to task menu.
|
||||
List<SystemShortcut> screenshotShortcuts = TaskShortcutFactory.SCREENSHOT
|
||||
.getShortcuts(activity, taskContainer);
|
||||
.getShortcuts(container, taskContainer);
|
||||
if (screenshotShortcuts != null) {
|
||||
shortcuts.addAll(screenshotShortcuts);
|
||||
}
|
||||
@@ -96,7 +98,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
// or in grid-only overview.
|
||||
if (orientedState.getDisplayRotation() == ROTATION_0 || isGridOnlyOverview) {
|
||||
List<SystemShortcut> modalShortcuts = TaskShortcutFactory.MODAL
|
||||
.getShortcuts(activity, taskContainer);
|
||||
.getShortcuts(container, taskContainer);
|
||||
if (modalShortcuts != null) {
|
||||
shortcuts.addAll(modalShortcuts);
|
||||
}
|
||||
@@ -136,6 +138,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
TaskShortcutFactory.PIN,
|
||||
TaskShortcutFactory.INSTALL,
|
||||
TaskShortcutFactory.FREE_FORM,
|
||||
DesktopSystemShortcut.Companion.createFactory(),
|
||||
TaskShortcutFactory.WELLBEING,
|
||||
TaskShortcutFactory.SAVE_APP_PAIR
|
||||
};
|
||||
@@ -253,9 +256,9 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
/**
|
||||
* Gets the system shortcut for the screenshot that will be added to the task menu.
|
||||
*/
|
||||
public SystemShortcut getScreenshotShortcut(BaseDraggingActivity activity,
|
||||
public SystemShortcut getScreenshotShortcut(RecentsViewContainer container,
|
||||
ItemInfo iteminfo, View originalView) {
|
||||
return new ScreenshotSystemShortcut(activity, iteminfo, originalView);
|
||||
return new ScreenshotSystemShortcut(container, iteminfo, originalView);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,19 +306,19 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
|
||||
private class ScreenshotSystemShortcut extends SystemShortcut {
|
||||
|
||||
private final BaseDraggingActivity mActivity;
|
||||
private final RecentsViewContainer mContainer;
|
||||
|
||||
ScreenshotSystemShortcut(BaseDraggingActivity activity, ItemInfo itemInfo,
|
||||
ScreenshotSystemShortcut(RecentsViewContainer container, ItemInfo itemInfo,
|
||||
View originalView) {
|
||||
super(R.drawable.ic_screenshot, R.string.action_screenshot, activity, itemInfo,
|
||||
super(R.drawable.ic_screenshot, R.string.action_screenshot, container, itemInfo,
|
||||
originalView);
|
||||
mActivity = activity;
|
||||
mContainer = container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
saveScreenshot(mThumbnailView.getTaskView().getTask());
|
||||
dismissTaskMenuView(mActivity);
|
||||
dismissTaskMenuView();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_FREE_FORM_TAP;
|
||||
import static com.android.window.flags.Flags.enableDesktopWindowingMode;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityOptions;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
@@ -39,7 +38,6 @@ import android.window.SplashScreen;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
@@ -50,9 +48,11 @@ import com.android.launcher3.popup.SystemShortcut;
|
||||
import com.android.launcher3.popup.SystemShortcut.AppInfo;
|
||||
import com.android.launcher3.util.InstantAppResolver;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
|
||||
import com.android.launcher3.views.ActivityContext;
|
||||
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
|
||||
import com.android.quickstep.views.GroupedTaskView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
import com.android.quickstep.views.TaskThumbnailView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.quickstep.views.TaskView.TaskIdAttributeContainer;
|
||||
@@ -74,7 +74,7 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public interface TaskShortcutFactory {
|
||||
@Nullable
|
||||
default List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
|
||||
default List<SystemShortcut> getShortcuts(RecentsViewContainer container,
|
||||
TaskIdAttributeContainer taskContainer) {
|
||||
return null;
|
||||
}
|
||||
@@ -94,7 +94,7 @@ public interface TaskShortcutFactory {
|
||||
|
||||
TaskShortcutFactory APP_INFO = new TaskShortcutFactory() {
|
||||
@Override
|
||||
public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
|
||||
public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
|
||||
TaskIdAttributeContainer taskContainer) {
|
||||
TaskView taskView = taskContainer.getTaskView();
|
||||
AppInfo.SplitAccessibilityInfo accessibilityInfo =
|
||||
@@ -102,7 +102,7 @@ public interface TaskShortcutFactory {
|
||||
TaskUtils.getTitle(taskView.getContext(), taskContainer.getTask()),
|
||||
taskContainer.getA11yNodeId()
|
||||
);
|
||||
return Collections.singletonList(new AppInfo(activity, taskContainer.getItemInfo(),
|
||||
return Collections.singletonList(new AppInfo(container, taskContainer.getItemInfo(),
|
||||
taskView, accessibilityInfo));
|
||||
}
|
||||
|
||||
@@ -116,9 +116,9 @@ public interface TaskShortcutFactory {
|
||||
private final TaskView mTaskView;
|
||||
private final SplitPositionOption mSplitPositionOption;
|
||||
|
||||
public SplitSelectSystemShortcut(BaseDraggingActivity target, TaskView taskView,
|
||||
public SplitSelectSystemShortcut(RecentsViewContainer container, TaskView taskView,
|
||||
SplitPositionOption option) {
|
||||
super(option.iconResId, option.textResId, target, taskView.getItemInfo(), taskView);
|
||||
super(option.iconResId, option.textResId, container, taskView.getItemInfo(), taskView);
|
||||
mTaskView = taskView;
|
||||
mSplitPositionOption = option;
|
||||
}
|
||||
@@ -133,25 +133,26 @@ public interface TaskShortcutFactory {
|
||||
* A menu item, "Save app pair", that allows the user to preserve the current app combination as
|
||||
* one persistent icon on the Home screen, allowing for quick split screen launching.
|
||||
*/
|
||||
class SaveAppPairSystemShortcut extends SystemShortcut<BaseDraggingActivity> {
|
||||
class SaveAppPairSystemShortcut extends SystemShortcut<RecentsViewContainer> {
|
||||
private final GroupedTaskView mTaskView;
|
||||
|
||||
public SaveAppPairSystemShortcut(BaseDraggingActivity activity, GroupedTaskView taskView,
|
||||
int iconResId) {
|
||||
super(iconResId, R.string.save_app_pair, activity,
|
||||
|
||||
public SaveAppPairSystemShortcut(RecentsViewContainer container, GroupedTaskView taskView,
|
||||
int iconResId) {
|
||||
super(iconResId, R.string.save_app_pair, container,
|
||||
taskView.getItemInfo(), taskView);
|
||||
mTaskView = taskView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
dismissTaskMenuView(mTarget);
|
||||
dismissTaskMenuView();
|
||||
((RecentsView) mTarget.getOverviewPanel())
|
||||
.getSplitSelectController().getAppPairsController().saveAppPair(mTaskView);
|
||||
}
|
||||
}
|
||||
|
||||
class FreeformSystemShortcut extends SystemShortcut<BaseDraggingActivity> {
|
||||
class FreeformSystemShortcut extends SystemShortcut<RecentsViewContainer> {
|
||||
private static final String TAG = "FreeformSystemShortcut";
|
||||
|
||||
private Handler mHandler;
|
||||
@@ -161,20 +162,20 @@ public interface TaskShortcutFactory {
|
||||
private final TaskView mTaskView;
|
||||
private final LauncherEvent mLauncherEvent;
|
||||
|
||||
public FreeformSystemShortcut(int iconRes, int textRes, BaseDraggingActivity activity,
|
||||
public FreeformSystemShortcut(int iconRes, int textRes, RecentsViewContainer container,
|
||||
TaskIdAttributeContainer taskContainer, LauncherEvent launcherEvent) {
|
||||
super(iconRes, textRes, activity, taskContainer.getItemInfo(),
|
||||
super(iconRes, textRes, container, taskContainer.getItemInfo(),
|
||||
taskContainer.getTaskView());
|
||||
mLauncherEvent = launcherEvent;
|
||||
mHandler = new Handler(Looper.getMainLooper());
|
||||
mTaskView = taskContainer.getTaskView();
|
||||
mRecentsView = activity.getOverviewPanel();
|
||||
mRecentsView = container.getOverviewPanel();
|
||||
mThumbnailView = taskContainer.getThumbnailView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
dismissTaskMenuView(mTarget);
|
||||
dismissTaskMenuView();
|
||||
RecentsView rv = mTarget.getOverviewPanel();
|
||||
rv.switchToScreenshot(() -> {
|
||||
rv.finishRecentsAnimation(true /* toRecents */, false /* shouldPip */, () -> {
|
||||
@@ -252,11 +253,11 @@ public interface TaskShortcutFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private ActivityOptions makeLaunchOptions(Activity activity) {
|
||||
private ActivityOptions makeLaunchOptions(RecentsViewContainer container) {
|
||||
ActivityOptions activityOptions = ActivityOptions.makeBasic();
|
||||
activityOptions.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
|
||||
// Arbitrary bounds only because freeform is in dev mode right now
|
||||
final View decorView = activity.getWindow().getDecorView();
|
||||
final View decorView = container.getWindow().getDecorView();
|
||||
final WindowInsets insets = decorView.getRootWindowInsets();
|
||||
final Rect r = new Rect(0, 0, decorView.getWidth() / 2, decorView.getHeight() / 2);
|
||||
r.offsetTo(insets.getSystemWindowInsetLeft() + 50,
|
||||
@@ -277,9 +278,9 @@ public interface TaskShortcutFactory {
|
||||
*/
|
||||
TaskShortcutFactory SPLIT_SELECT = new TaskShortcutFactory() {
|
||||
@Override
|
||||
public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
|
||||
public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
|
||||
TaskIdAttributeContainer taskContainer) {
|
||||
DeviceProfile deviceProfile = activity.getDeviceProfile();
|
||||
DeviceProfile deviceProfile = container.getDeviceProfile();
|
||||
final Task task = taskContainer.getTask();
|
||||
final int intentFlags = task.key.baseIntent.getFlags();
|
||||
final TaskView taskView = taskContainer.getTaskView();
|
||||
@@ -291,7 +292,7 @@ public interface TaskShortcutFactory {
|
||||
!deviceProfile.isTaskbarPresent && recentsView.getTaskViewCount() < 2;
|
||||
boolean isTaskSplitNotSupported = !task.isDockable ||
|
||||
(intentFlags & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0;
|
||||
boolean hideForExistingMultiWindow = activity.getDeviceProfile().isMultiWindowMode;
|
||||
boolean hideForExistingMultiWindow = container.getDeviceProfile().isMultiWindowMode;
|
||||
boolean isFocusedTask = deviceProfile.isTablet && taskView.isFocusedTask();
|
||||
boolean isTaskInExpectedScrollPosition =
|
||||
recentsView.isTaskInExpectedScrollPosition(recentsView.indexOfChild(taskView));
|
||||
@@ -304,7 +305,7 @@ public interface TaskShortcutFactory {
|
||||
return orientationHandler.getSplitPositionOptions(deviceProfile)
|
||||
.stream()
|
||||
.map((Function<SplitPositionOption, SystemShortcut>) option ->
|
||||
new SplitSelectSystemShortcut(activity, taskView, option))
|
||||
new SplitSelectSystemShortcut(container, taskView, option))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
};
|
||||
@@ -312,9 +313,9 @@ public interface TaskShortcutFactory {
|
||||
TaskShortcutFactory SAVE_APP_PAIR = new TaskShortcutFactory() {
|
||||
@Nullable
|
||||
@Override
|
||||
public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
|
||||
public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
|
||||
TaskIdAttributeContainer taskContainer) {
|
||||
DeviceProfile deviceProfile = activity.getDeviceProfile();
|
||||
DeviceProfile deviceProfile = container.getDeviceProfile();
|
||||
final TaskView taskView = taskContainer.getTaskView();
|
||||
final RecentsView recentsView = taskView.getRecentsView();
|
||||
boolean isLargeTileFocusedTask = deviceProfile.isTablet && taskView.isFocusedTask();
|
||||
@@ -348,7 +349,8 @@ public interface TaskShortcutFactory {
|
||||
: R.drawable.ic_save_app_pair_up_down;
|
||||
|
||||
return Collections.singletonList(
|
||||
new SaveAppPairSystemShortcut(activity, (GroupedTaskView) taskView, iconResId));
|
||||
new SaveAppPairSystemShortcut(container,
|
||||
(GroupedTaskView) taskView, iconResId));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -359,25 +361,25 @@ public interface TaskShortcutFactory {
|
||||
|
||||
TaskShortcutFactory FREE_FORM = new TaskShortcutFactory() {
|
||||
@Override
|
||||
public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
|
||||
public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
|
||||
TaskIdAttributeContainer taskContainer) {
|
||||
final Task task = taskContainer.getTask();
|
||||
if (!task.isDockable) {
|
||||
return null;
|
||||
}
|
||||
if (!isAvailable(activity, task.key.displayId)) {
|
||||
if (!isAvailable(container)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Collections.singletonList(new FreeformSystemShortcut(
|
||||
R.drawable.ic_caption_desktop_button_foreground,
|
||||
R.string.recent_task_option_freeform, activity, taskContainer,
|
||||
R.string.recent_task_option_freeform, container, taskContainer,
|
||||
LAUNCHER_SYSTEM_SHORTCUT_FREE_FORM_TAP));
|
||||
}
|
||||
|
||||
private boolean isAvailable(BaseDraggingActivity activity, int displayId) {
|
||||
private boolean isAvailable(RecentsViewContainer container) {
|
||||
return Settings.Global.getInt(
|
||||
activity.getContentResolver(),
|
||||
container.asContext().getContentResolver(),
|
||||
Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0
|
||||
&& !enableDesktopWindowingMode();
|
||||
}
|
||||
@@ -385,9 +387,9 @@ public interface TaskShortcutFactory {
|
||||
|
||||
TaskShortcutFactory PIN = new TaskShortcutFactory() {
|
||||
@Override
|
||||
public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
|
||||
public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
|
||||
TaskIdAttributeContainer taskContainer) {
|
||||
if (!SystemUiProxy.INSTANCE.get(activity).isActive()) {
|
||||
if (!SystemUiProxy.INSTANCE.get(container.asContext()).isActive()) {
|
||||
return null;
|
||||
}
|
||||
if (!ActivityManagerWrapper.getInstance().isScreenPinningEnabled()) {
|
||||
@@ -397,17 +399,17 @@ public interface TaskShortcutFactory {
|
||||
// We shouldn't be able to pin while an app is locked.
|
||||
return null;
|
||||
}
|
||||
return Collections.singletonList(new PinSystemShortcut(activity, taskContainer));
|
||||
return Collections.singletonList(new PinSystemShortcut(container, taskContainer));
|
||||
}
|
||||
};
|
||||
|
||||
class PinSystemShortcut extends SystemShortcut<BaseDraggingActivity> {
|
||||
class PinSystemShortcut extends SystemShortcut<RecentsViewContainer> {
|
||||
|
||||
private static final String TAG = "PinSystemShortcut";
|
||||
|
||||
private final TaskView mTaskView;
|
||||
|
||||
public PinSystemShortcut(BaseDraggingActivity target,
|
||||
public PinSystemShortcut(RecentsViewContainer target,
|
||||
TaskIdAttributeContainer taskContainer) {
|
||||
super(R.drawable.ic_pin, R.string.recent_task_option_pin, target,
|
||||
taskContainer.getItemInfo(), taskContainer.getTaskView());
|
||||
@@ -417,10 +419,10 @@ public interface TaskShortcutFactory {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (mTaskView.launchTaskAnimated() != null) {
|
||||
SystemUiProxy.INSTANCE.get(mTarget).startScreenPinning(
|
||||
SystemUiProxy.INSTANCE.get(mTarget.asContext()).startScreenPinning(
|
||||
mTaskView.getTask().key.id);
|
||||
}
|
||||
dismissTaskMenuView(mTarget);
|
||||
dismissTaskMenuView();
|
||||
mTarget.getStatsLogManager().logger().withItemInfo(mTaskView.getItemInfo())
|
||||
.log(LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_PIN_TAP);
|
||||
}
|
||||
@@ -428,12 +430,12 @@ public interface TaskShortcutFactory {
|
||||
|
||||
TaskShortcutFactory INSTALL = new TaskShortcutFactory() {
|
||||
@Override
|
||||
public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
|
||||
public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
|
||||
TaskIdAttributeContainer taskContainer) {
|
||||
Task t = taskContainer.getTask();
|
||||
return InstantAppResolver.newInstance(activity).isInstantApp(
|
||||
return InstantAppResolver.newInstance(container.asContext()).isInstantApp(
|
||||
t.getTopComponent().getPackageName(), t.getKey().userId)
|
||||
? Collections.singletonList(new SystemShortcut.Install(activity,
|
||||
? Collections.singletonList(new SystemShortcut.Install(container,
|
||||
taskContainer.getItemInfo(), taskContainer.getTaskView()))
|
||||
: null;
|
||||
}
|
||||
@@ -441,10 +443,10 @@ public interface TaskShortcutFactory {
|
||||
|
||||
TaskShortcutFactory WELLBEING = new TaskShortcutFactory() {
|
||||
@Override
|
||||
public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
|
||||
public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
|
||||
TaskIdAttributeContainer taskContainer) {
|
||||
SystemShortcut<BaseDraggingActivity> wellbeingShortcut =
|
||||
WellbeingModel.SHORTCUT_FACTORY.getShortcut(activity,
|
||||
SystemShortcut<ActivityContext> wellbeingShortcut =
|
||||
WellbeingModel.SHORTCUT_FACTORY.getShortcut(container,
|
||||
taskContainer.getItemInfo(), taskContainer.getTaskView());
|
||||
return createSingletonShortcutList(wellbeingShortcut);
|
||||
}
|
||||
@@ -452,11 +454,11 @@ public interface TaskShortcutFactory {
|
||||
|
||||
TaskShortcutFactory SCREENSHOT = new TaskShortcutFactory() {
|
||||
@Override
|
||||
public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
|
||||
public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
|
||||
TaskIdAttributeContainer taskContainer) {
|
||||
SystemShortcut screenshotShortcut =
|
||||
taskContainer.getThumbnailView().getTaskOverlay()
|
||||
.getScreenshotShortcut(activity, taskContainer.getItemInfo(),
|
||||
.getScreenshotShortcut(container, taskContainer.getItemInfo(),
|
||||
taskContainer.getTaskView());
|
||||
return createSingletonShortcutList(screenshotShortcut);
|
||||
}
|
||||
@@ -464,7 +466,7 @@ public interface TaskShortcutFactory {
|
||||
|
||||
TaskShortcutFactory MODAL = new TaskShortcutFactory() {
|
||||
@Override
|
||||
public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
|
||||
public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
|
||||
TaskIdAttributeContainer taskContainer) {
|
||||
SystemShortcut modalStateSystemShortcut =
|
||||
taskContainer.getThumbnailView().getTaskOverlay()
|
||||
|
||||
@@ -120,6 +120,7 @@ import com.android.quickstep.util.ActiveGestureLog;
|
||||
import com.android.quickstep.util.ActiveGestureLog.CompoundString;
|
||||
import com.android.quickstep.util.AssistStateManager;
|
||||
import com.android.quickstep.util.AssistUtils;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
import com.android.systemui.shared.recents.IOverviewProxy;
|
||||
import com.android.systemui.shared.recents.ISystemUiProxy;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
@@ -317,7 +318,7 @@ public class TouchInteractionService extends Service {
|
||||
public void enterStageSplitFromRunningApp(boolean leftOrTop) {
|
||||
executeForTouchInteractionService(tis -> {
|
||||
StatefulActivity activity =
|
||||
tis.mOverviewComponentObserver.getActivityInterface().getCreatedActivity();
|
||||
tis.mOverviewComponentObserver.getActivityInterface().getCreatedContainer();
|
||||
if (activity != null) {
|
||||
activity.enterStageSplitFromRunningApp(leftOrTop);
|
||||
}
|
||||
@@ -594,7 +595,7 @@ public class TouchInteractionService extends Service {
|
||||
mAllAppsActionManager.setHomeAndOverviewSame(isHomeAndOverviewSame);
|
||||
|
||||
StatefulActivity newOverviewActivity = mOverviewComponentObserver.getActivityInterface()
|
||||
.getCreatedActivity();
|
||||
.getCreatedContainer();
|
||||
if (newOverviewActivity != null) {
|
||||
mTaskbarManager.setActivity(newOverviewActivity);
|
||||
}
|
||||
@@ -602,23 +603,21 @@ public class TouchInteractionService extends Service {
|
||||
}
|
||||
|
||||
private PendingIntent createAllAppsPendingIntent() {
|
||||
final Intent homeIntent = new Intent(mOverviewComponentObserver.getHomeIntent())
|
||||
.setAction(INTENT_ACTION_ALL_APPS_TOGGLE);
|
||||
|
||||
if (FeatureFlags.ENABLE_ALL_APPS_SEARCH_IN_TASKBAR.get()) {
|
||||
return new PendingIntent(new IIntentSender.Stub() {
|
||||
@Override
|
||||
public void send(int code, Intent intent, String resolvedType,
|
||||
IBinder allowlistToken, IIntentReceiver finishedReceiver,
|
||||
String requiredPermission, Bundle options) {
|
||||
MAIN_EXECUTOR.execute(() -> mTaskbarManager.toggleAllApps(homeIntent));
|
||||
MAIN_EXECUTOR.execute(() -> mTaskbarManager.toggleAllApps());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return PendingIntent.getActivity(
|
||||
this,
|
||||
GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS,
|
||||
homeIntent,
|
||||
new Intent(mOverviewComponentObserver.getHomeIntent())
|
||||
.setAction(INTENT_ACTION_ALL_APPS_TOGGLE),
|
||||
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
||||
}
|
||||
}
|
||||
@@ -830,8 +829,8 @@ public class TouchInteractionService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
boolean cancelGesture = mGestureState.getActivityInterface() != null
|
||||
&& mGestureState.getActivityInterface().shouldCancelCurrentGesture();
|
||||
boolean cancelGesture = mGestureState.getContainerInterface() != null
|
||||
&& mGestureState.getContainerInterface().shouldCancelCurrentGesture();
|
||||
boolean cleanUpConsumer = (action == ACTION_UP || action == ACTION_CANCEL || cancelGesture)
|
||||
&& mConsumer != null
|
||||
&& !mConsumer.getActiveConsumerInHierarchy().isConsumerDetachedFromGesture();
|
||||
@@ -1148,7 +1147,7 @@ public class TouchInteractionService extends Service {
|
||||
|
||||
TopTaskTracker.CachedTaskInfo runningTask = gestureState.getRunningTask();
|
||||
// Use overview input consumer for sharesheets on top of home.
|
||||
boolean forceOverviewInputConsumer = gestureState.getActivityInterface().isStarted()
|
||||
boolean forceOverviewInputConsumer = gestureState.getContainerInterface().isStarted()
|
||||
&& runningTask != null
|
||||
&& runningTask.isRootChooseActivity();
|
||||
|
||||
@@ -1172,7 +1171,7 @@ public class TouchInteractionService extends Service {
|
||||
// with shell-transitions, home is resumed during recents animation, so
|
||||
// explicitly check against recents animation too.
|
||||
boolean launcherResumedThroughShellTransition =
|
||||
gestureState.getActivityInterface().isResumed()
|
||||
gestureState.getContainerInterface().isResumed()
|
||||
&& !previousGestureState.isRecentsAnimationRunning();
|
||||
// If a task fragment within Launcher is resumed
|
||||
boolean launcherChildActivityResumed = useActivityOverlay()
|
||||
@@ -1182,7 +1181,7 @@ public class TouchInteractionService extends Service {
|
||||
&& !launcherResumedThroughShellTransition
|
||||
&& !previousGestureState.isRecentsAnimationRunning();
|
||||
|
||||
if (gestureState.getActivityInterface().isInLiveTileMode()) {
|
||||
if (gestureState.getContainerInterface().isInLiveTileMode()) {
|
||||
return createOverviewInputConsumer(
|
||||
previousGestureState,
|
||||
gestureState,
|
||||
@@ -1230,7 +1229,7 @@ public class TouchInteractionService extends Service {
|
||||
|
||||
final AbsSwipeUpHandler.Factory factory = getSwipeUpHandlerFactory();
|
||||
final boolean shouldDefer = !mOverviewComponentObserver.isHomeAndOverviewSame()
|
||||
|| gestureState.getActivityInterface().deferStartingActivity(mDeviceState, event);
|
||||
|| gestureState.getContainerInterface().deferStartingActivity(mDeviceState, event);
|
||||
final boolean disableHorizontalSwipe = mDeviceState.isInExclusionRegion(event);
|
||||
return new OtherActivityInputConsumer(this, mDeviceState, mTaskAnimationManager,
|
||||
gestureState, shouldDefer, this::onConsumerInactive,
|
||||
@@ -1264,18 +1263,19 @@ public class TouchInteractionService extends Service {
|
||||
MotionEvent event,
|
||||
boolean forceOverviewInputConsumer,
|
||||
CompoundString reasonString) {
|
||||
StatefulActivity activity = gestureState.getActivityInterface().getCreatedActivity();
|
||||
if (activity == null) {
|
||||
RecentsViewContainer container = gestureState.getContainerInterface().getCreatedContainer();
|
||||
if (container == null) {
|
||||
return getDefaultInputConsumer(
|
||||
reasonString.append(SUBSTRING_PREFIX)
|
||||
.append("activity == null, trying to use default input consumer"));
|
||||
}
|
||||
|
||||
boolean hasWindowFocus = activity.getRootView().hasWindowFocus();
|
||||
boolean hasWindowFocus = container.getRootView().hasWindowFocus();
|
||||
boolean isPreviousGestureAnimatingToLauncher =
|
||||
previousGestureState.isRunningAnimationToLauncher()
|
||||
|| mDeviceState.isPredictiveBackToHomeInProgress();
|
||||
boolean isInLiveTileMode = gestureState.getActivityInterface().isInLiveTileMode();
|
||||
boolean isInLiveTileMode = gestureState.getContainerInterface().isInLiveTileMode();
|
||||
|
||||
reasonString.append(SUBSTRING_PREFIX)
|
||||
.append(hasWindowFocus
|
||||
? "activity has window focus"
|
||||
@@ -1289,14 +1289,14 @@ public class TouchInteractionService extends Service {
|
||||
|| isInLiveTileMode) {
|
||||
reasonString.append(SUBSTRING_PREFIX)
|
||||
.append("overview should have focus, using OverviewInputConsumer");
|
||||
return new OverviewInputConsumer(gestureState, activity, mInputMonitorCompat,
|
||||
return new OverviewInputConsumer(gestureState, container, mInputMonitorCompat,
|
||||
false /* startingInActivityBounds */);
|
||||
} else {
|
||||
reasonString.append(SUBSTRING_PREFIX).append(
|
||||
"overview shouldn't have focus, using OverviewWithoutFocusInputConsumer");
|
||||
final boolean disableHorizontalSwipe = mDeviceState.isInExclusionRegion(event);
|
||||
return new OverviewWithoutFocusInputConsumer(activity, mDeviceState, gestureState,
|
||||
mInputMonitorCompat, disableHorizontalSwipe);
|
||||
return new OverviewWithoutFocusInputConsumer(container.asContext(), mDeviceState,
|
||||
gestureState, mInputMonitorCompat, disableHorizontalSwipe);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1369,7 +1369,7 @@ public class TouchInteractionService extends Service {
|
||||
mOverviewComponentObserver.getActivityInterface();
|
||||
final Intent overviewIntent = new Intent(
|
||||
mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState());
|
||||
if (activityInterface.getCreatedActivity() != null && fromInit) {
|
||||
if (activityInterface.getCreatedContainer() != null && fromInit) {
|
||||
// The activity has been created before the initialization of overview service. It is
|
||||
// usually happens when booting or launcher is the top activity, so we should already
|
||||
// have the latest state.
|
||||
@@ -1391,7 +1391,7 @@ public class TouchInteractionService extends Service {
|
||||
}
|
||||
final BaseActivityInterface activityInterface =
|
||||
mOverviewComponentObserver.getActivityInterface();
|
||||
final BaseDraggingActivity activity = activityInterface.getCreatedActivity();
|
||||
final BaseDraggingActivity activity = activityInterface.getCreatedContainer();
|
||||
if (activity == null || activity.isStarted()) {
|
||||
// We only care about the existing background activity.
|
||||
return;
|
||||
@@ -1441,7 +1441,7 @@ public class TouchInteractionService extends Service {
|
||||
DisplayController.INSTANCE.get(this).dump(pw);
|
||||
pw.println("TouchState:");
|
||||
BaseDraggingActivity createdOverviewActivity = mOverviewComponentObserver == null ? null
|
||||
: mOverviewComponentObserver.getActivityInterface().getCreatedActivity();
|
||||
: mOverviewComponentObserver.getActivityInterface().getCreatedContainer();
|
||||
boolean resumed = mOverviewComponentObserver != null
|
||||
&& mOverviewComponentObserver.getActivityInterface().isResumed();
|
||||
pw.println(" createdOverviewActivity=" + createdOverviewActivity);
|
||||
|
||||
@@ -24,9 +24,9 @@ import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
import com.android.launcher3.util.NavigationMode;
|
||||
import com.android.launcher3.util.TouchController;
|
||||
import com.android.quickstep.RecentsActivity;
|
||||
import com.android.quickstep.util.NavBarPosition;
|
||||
import com.android.quickstep.util.TriggerSwipeUpTouchTracker;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
|
||||
/**
|
||||
* In 0-button mode, intercepts swipe up from the nav bar on FallbackRecentsView to go home.
|
||||
@@ -34,17 +34,18 @@ import com.android.quickstep.util.TriggerSwipeUpTouchTracker;
|
||||
public class FallbackNavBarTouchController implements TouchController,
|
||||
TriggerSwipeUpTouchTracker.OnSwipeUpListener {
|
||||
|
||||
private final RecentsActivity mActivity;
|
||||
private final RecentsViewContainer mContainer;
|
||||
@Nullable
|
||||
private final TriggerSwipeUpTouchTracker mTriggerSwipeUpTracker;
|
||||
|
||||
public FallbackNavBarTouchController(RecentsActivity activity) {
|
||||
mActivity = activity;
|
||||
NavigationMode sysUINavigationMode = DisplayController.getNavigationMode(mActivity);
|
||||
public FallbackNavBarTouchController(RecentsViewContainer container) {
|
||||
mContainer = container;
|
||||
NavigationMode sysUINavigationMode =
|
||||
DisplayController.getNavigationMode(mContainer.asContext());
|
||||
if (sysUINavigationMode == NavigationMode.NO_BUTTON) {
|
||||
NavBarPosition navBarPosition = new NavBarPosition(sysUINavigationMode,
|
||||
DisplayController.INSTANCE.get(mActivity).getInfo());
|
||||
mTriggerSwipeUpTracker = new TriggerSwipeUpTouchTracker(mActivity,
|
||||
DisplayController.INSTANCE.get(mContainer.asContext()).getInfo());
|
||||
mTriggerSwipeUpTracker = new TriggerSwipeUpTouchTracker(mContainer.asContext(),
|
||||
true /* disableHorizontalSwipe */, navBarPosition, this);
|
||||
} else {
|
||||
mTriggerSwipeUpTracker = null;
|
||||
@@ -75,6 +76,6 @@ public class FallbackNavBarTouchController implements TouchController,
|
||||
|
||||
@Override
|
||||
public void onSwipeUp(boolean wasFling, PointF finalVelocity) {
|
||||
mActivity.<FallbackRecentsView>getOverviewPanel().startHome();
|
||||
mContainer.<FallbackRecentsView>getOverviewPanel().startHome();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,9 @@ import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.util.MultiPropertyFactory;
|
||||
import com.android.quickstep.RecentsActivity;
|
||||
import com.android.quickstep.views.ClearAllButton;
|
||||
import com.android.quickstep.views.OverviewActionsView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
|
||||
/**
|
||||
* State controller for fallback recents activity
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.desktop.DesktopRecentsTransitionController;
|
||||
import com.android.launcher3.logging.StatsLogManager;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource;
|
||||
@@ -67,7 +68,7 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
|
||||
|
||||
public FallbackRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr, FallbackActivityInterface.INSTANCE);
|
||||
mActivity.getStateManager().addStateListener(this);
|
||||
mContainer.getStateManager().addStateListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -80,13 +81,18 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
|
||||
|
||||
@Override
|
||||
protected void handleStartHome(boolean animated) {
|
||||
mActivity.startHome();
|
||||
AbstractFloatingView.closeAllOpenViews(mActivity, mActivity.isStarted());
|
||||
mContainer.startHome();
|
||||
AbstractFloatingView.closeAllOpenViews(mContainer, mContainer.isStarted());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canStartHomeSafely() {
|
||||
return mActivity.canStartHomeSafely();
|
||||
return mContainer.canStartHomeSafely();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateManager<RecentsState> getStateManager() {
|
||||
return mContainer.getStateManager();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,10 +216,10 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
|
||||
public void setModalStateEnabled(int taskId, boolean animate) {
|
||||
if (taskId != INVALID_TASK_ID) {
|
||||
setSelectedTask(taskId);
|
||||
mActivity.getStateManager().goToState(RecentsState.MODAL_TASK, animate);
|
||||
mContainer.getStateManager().goToState(RecentsState.MODAL_TASK, animate);
|
||||
} else {
|
||||
if (mActivity.isInState(RecentsState.MODAL_TASK)) {
|
||||
mActivity.getStateManager().goToState(DEFAULT, animate);
|
||||
if (mContainer.isInState(RecentsState.MODAL_TASK)) {
|
||||
mContainer.getStateManager().goToState(DEFAULT, animate);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -223,13 +229,13 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
|
||||
@SplitConfigurationOptions.StagePosition int stagePosition,
|
||||
StatsLogManager.EventEnum splitEvent) {
|
||||
super.initiateSplitSelect(taskView, stagePosition, splitEvent);
|
||||
mActivity.getStateManager().goToState(OVERVIEW_SPLIT_SELECT);
|
||||
mContainer.getStateManager().goToState(OVERVIEW_SPLIT_SELECT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateTransitionStart(RecentsState toState) {
|
||||
setOverviewStateEnabled(true);
|
||||
setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
|
||||
setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mContainer.getDeviceProfile()));
|
||||
setOverviewFullscreenEnabled(toState.isFullScreen());
|
||||
if (toState == MODAL_TASK) {
|
||||
setOverviewSelectEnabled(true);
|
||||
@@ -280,7 +286,7 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
|
||||
public void setOverviewStateEnabled(boolean enabled) {
|
||||
super.setOverviewStateEnabled(enabled);
|
||||
if (enabled) {
|
||||
RecentsState state = mActivity.getStateManager().getState();
|
||||
RecentsState state = mContainer.getStateManager().getState();
|
||||
setDisallowScrollToClearAll(!state.hasClearAllButton());
|
||||
}
|
||||
}
|
||||
@@ -289,18 +295,18 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
boolean result = super.onTouchEvent(ev);
|
||||
// Do not let touch escape to siblings below this view.
|
||||
return result || mActivity.getStateManager().getState().overviewUi();
|
||||
return result || mContainer.getStateManager().getState().overviewUi();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initiateSplitSelect(SplitSelectSource splitSelectSource) {
|
||||
super.initiateSplitSelect(splitSelectSource);
|
||||
mActivity.getStateManager().goToState(OVERVIEW_SPLIT_SELECT);
|
||||
mContainer.getStateManager().goToState(OVERVIEW_SPLIT_SELECT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canLaunchFullscreenTask() {
|
||||
return !mActivity.isInState(OVERVIEW_SPLIT_SELECT);
|
||||
return !mContainer.isInState(OVERVIEW_SPLIT_SELECT);
|
||||
}
|
||||
|
||||
/** Returns if app pairs are supported in this launcher. */
|
||||
|
||||
@@ -26,7 +26,8 @@ import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.statemanager.BaseState;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.quickstep.RecentsActivity;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
|
||||
/**
|
||||
* State definition for Fallback recents
|
||||
@@ -126,12 +127,13 @@ public class RecentsState implements BaseState<RecentsState> {
|
||||
/**
|
||||
* For this state, what color scrim should be drawn behind overview.
|
||||
*/
|
||||
public int getScrimColor(RecentsActivity activity) {
|
||||
return hasFlag(FLAG_SCRIM) ? Themes.getAttrColor(activity, R.attr.overviewScrimColor)
|
||||
public int getScrimColor(Context context) {
|
||||
return hasFlag(FLAG_SCRIM)
|
||||
? Themes.getAttrColor(context, R.attr.overviewScrimColor)
|
||||
: Color.TRANSPARENT;
|
||||
}
|
||||
|
||||
public float[] getOverviewScaleAndOffset(RecentsActivity activity) {
|
||||
public float[] getOverviewScaleAndOffset(RecentsViewContainer container) {
|
||||
return new float[] { NO_SCALE, NO_OFFSET };
|
||||
}
|
||||
|
||||
@@ -161,8 +163,8 @@ public class RecentsState implements BaseState<RecentsState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] getOverviewScaleAndOffset(RecentsActivity activity) {
|
||||
return getOverviewScaleAndOffsetForModalState(activity);
|
||||
public float[] getOverviewScaleAndOffset(RecentsViewContainer container) {
|
||||
return getOverviewScaleAndOffsetForModalState(container.getOverviewPanel());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,8 +174,8 @@ public class RecentsState implements BaseState<RecentsState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] getOverviewScaleAndOffset(RecentsActivity activity) {
|
||||
return getOverviewScaleAndOffsetForBackgroundState(activity);
|
||||
public float[] getOverviewScaleAndOffset(RecentsViewContainer container) {
|
||||
return getOverviewScaleAndOffsetForBackgroundState(container.getOverviewPanel());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +185,7 @@ public class RecentsState implements BaseState<RecentsState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] getOverviewScaleAndOffset(RecentsActivity activity) {
|
||||
public float[] getOverviewScaleAndOffset(RecentsViewContainer container) {
|
||||
return new float[] { NO_SCALE, 1 };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class RecentsTaskController extends TaskViewTouchController<RecentsActivi
|
||||
|
||||
@Override
|
||||
protected boolean isRecentsInteractive() {
|
||||
return mActivity.hasWindowFocus() || mActivity.getStateManager().getState().hasLiveTile();
|
||||
return mContainer.hasWindowFocus() || mContainer.getStateManager().getState().hasLiveTile();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -43,13 +43,13 @@ import android.view.MotionEvent;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import com.android.app.animation.Interpolators;
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.quickstep.BaseActivityInterface;
|
||||
import com.android.quickstep.BaseContainerInterface;
|
||||
import com.android.quickstep.GestureState;
|
||||
import com.android.quickstep.InputConsumer;
|
||||
import com.android.quickstep.RecentsAnimationDeviceState;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
import com.android.systemui.shared.system.InputMonitorCompat;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
@@ -78,7 +78,7 @@ public class AssistantInputConsumer extends DelegateInputConsumer {
|
||||
private float mTimeFraction;
|
||||
private long mDragTime;
|
||||
private float mLastProgress;
|
||||
private BaseActivityInterface mActivityInterface;
|
||||
private BaseContainerInterface mContainerInterface;
|
||||
|
||||
private final float mDragDistThreshold;
|
||||
private final float mFlingDistThreshold;
|
||||
@@ -106,7 +106,7 @@ public class AssistantInputConsumer extends DelegateInputConsumer {
|
||||
float slop = ViewConfiguration.get(context).getScaledTouchSlop();
|
||||
|
||||
mSquaredSlop = slop * slop;
|
||||
mActivityInterface = gestureState.getActivityInterface();
|
||||
mContainerInterface = gestureState.getContainerInterface();
|
||||
|
||||
boolean flingDisabled = deviceState.isAssistantGestureIsConstrained()
|
||||
|| deviceState.isInDeferredGestureRegion(startEvent);
|
||||
@@ -237,9 +237,9 @@ public class AssistantInputConsumer extends DelegateInputConsumer {
|
||||
}
|
||||
|
||||
private void startAssistantInternal() {
|
||||
BaseDraggingActivity launcherActivity = mActivityInterface.getCreatedActivity();
|
||||
if (launcherActivity != null) {
|
||||
launcherActivity.getRootView().performHapticFeedback(
|
||||
RecentsViewContainer container = mContainerInterface.getCreatedContainer();
|
||||
if (container != null) {
|
||||
container.getRootView().performHapticFeedback(
|
||||
13, // HapticFeedbackConstants.GESTURE_END
|
||||
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
|
||||
}
|
||||
|
||||
+48
-4
@@ -20,6 +20,7 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_LONG_PRESS_NAVBAR;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_LONG_PRESS_STASHED_TASKBAR;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.LogConfig.NAV_HANDLE_LONG_PRESS;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
@@ -43,14 +44,19 @@ import com.android.systemui.shared.system.InputMonitorCompat;
|
||||
public class NavHandleLongPressInputConsumer extends DelegateInputConsumer {
|
||||
|
||||
private static final String TAG = "NavHandleLongPressIC";
|
||||
private static final boolean DEBUG_NAV_HANDLE = Utilities.isPropertyEnabled(
|
||||
NAV_HANDLE_LONG_PRESS);
|
||||
|
||||
private final NavHandleLongPressHandler mNavHandleLongPressHandler;
|
||||
private final float mNavHandleWidth;
|
||||
private final float mScreenWidth;
|
||||
|
||||
private final Runnable mTriggerLongPress = this::triggerLongPress;
|
||||
private final float mTouchSlopSquared;
|
||||
private final float mTouchSlopSquaredOriginal;
|
||||
private float mTouchSlopSquared;
|
||||
private final float mOuterTouchSlopSquared;
|
||||
private final int mLongPressTimeout;
|
||||
private final int mOuterLongPressTimeout;
|
||||
private final boolean mDeepPressEnabled;
|
||||
private final NavHandle mNavHandle;
|
||||
private final StatsLogManager mStatsLogManager;
|
||||
@@ -65,13 +71,23 @@ public class NavHandleLongPressInputConsumer extends DelegateInputConsumer {
|
||||
super(delegate, inputMonitor);
|
||||
mScreenWidth = DisplayController.INSTANCE.get(context).getInfo().currentSize.x;
|
||||
mDeepPressEnabled = DeviceConfigWrapper.get().getEnableLpnhDeepPress();
|
||||
int twoStageMultiplier = DeviceConfigWrapper.get().getTwoStageMultiplier();
|
||||
AssistStateManager assistStateManager = AssistStateManager.INSTANCE.get(context);
|
||||
if (assistStateManager.getLPNHDurationMillis().isPresent()) {
|
||||
mLongPressTimeout = assistStateManager.getLPNHDurationMillis().get().intValue();
|
||||
} else {
|
||||
mLongPressTimeout = ViewConfiguration.getLongPressTimeout();
|
||||
}
|
||||
mTouchSlopSquared = deviceState.getSquaredTouchSlop();
|
||||
mOuterLongPressTimeout = mLongPressTimeout * twoStageMultiplier;
|
||||
mTouchSlopSquaredOriginal = deviceState.getSquaredTouchSlop();
|
||||
mTouchSlopSquared = mTouchSlopSquaredOriginal;
|
||||
mOuterTouchSlopSquared = mTouchSlopSquared * (twoStageMultiplier * twoStageMultiplier);
|
||||
if (DEBUG_NAV_HANDLE) {
|
||||
Log.d(TAG, "mLongPressTimeout=" + mLongPressTimeout);
|
||||
Log.d(TAG, "mOuterLongPressTimeout=" + mOuterLongPressTimeout);
|
||||
Log.d(TAG, "mTouchSlopSquared=" + mTouchSlopSquared);
|
||||
Log.d(TAG, "mOuterTouchSlopSquared=" + mOuterTouchSlopSquared);
|
||||
}
|
||||
mNavHandle = navHandle;
|
||||
mNavHandleWidth = navHandle.getNavHandleWidth(context);
|
||||
mNavHandleLongPressHandler = NavHandleLongPressHandler.newInstance(context);
|
||||
@@ -109,22 +125,44 @@ public class NavHandleLongPressInputConsumer extends DelegateInputConsumer {
|
||||
mCurrentDownEvent.recycle();
|
||||
}
|
||||
mCurrentDownEvent = MotionEvent.obtain(ev);
|
||||
mTouchSlopSquared = mTouchSlopSquaredOriginal;
|
||||
mDeepPressLogged = false;
|
||||
if (isInNavBarHorizontalArea(ev.getRawX())) {
|
||||
mNavHandleLongPressHandler.onTouchStarted(mNavHandle);
|
||||
MAIN_EXECUTOR.getHandler().postDelayed(mTriggerLongPress, mLongPressTimeout);
|
||||
}
|
||||
if (DEBUG_NAV_HANDLE) {
|
||||
Log.d(TAG, "ACTION_DOWN");
|
||||
}
|
||||
}
|
||||
case MotionEvent.ACTION_MOVE -> {
|
||||
if (!MAIN_EXECUTOR.getHandler().hasCallbacks(mTriggerLongPress)) {
|
||||
break;
|
||||
}
|
||||
|
||||
float touchSlopSquared = mTouchSlopSquared;
|
||||
float dx = ev.getX() - mCurrentDownEvent.getX();
|
||||
float dy = ev.getY() - mCurrentDownEvent.getY();
|
||||
double distanceSquared = (dx * dx) + (dy * dy);
|
||||
if (distanceSquared > touchSlopSquared) {
|
||||
if (DEBUG_NAV_HANDLE) {
|
||||
Log.d(TAG, "ACTION_MOVE distanceSquared=" + distanceSquared);
|
||||
}
|
||||
if (DeviceConfigWrapper.get().getEnableLpnhTwoStages()) {
|
||||
if (mTouchSlopSquared < distanceSquared
|
||||
&& distanceSquared <= mOuterTouchSlopSquared) {
|
||||
MAIN_EXECUTOR.getHandler().removeCallbacks(mTriggerLongPress);
|
||||
int delay = mOuterLongPressTimeout
|
||||
- (int) (ev.getEventTime() - ev.getDownTime());
|
||||
MAIN_EXECUTOR.getHandler().postDelayed(mTriggerLongPress, delay);
|
||||
mTouchSlopSquared = mOuterTouchSlopSquared;
|
||||
if (DEBUG_NAV_HANDLE) {
|
||||
Log.d(TAG, "Touch in middle region!");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (distanceSquared > mTouchSlopSquared) {
|
||||
if (DEBUG_NAV_HANDLE) {
|
||||
Log.d(TAG, "Touch slop out. mTouchSlopSquared=" + mTouchSlopSquared);
|
||||
}
|
||||
cancelLongPress("touch slop passed");
|
||||
}
|
||||
}
|
||||
@@ -153,6 +191,9 @@ public class NavHandleLongPressInputConsumer extends DelegateInputConsumer {
|
||||
}
|
||||
|
||||
private void triggerLongPress() {
|
||||
if (DEBUG_NAV_HANDLE) {
|
||||
Log.d(TAG, "triggerLongPress");
|
||||
}
|
||||
String runningPackage = mTopTaskTracker.getCachedTopTask(
|
||||
/* filterOnlyVisibleRecents */ true).getPackageName();
|
||||
mStatsLogManager.logger().withPackageName(runningPackage).log(
|
||||
@@ -175,6 +216,9 @@ public class NavHandleLongPressInputConsumer extends DelegateInputConsumer {
|
||||
}
|
||||
|
||||
private void cancelLongPress(String reason) {
|
||||
if (DEBUG_NAV_HANDLE) {
|
||||
Log.d(TAG, "cancelLongPress");
|
||||
}
|
||||
MAIN_EXECUTOR.getHandler().removeCallbacks(mTriggerLongPress);
|
||||
mNavHandleLongPressHandler.onTouchFinished(mNavHandle, reason);
|
||||
}
|
||||
|
||||
@@ -49,7 +49,6 @@ import com.android.launcher3.util.Preconditions;
|
||||
import com.android.launcher3.util.TraceHelper;
|
||||
import com.android.quickstep.AbsSwipeUpHandler;
|
||||
import com.android.quickstep.AbsSwipeUpHandler.Factory;
|
||||
import com.android.quickstep.BaseActivityInterface;
|
||||
import com.android.quickstep.GestureState;
|
||||
import com.android.quickstep.InputConsumer;
|
||||
import com.android.quickstep.RecentsAnimationCallbacks;
|
||||
@@ -86,8 +85,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
||||
private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher();
|
||||
private final InputMonitorCompat mInputMonitorCompat;
|
||||
private final InputEventReceiver mInputEventReceiver;
|
||||
private final BaseActivityInterface mActivityInterface;
|
||||
|
||||
private final AbsSwipeUpHandler.Factory mHandlerFactory;
|
||||
|
||||
private final Consumer<OtherActivityInputConsumer> mOnCompleteCallback;
|
||||
@@ -135,7 +132,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
||||
mTaskAnimationManager = taskAnimationManager;
|
||||
mGestureState = gestureState;
|
||||
mHandlerFactory = handlerFactory;
|
||||
mActivityInterface = mGestureState.getActivityInterface();
|
||||
|
||||
mMotionPauseDetector = new MotionPauseDetector(base, false,
|
||||
mNavBarPosition.isLeftEdge() || mNavBarPosition.isRightEdge()
|
||||
|
||||
@@ -28,24 +28,24 @@ import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.statemanager.BaseState;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.launcher3.testing.TestLogging;
|
||||
import com.android.launcher3.testing.shared.TestProtocol;
|
||||
import com.android.launcher3.views.BaseDragLayer;
|
||||
import com.android.quickstep.BaseActivityInterface;
|
||||
import com.android.quickstep.BaseContainerInterface;
|
||||
import com.android.quickstep.GestureState;
|
||||
import com.android.quickstep.InputConsumer;
|
||||
import com.android.quickstep.TaskUtils;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
import com.android.systemui.shared.system.InputMonitorCompat;
|
||||
|
||||
/**
|
||||
* Input consumer for handling touch on the recents/Launcher activity.
|
||||
*/
|
||||
public class OverviewInputConsumer<S extends BaseState<S>, T extends StatefulActivity<S>>
|
||||
public class OverviewInputConsumer<S extends BaseState<S>, T extends RecentsViewContainer>
|
||||
implements InputConsumer {
|
||||
|
||||
private final T mActivity;
|
||||
private final BaseActivityInterface<?, T> mActivityInterface;
|
||||
private final T mContainer;
|
||||
private final BaseContainerInterface<?, T> mContainerInterface;
|
||||
private final BaseDragLayer mTarget;
|
||||
private final InputMonitorCompat mInputMonitor;
|
||||
|
||||
@@ -56,14 +56,14 @@ public class OverviewInputConsumer<S extends BaseState<S>, T extends StatefulAct
|
||||
private boolean mHasSetTouchModeForFirstDPadEvent;
|
||||
private boolean mIsWaitingForAttachToWindow;
|
||||
|
||||
public OverviewInputConsumer(GestureState gestureState, T activity,
|
||||
public OverviewInputConsumer(GestureState gestureState, T container,
|
||||
@Nullable InputMonitorCompat inputMonitor, boolean startingInActivityBounds) {
|
||||
mActivity = activity;
|
||||
mContainer = container;
|
||||
mInputMonitor = inputMonitor;
|
||||
mStartingInActivityBounds = startingInActivityBounds;
|
||||
mActivityInterface = gestureState.getActivityInterface();
|
||||
mContainerInterface = gestureState.getContainerInterface();
|
||||
|
||||
mTarget = activity.getDragLayer();
|
||||
mTarget = container.getDragLayer();
|
||||
mTarget.getLocationOnScreen(mLocationOnScreen);
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ public class OverviewInputConsumer<S extends BaseState<S>, T extends StatefulAct
|
||||
if (!mTargetHandledTouch && handled) {
|
||||
mTargetHandledTouch = true;
|
||||
if (!mStartingInActivityBounds) {
|
||||
mActivityInterface.closeOverlay();
|
||||
mContainerInterface.closeOverlay();
|
||||
TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
|
||||
}
|
||||
if (mInputMonitor != null) {
|
||||
@@ -100,13 +100,13 @@ public class OverviewInputConsumer<S extends BaseState<S>, T extends StatefulAct
|
||||
}
|
||||
}
|
||||
if (mHasSetTouchModeForFirstDPadEvent) {
|
||||
mActivity.getRootView().clearFocus();
|
||||
mContainer.getRootView().clearFocus();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHoverEvent(MotionEvent ev) {
|
||||
mActivity.dispatchGenericMotionEvent(ev);
|
||||
mContainer.dispatchGenericMotionEvent(ev);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -115,7 +115,8 @@ public class OverviewInputConsumer<S extends BaseState<S>, T extends StatefulAct
|
||||
case KeyEvent.KEYCODE_VOLUME_DOWN:
|
||||
case KeyEvent.KEYCODE_VOLUME_UP:
|
||||
case KeyEvent.KEYCODE_VOLUME_MUTE:
|
||||
MediaSessionManager mgr = mActivity.getSystemService(MediaSessionManager.class);
|
||||
MediaSessionManager mgr = mContainer.asContext()
|
||||
.getSystemService(MediaSessionManager.class);
|
||||
mgr.dispatchVolumeKeyEventAsSystemService(ev,
|
||||
AudioManager.USE_DEFAULT_STREAM_TYPE);
|
||||
break;
|
||||
@@ -124,7 +125,7 @@ public class OverviewInputConsumer<S extends BaseState<S>, T extends StatefulAct
|
||||
if (mHasSetTouchModeForFirstDPadEvent) {
|
||||
break;
|
||||
}
|
||||
View viewRoot = mActivity.getRootView();
|
||||
View viewRoot = mContainer.getRootView();
|
||||
if (viewRoot.isAttachedToWindow()) {
|
||||
setTouchModeChanged(viewRoot);
|
||||
break;
|
||||
@@ -150,7 +151,7 @@ public class OverviewInputConsumer<S extends BaseState<S>, T extends StatefulAct
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mActivity.dispatchKeyEvent(ev);
|
||||
mContainer.dispatchKeyEvent(ev);
|
||||
}
|
||||
|
||||
private void setTouchModeChanged(@NonNull View viewRoot) {
|
||||
|
||||
@@ -19,12 +19,12 @@ import android.content.Context;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.quickstep.GestureState;
|
||||
import com.android.quickstep.InputConsumer;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.util.MotionPauseDetector;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
|
||||
/**
|
||||
* An input consumer that detects swipe up and hold to exit screen pinning mode.
|
||||
@@ -44,10 +44,10 @@ public class ScreenPinnedInputConsumer implements InputConsumer {
|
||||
mMotionPauseDetector = new MotionPauseDetector(context, true /* makePauseHarderToTrigger*/);
|
||||
mMotionPauseDetector.setOnMotionPauseListener(() -> {
|
||||
SystemUiProxy.INSTANCE.get(context).stopScreenPinning();
|
||||
BaseDraggingActivity launcherActivity = gestureState.getActivityInterface()
|
||||
.getCreatedActivity();
|
||||
if (launcherActivity != null) {
|
||||
launcherActivity.getRootView().performHapticFeedback(
|
||||
RecentsViewContainer container = gestureState.getContainerInterface()
|
||||
.getCreatedContainer();
|
||||
if (container != null) {
|
||||
container.getRootView().performHapticFeedback(
|
||||
HapticFeedbackConstants.LONG_PRESS,
|
||||
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
|
||||
}
|
||||
|
||||
@@ -39,12 +39,12 @@ import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.touch.AllAppsSwipeController;
|
||||
import com.android.quickstep.DeviceConfigWrapper;
|
||||
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
|
||||
/**
|
||||
* Controls an animation that can go beyond progress = 1, at which point resistance should be
|
||||
@@ -158,11 +158,12 @@ public class AnimatorControllerWithResistance {
|
||||
PendingAnimation resistAnim = createRecentsResistanceAnim(params);
|
||||
|
||||
// Apply All Apps animation during the resistance animation.
|
||||
if (recentsOrientedState.getActivityInterface().allowAllAppsFromOverview()) {
|
||||
StatefulActivity activity =
|
||||
recentsOrientedState.getActivityInterface().getCreatedActivity();
|
||||
if (activity != null) {
|
||||
StateManager<LauncherState> stateManager = activity.getStateManager();
|
||||
if (recentsOrientedState.getContainerInterface().allowAllAppsFromOverview()) {
|
||||
RecentsViewContainer container =
|
||||
recentsOrientedState.getContainerInterface().getCreatedContainer();
|
||||
if (container != null) {
|
||||
RecentsView recentsView = container.getOverviewPanel();
|
||||
StateManager<LauncherState> stateManager = recentsView.getStateManager();
|
||||
if (stateManager.isInStableState(LauncherState.BACKGROUND_APP)
|
||||
&& stateManager.isInTransition()) {
|
||||
|
||||
@@ -185,7 +186,7 @@ public class AnimatorControllerWithResistance {
|
||||
private static float getAllAppsThreshold(Context context,
|
||||
RecentsOrientedState recentsOrientedState, DeviceProfile dp) {
|
||||
int transitionDragLength =
|
||||
recentsOrientedState.getActivityInterface().getSwipeUpDestinationAndLength(
|
||||
recentsOrientedState.getContainerInterface().getSwipeUpDestinationAndLength(
|
||||
dp, context, TEMP_RECT,
|
||||
recentsOrientedState.getOrientationHandler());
|
||||
float dragLengthFactor = (float) dp.heightPx / transitionDragLength;
|
||||
@@ -203,7 +204,7 @@ public class AnimatorControllerWithResistance {
|
||||
Rect startRect = new Rect();
|
||||
RecentsPagedOrientationHandler orientationHandler = params.recentsOrientedState
|
||||
.getOrientationHandler();
|
||||
params.recentsOrientedState.getActivityInterface()
|
||||
params.recentsOrientedState.getContainerInterface()
|
||||
.calculateTaskSize(params.context, params.dp, startRect, orientationHandler);
|
||||
long distanceToCover = startRect.bottom;
|
||||
PendingAnimation resistAnim = params.resistAnim != null
|
||||
@@ -303,14 +304,14 @@ public class AnimatorControllerWithResistance {
|
||||
this.translationProperty = translationProperty;
|
||||
if (dp.isTablet) {
|
||||
resistanceParams =
|
||||
recentsOrientedState.getActivityInterface().allowAllAppsFromOverview()
|
||||
recentsOrientedState.getContainerInterface().allowAllAppsFromOverview()
|
||||
? RecentsResistanceParams.FROM_APP_TO_ALL_APPS_TABLET
|
||||
: enableGridOnlyOverview()
|
||||
? RecentsResistanceParams.FROM_APP_TABLET_GRID_ONLY
|
||||
: RecentsResistanceParams.FROM_APP_TABLET;
|
||||
} else {
|
||||
resistanceParams =
|
||||
recentsOrientedState.getActivityInterface().allowAllAppsFromOverview()
|
||||
recentsOrientedState.getContainerInterface().allowAllAppsFromOverview()
|
||||
? RecentsResistanceParams.FROM_APP_TO_ALL_APPS
|
||||
: RecentsResistanceParams.FROM_APP;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.internal.jank.Cuj;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
|
||||
@@ -56,8 +55,10 @@ import com.android.launcher3.model.data.AppPairInfo;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.taskbar.TaskbarActivityContext;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
|
||||
import com.android.launcher3.views.ActivityContext;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.TopTaskTracker;
|
||||
import com.android.quickstep.views.GroupedTaskView;
|
||||
@@ -159,7 +160,7 @@ public class AppPairsController {
|
||||
});
|
||||
MAIN_EXECUTOR.execute(() -> {
|
||||
LauncherAccessibilityDelegate delegate =
|
||||
Launcher.getLauncher(mContext).getAccessibilityDelegate();
|
||||
QuickstepLauncher.getLauncher(mContext).getAccessibilityDelegate();
|
||||
if (delegate != null) {
|
||||
delegate.addToWorkspace(newAppPair, true, (success) -> {
|
||||
if (success) {
|
||||
@@ -238,7 +239,8 @@ public class AppPairsController {
|
||||
return null;
|
||||
}
|
||||
|
||||
AllAppsStore appsStore = Launcher.getLauncher(mContext).getAppsView().getAppsStore();
|
||||
AllAppsStore appsStore = ActivityContext.lookupContext(mContext)
|
||||
.getAppsView().getAppsStore();
|
||||
|
||||
// Lookup by ComponentKey
|
||||
AppInfo appInfo = appsStore.getApp(key);
|
||||
|
||||
@@ -52,16 +52,38 @@ public class AssistStateManager implements ResourceBasedOverride {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/** Get the Launcher overridden long press duration to trigger Assistant. */
|
||||
/** Get the Launcher overridden long press nav handle duration to trigger Assistant. */
|
||||
public Optional<Long> getLPNHDurationMillis() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/** Get the Launcher overridden long press touch slop multiplier to trigger Assistant. */
|
||||
public Optional<Long> getLPNHCustomSlopMultiplier() {
|
||||
/**
|
||||
* Get the Launcher overridden long press nav handle touch slop multiplier to trigger Assistant.
|
||||
*/
|
||||
public Optional<Float> getLPNHCustomSlopMultiplier() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/** Get the Launcher overridden long press home duration to trigger Assistant. */
|
||||
public Optional<Long> getLPHDurationMillis() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/** Get the Launcher overridden long press home touch slop multiplier to trigger Assistant. */
|
||||
public Optional<Float> getLPHCustomSlopMultiplier() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/** Get the long press duration data source. */
|
||||
public int getDurationDataSource() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Get the long press touch slop multiplier data source. */
|
||||
public int getSlopDataSource() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Return {@code true} if the Settings toggle is enabled. */
|
||||
public boolean isSettingsAllEntrypointsEnabled() {
|
||||
return false;
|
||||
|
||||
@@ -17,11 +17,11 @@ package com.android.quickstep.util;
|
||||
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.quickstep.BaseActivityInterface;
|
||||
import com.android.quickstep.BaseContainerInterface;
|
||||
import com.android.quickstep.GestureState;
|
||||
import com.android.quickstep.InputConsumer;
|
||||
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -31,13 +31,13 @@ import java.util.function.Supplier;
|
||||
*/
|
||||
public class InputProxyHandlerFactory implements Supplier<InputConsumer> {
|
||||
|
||||
private final BaseActivityInterface mActivityInterface;
|
||||
private final BaseContainerInterface mContainerInterface;
|
||||
private final GestureState mGestureState;
|
||||
|
||||
@UiThread
|
||||
public InputProxyHandlerFactory(BaseActivityInterface activityInterface,
|
||||
public InputProxyHandlerFactory(BaseContainerInterface activityInterface,
|
||||
GestureState gestureState) {
|
||||
mActivityInterface = activityInterface;
|
||||
mContainerInterface = activityInterface;
|
||||
mGestureState = gestureState;
|
||||
}
|
||||
|
||||
@@ -46,8 +46,8 @@ public class InputProxyHandlerFactory implements Supplier<InputConsumer> {
|
||||
*/
|
||||
@Override
|
||||
public InputConsumer get() {
|
||||
StatefulActivity activity = mActivityInterface.getCreatedActivity();
|
||||
return activity == null ? InputConsumer.NO_OP
|
||||
: new OverviewInputConsumer(mGestureState, activity, null, true);
|
||||
RecentsViewContainer container = mContainerInterface.getCreatedContainer();
|
||||
return container == null ? InputConsumer.NO_OP
|
||||
: new OverviewInputConsumer(mGestureState, container, null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +30,9 @@ import androidx.core.view.OneShotPreDrawListener;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
|
||||
import com.android.launcher3.Hotseat;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.Workspace;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.launcher3.util.HorizontalInsettableView;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.util.unfold.LauncherJankMonitorTransitionProgressListener;
|
||||
@@ -56,7 +56,7 @@ public class LauncherUnfoldAnimationController implements OnDeviceProfileChangeL
|
||||
private static final FloatProperty<Hotseat> HOTSEAT_SCALE_PROPERTY =
|
||||
HOTSEAT_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_UNFOLD_ANIMATION);
|
||||
|
||||
private final Launcher mLauncher;
|
||||
private final QuickstepLauncher mLauncher;
|
||||
private final ScopedUnfoldTransitionProgressProvider mProgressProvider;
|
||||
private final NaturalRotationUnfoldProgressProvider mNaturalOrientationProgressProvider;
|
||||
private final UnfoldMoveFromCenterHotseatAnimator mUnfoldMoveFromCenterHotseatAnimator;
|
||||
@@ -73,7 +73,7 @@ public class LauncherUnfoldAnimationController implements OnDeviceProfileChangeL
|
||||
private HorizontalInsettableView mQsbInsettable;
|
||||
|
||||
public LauncherUnfoldAnimationController(
|
||||
Launcher launcher,
|
||||
QuickstepLauncher launcher,
|
||||
WindowManager windowManager,
|
||||
UnfoldTransitionProgressProvider unfoldTransitionProgressProvider,
|
||||
RotationChangeProvider rotationChangeProvider) {
|
||||
|
||||
@@ -19,39 +19,40 @@ import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_O
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.dynamicanimation.animation.DynamicAnimation;
|
||||
|
||||
import com.android.launcher3.anim.SpringAnimationBuilder;
|
||||
import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
|
||||
public class RecentsAtomicAnimationFactory<ACTIVITY_TYPE extends StatefulActivity, STATE_TYPE>
|
||||
extends AtomicAnimationFactory<STATE_TYPE> {
|
||||
public class RecentsAtomicAnimationFactory<CONTAINER extends Context & RecentsViewContainer,
|
||||
STATE_TYPE> extends AtomicAnimationFactory<STATE_TYPE> {
|
||||
|
||||
public static final int INDEX_RECENTS_FADE_ANIM = AtomicAnimationFactory.NEXT_INDEX + 0;
|
||||
public static final int INDEX_RECENTS_TRANSLATE_X_ANIM = AtomicAnimationFactory.NEXT_INDEX + 1;
|
||||
|
||||
private static final int MY_ANIM_COUNT = 2;
|
||||
|
||||
protected final ACTIVITY_TYPE mActivity;
|
||||
protected final CONTAINER mContainer;
|
||||
|
||||
public RecentsAtomicAnimationFactory(ACTIVITY_TYPE activity) {
|
||||
public RecentsAtomicAnimationFactory(CONTAINER container) {
|
||||
super(MY_ANIM_COUNT);
|
||||
mActivity = activity;
|
||||
mContainer = container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Animator createStateElementAnimation(int index, float... values) {
|
||||
switch (index) {
|
||||
case INDEX_RECENTS_FADE_ANIM:
|
||||
ObjectAnimator alpha = ObjectAnimator.ofFloat(mActivity.getOverviewPanel(),
|
||||
ObjectAnimator alpha = ObjectAnimator.ofFloat(mContainer.getOverviewPanel(),
|
||||
RecentsView.CONTENT_ALPHA, values);
|
||||
return alpha;
|
||||
case INDEX_RECENTS_TRANSLATE_X_ANIM: {
|
||||
RecentsView rv = mActivity.getOverviewPanel();
|
||||
return new SpringAnimationBuilder(mActivity)
|
||||
RecentsView rv = mContainer.getOverviewPanel();
|
||||
return new SpringAnimationBuilder(mContainer)
|
||||
.setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE)
|
||||
.setDampingRatio(0.8f)
|
||||
.setStiffness(250)
|
||||
|
||||
@@ -50,7 +50,7 @@ import com.android.launcher3.testing.shared.TestProtocol;
|
||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
import com.android.launcher3.util.SettingsCache;
|
||||
import com.android.quickstep.BaseActivityInterface;
|
||||
import com.android.quickstep.BaseContainerInterface;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.TaskAnimationManager;
|
||||
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
|
||||
@@ -118,7 +118,7 @@ public class RecentsOrientedState implements
|
||||
| FLAG_SWIPE_UP_NOT_RUNNING;
|
||||
|
||||
private final Context mContext;
|
||||
private final BaseActivityInterface mActivityInterface;
|
||||
private final BaseContainerInterface mContainerInterface;
|
||||
private final OrientationEventListener mOrientationListener;
|
||||
private final SettingsCache mSettingsCache;
|
||||
private final SettingsCache.OnChangeListener mRotationChangeListener =
|
||||
@@ -138,10 +138,10 @@ public class RecentsOrientedState implements
|
||||
* is enabled
|
||||
* @see #setRotationWatcherEnabled(boolean)
|
||||
*/
|
||||
public RecentsOrientedState(Context context, BaseActivityInterface activityInterface,
|
||||
public RecentsOrientedState(Context context, BaseContainerInterface containerInterface,
|
||||
IntConsumer rotationChangeListener) {
|
||||
mContext = context;
|
||||
mActivityInterface = activityInterface;
|
||||
mContainerInterface = containerInterface;
|
||||
mOrientationListener = new OrientationEventListener(context) {
|
||||
@Override
|
||||
public void onOrientationChanged(int degrees) {
|
||||
@@ -153,7 +153,7 @@ public class RecentsOrientedState implements
|
||||
}
|
||||
};
|
||||
|
||||
mFlags = mActivityInterface.rotationSupportedByActivity
|
||||
mFlags = mContainerInterface.rotationSupportedByActivity
|
||||
? FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY : 0;
|
||||
|
||||
mFlags |= FLAG_SWIPE_UP_NOT_RUNNING;
|
||||
@@ -161,8 +161,8 @@ public class RecentsOrientedState implements
|
||||
initFlags();
|
||||
}
|
||||
|
||||
public BaseActivityInterface getActivityInterface() {
|
||||
return mActivityInterface;
|
||||
public BaseContainerInterface getContainerInterface() {
|
||||
return mContainerInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,7 +20,6 @@ import android.view.View
|
||||
import com.android.app.animation.Interpolators
|
||||
import com.android.app.animation.Interpolators.EMPHASIZED
|
||||
import com.android.app.animation.Interpolators.LINEAR
|
||||
import com.android.launcher3.Launcher
|
||||
import com.android.launcher3.LauncherAnimUtils.HOTSEAT_SCALE_PROPERTY_FACTORY
|
||||
import com.android.launcher3.LauncherAnimUtils.SCALE_INDEX_WORKSPACE_STATE
|
||||
import com.android.launcher3.LauncherAnimUtils.WORKSPACE_SCALE_PROPERTY_FACTORY
|
||||
@@ -39,7 +38,7 @@ import com.android.quickstep.views.RecentsView
|
||||
* Creates an animation where the workspace and hotseat fade in while revealing from the center of
|
||||
* the screen outwards radially. This is used in conjunction with the swipe up to home animation.
|
||||
*/
|
||||
class ScalingWorkspaceRevealAnim(launcher: Launcher) {
|
||||
class ScalingWorkspaceRevealAnim(launcher: QuickstepLauncher) {
|
||||
companion object {
|
||||
private const val FADE_DURATION_MS = 200L
|
||||
private const val SCALE_DURATION_MS = 1000L
|
||||
|
||||
@@ -41,7 +41,6 @@ import androidx.annotation.VisibleForTesting
|
||||
import com.android.app.animation.Interpolators
|
||||
import com.android.launcher3.DeviceProfile
|
||||
import com.android.launcher3.Flags.enableOverviewIconMenu
|
||||
import com.android.launcher3.Launcher
|
||||
import com.android.launcher3.QuickstepTransitionManager
|
||||
import com.android.launcher3.Utilities
|
||||
import com.android.launcher3.anim.PendingAnimation
|
||||
@@ -50,8 +49,8 @@ import com.android.launcher3.config.FeatureFlags
|
||||
import com.android.launcher3.logging.StatsLogManager.EventEnum
|
||||
import com.android.launcher3.statehandlers.DepthController
|
||||
import com.android.launcher3.statemanager.StateManager
|
||||
import com.android.launcher3.statemanager.StatefulActivity
|
||||
import com.android.launcher3.taskbar.TaskbarActivityContext
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher
|
||||
import com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource
|
||||
import com.android.launcher3.views.BaseDragLayer
|
||||
@@ -61,6 +60,7 @@ import com.android.quickstep.views.FloatingTaskView
|
||||
import com.android.quickstep.views.GroupedTaskView
|
||||
import com.android.quickstep.views.IconAppChipView
|
||||
import com.android.quickstep.views.RecentsView
|
||||
import com.android.quickstep.views.RecentsViewContainer
|
||||
import com.android.quickstep.views.SplitInstructionsView
|
||||
import com.android.quickstep.views.TaskThumbnailView
|
||||
import com.android.quickstep.views.TaskView
|
||||
@@ -269,12 +269,12 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
}
|
||||
|
||||
/** Does not play any animation if user is not currently in split selection state. */
|
||||
fun playPlaceholderDismissAnim(launcher: StatefulActivity<*>, splitDismissEvent: EventEnum) {
|
||||
fun playPlaceholderDismissAnim(container: RecentsViewContainer, splitDismissEvent: EventEnum) {
|
||||
if (!splitSelectStateController.isSplitSelectActive) {
|
||||
return
|
||||
}
|
||||
|
||||
val anim = createPlaceholderDismissAnim(launcher, splitDismissEvent, null /*duration*/)
|
||||
val anim = createPlaceholderDismissAnim(container, splitDismissEvent, null /*duration*/)
|
||||
anim.start()
|
||||
}
|
||||
|
||||
@@ -283,18 +283,18 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
* for why split is being dismissed
|
||||
*/
|
||||
fun createPlaceholderDismissAnim(
|
||||
launcher: StatefulActivity<*>,
|
||||
container: RecentsViewContainer,
|
||||
splitDismissEvent: EventEnum,
|
||||
duration: Long?
|
||||
): AnimatorSet {
|
||||
val animatorSet = AnimatorSet()
|
||||
duration?.let { animatorSet.duration = it }
|
||||
val recentsView: RecentsView<*, *> = launcher.getOverviewPanel()
|
||||
val recentsView: RecentsView<*, *> = container.getOverviewPanel()
|
||||
val floatingTask: FloatingTaskView =
|
||||
splitSelectStateController.firstFloatingTaskView ?: return animatorSet
|
||||
|
||||
// We are in split selection state currently, transitioning to another state
|
||||
val dragLayer: BaseDragLayer<*> = launcher.dragLayer
|
||||
val dragLayer: BaseDragLayer<*> = container.dragLayer
|
||||
val onScreenRectF = RectF()
|
||||
Utilities.getBoundsForViewInDragLayer(
|
||||
dragLayer,
|
||||
@@ -320,7 +320,7 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
floatingTask,
|
||||
onScreenRectF,
|
||||
floatingTask.stagePosition,
|
||||
launcher.deviceProfile
|
||||
container.deviceProfile
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -329,7 +329,7 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
splitSelectStateController.resetState()
|
||||
safeRemoveViewFromDragLayer(
|
||||
launcher,
|
||||
container,
|
||||
splitSelectStateController.splitInstructionsView
|
||||
)
|
||||
}
|
||||
@@ -343,11 +343,11 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
* Returns a [PendingAnimation] to animate in the chip to instruct a user to select a second app
|
||||
* for splitscreen
|
||||
*/
|
||||
fun getShowSplitInstructionsAnim(launcher: StatefulActivity<*>): PendingAnimation {
|
||||
safeRemoveViewFromDragLayer(launcher, splitSelectStateController.splitInstructionsView)
|
||||
val splitInstructionsView = SplitInstructionsView.getSplitInstructionsView(launcher)
|
||||
fun getShowSplitInstructionsAnim(container: RecentsViewContainer): PendingAnimation {
|
||||
safeRemoveViewFromDragLayer(container, splitSelectStateController.splitInstructionsView)
|
||||
val splitInstructionsView = SplitInstructionsView.getSplitInstructionsView(container)
|
||||
splitSelectStateController.splitInstructionsView = splitInstructionsView
|
||||
val timings = AnimUtils.getDeviceOverviewToSplitTimings(launcher.deviceProfile.isTablet)
|
||||
val timings = AnimUtils.getDeviceOverviewToSplitTimings(container.deviceProfile.isTablet)
|
||||
val anim = PendingAnimation(100 /*duration */)
|
||||
splitInstructionsView.alpha = 0f
|
||||
anim.setViewAlpha(
|
||||
@@ -374,8 +374,8 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
}
|
||||
|
||||
/** Removes the split instructions view from [launcher] drag layer. */
|
||||
fun removeSplitInstructionsView(launcher: StatefulActivity<*>) {
|
||||
safeRemoveViewFromDragLayer(launcher, splitSelectStateController.splitInstructionsView)
|
||||
fun removeSplitInstructionsView(container: RecentsViewContainer) {
|
||||
safeRemoveViewFromDragLayer(container, splitSelectStateController.splitInstructionsView)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -384,22 +384,23 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
* TODO(b/276361926): Remove the [resetCallback] option once contextual launches
|
||||
*/
|
||||
fun playAnimPlaceholderToFullscreen(
|
||||
launcher: StatefulActivity<*>,
|
||||
container: RecentsViewContainer,
|
||||
view: View,
|
||||
resetCallback: Optional<Runnable>
|
||||
) {
|
||||
val stagedTaskView = view as FloatingTaskView
|
||||
|
||||
val isTablet: Boolean = launcher.deviceProfile.isTablet
|
||||
val isTablet: Boolean = container.deviceProfile.isTablet
|
||||
val duration =
|
||||
if (isTablet) SplitAnimationTimings.TABLET_CONFIRM_DURATION
|
||||
else SplitAnimationTimings.PHONE_CONFIRM_DURATION
|
||||
|
||||
val pendingAnimation = PendingAnimation(duration.toLong())
|
||||
val firstTaskStartingBounds = Rect()
|
||||
val firstTaskEndingBounds = Rect()
|
||||
|
||||
stagedTaskView.getBoundsOnScreen(firstTaskStartingBounds)
|
||||
launcher.dragLayer.getBoundsOnScreen(firstTaskEndingBounds)
|
||||
container.dragLayer.getBoundsOnScreen(firstTaskEndingBounds)
|
||||
splitSelectStateController.setLaunchingFirstAppFullscreen()
|
||||
|
||||
stagedTaskView.addConfirmAnimation(
|
||||
@@ -589,7 +590,7 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
}
|
||||
|
||||
// Else we are in Launcher and can launch with the full icon stretch-and-split animation.
|
||||
val launcher = Launcher.getLauncher(launchingIconView.context)
|
||||
val launcher = QuickstepLauncher.getLauncher(launchingIconView.context)
|
||||
val dp = launcher.deviceProfile
|
||||
|
||||
// Create an AnimatorSet that will run both shell and launcher transitions together
|
||||
@@ -923,9 +924,9 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC
|
||||
animator.start()
|
||||
}
|
||||
|
||||
private fun safeRemoveViewFromDragLayer(launcher: StatefulActivity<*>, view: View?) {
|
||||
private fun safeRemoveViewFromDragLayer(container: RecentsViewContainer, view: View?) {
|
||||
if (view != null) {
|
||||
launcher.dragLayer.removeView(view)
|
||||
container.dragLayer.removeView(view)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,6 @@ import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.internal.logging.InstanceId;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.apppairs.AppPairIcon;
|
||||
@@ -82,9 +81,9 @@ import com.android.launcher3.logging.StatsLogManager;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.statehandlers.DepthController;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.launcher3.testing.TestLogging;
|
||||
import com.android.launcher3.testing.shared.TestProtocol;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.launcher3.util.BackPressHandler;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
|
||||
@@ -100,6 +99,7 @@ import com.android.quickstep.TaskAnimationManager;
|
||||
import com.android.quickstep.views.FloatingTaskView;
|
||||
import com.android.quickstep.views.GroupedTaskView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
import com.android.quickstep.views.SplitInstructionsView;
|
||||
import com.android.systemui.animation.RemoteAnimationRunnerCompat;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
@@ -121,7 +121,7 @@ import java.util.function.Consumer;
|
||||
public class SplitSelectStateController {
|
||||
private static final String TAG = "SplitSelectStateCtor";
|
||||
|
||||
private StatefulActivity mContext;
|
||||
private RecentsViewContainer mContainer;
|
||||
private final Handler mHandler;
|
||||
private final RecentsModel mRecentTasksModel;
|
||||
@Nullable
|
||||
@@ -179,7 +179,7 @@ public class SplitSelectStateController {
|
||||
public void onBackInvoked() {
|
||||
// When exiting from split selection, leave current context to go to
|
||||
// homescreen as well
|
||||
getSplitAnimationController().playPlaceholderDismissAnim(mContext,
|
||||
getSplitAnimationController().playPlaceholderDismissAnim(mContainer,
|
||||
LAUNCHER_SPLIT_SELECTION_EXIT_HOME);
|
||||
if (mActivityBackCallback != null) {
|
||||
mActivityBackCallback.run();
|
||||
@@ -187,11 +187,11 @@ public class SplitSelectStateController {
|
||||
}
|
||||
};
|
||||
|
||||
public SplitSelectStateController(StatefulActivity context, Handler handler,
|
||||
public SplitSelectStateController(RecentsViewContainer container, Handler handler,
|
||||
StateManager stateManager, DepthController depthController,
|
||||
StatsLogManager statsLogManager, SystemUiProxy systemUiProxy, RecentsModel recentsModel,
|
||||
Runnable activityBackCallback) {
|
||||
mContext = context;
|
||||
mContainer = container;
|
||||
mHandler = handler;
|
||||
mStatsLogManager = statsLogManager;
|
||||
mSystemUiProxy = systemUiProxy;
|
||||
@@ -200,12 +200,12 @@ public class SplitSelectStateController {
|
||||
mRecentTasksModel = recentsModel;
|
||||
mActivityBackCallback = activityBackCallback;
|
||||
mSplitAnimationController = new SplitAnimationController(this);
|
||||
mAppPairsController = new AppPairsController(context, this, statsLogManager);
|
||||
mSplitSelectDataHolder = new SplitSelectDataHolder(mContext);
|
||||
mAppPairsController = new AppPairsController(mContainer.asContext(), this, statsLogManager);
|
||||
mSplitSelectDataHolder = new SplitSelectDataHolder(mContainer.asContext());
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
mContext = null;
|
||||
mContainer = null;
|
||||
mActivityBackCallback = null;
|
||||
mAppPairsController.onDestroy();
|
||||
mSplitSelectDataHolder.onDestroy();
|
||||
@@ -646,7 +646,7 @@ public class SplitSelectStateController {
|
||||
}
|
||||
}
|
||||
|
||||
public void initSplitFromDesktopController(Launcher launcher) {
|
||||
public void initSplitFromDesktopController(QuickstepLauncher launcher) {
|
||||
initSplitFromDesktopController(new SplitFromDesktopController(launcher));
|
||||
}
|
||||
|
||||
@@ -955,7 +955,7 @@ public class SplitSelectStateController {
|
||||
public class SplitFromDesktopController {
|
||||
private static final String TAG = "SplitFromDesktopController";
|
||||
|
||||
private final Launcher mLauncher;
|
||||
private final QuickstepLauncher mLauncher;
|
||||
private final OverviewComponentObserver mOverviewComponentObserver;
|
||||
private final int mSplitPlaceholderSize;
|
||||
private final int mSplitPlaceholderInset;
|
||||
@@ -963,7 +963,7 @@ public class SplitSelectStateController {
|
||||
private ISplitSelectListener mSplitSelectListener;
|
||||
private Drawable mAppIcon;
|
||||
|
||||
public SplitFromDesktopController(Launcher launcher) {
|
||||
public SplitFromDesktopController(QuickstepLauncher launcher) {
|
||||
mLauncher = launcher;
|
||||
RecentsAnimationDeviceState deviceState = new RecentsAnimationDeviceState(
|
||||
launcher.getApplicationContext());
|
||||
|
||||
@@ -35,7 +35,6 @@ import android.view.View;
|
||||
|
||||
import com.android.internal.jank.Cuj;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
@@ -46,6 +45,7 @@ import com.android.launcher3.model.data.AppPairInfo;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.PackageItemInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.quickstep.views.FloatingTaskView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
|
||||
@@ -53,13 +53,14 @@ import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
|
||||
/** Handles when the stage split lands on the home screen. */
|
||||
public class SplitToWorkspaceController {
|
||||
|
||||
private final Launcher mLauncher;
|
||||
private final QuickstepLauncher mLauncher;
|
||||
private final SplitSelectStateController mController;
|
||||
|
||||
private final int mHalfDividerSize;
|
||||
private final IconCache mIconCache;
|
||||
|
||||
public SplitToWorkspaceController(Launcher launcher, SplitSelectStateController controller) {
|
||||
public SplitToWorkspaceController(QuickstepLauncher launcher,
|
||||
SplitSelectStateController controller) {
|
||||
mLauncher = launcher;
|
||||
mController = controller;
|
||||
mIconCache = LauncherAppState.getInstanceNoCreate().getIconCache();
|
||||
|
||||
@@ -38,7 +38,6 @@ import androidx.annotation.Nullable;
|
||||
import com.android.launcher3.CellLayout;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Hotseat;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.QuickstepTransitionManager;
|
||||
import com.android.launcher3.R;
|
||||
@@ -75,13 +74,13 @@ public class StaggeredWorkspaceAnim {
|
||||
private final AnimatorSet mAnimators = new AnimatorSet();
|
||||
private final @Nullable View mIgnoredView;
|
||||
|
||||
public StaggeredWorkspaceAnim(Launcher launcher, float velocity, boolean animateOverviewScrim,
|
||||
@Nullable View ignoredView) {
|
||||
public StaggeredWorkspaceAnim(QuickstepLauncher launcher, float velocity,
|
||||
boolean animateOverviewScrim, @Nullable View ignoredView) {
|
||||
this(launcher, velocity, animateOverviewScrim, ignoredView, true);
|
||||
}
|
||||
|
||||
public StaggeredWorkspaceAnim(Launcher launcher, float velocity, boolean animateOverviewScrim,
|
||||
@Nullable View ignoredView, boolean staggerWorkspace) {
|
||||
public StaggeredWorkspaceAnim(QuickstepLauncher launcher, float velocity,
|
||||
boolean animateOverviewScrim, @Nullable View ignoredView, boolean staggerWorkspace) {
|
||||
prepareToAnimate(launcher, animateOverviewScrim);
|
||||
|
||||
mIgnoredView = ignoredView;
|
||||
@@ -124,7 +123,8 @@ public class StaggeredWorkspaceAnim {
|
||||
for (int i = hotseatIcons.getChildCount() - 1; i >= 0; i--) {
|
||||
View child = hotseatIcons.getChildAt(i);
|
||||
CellLayoutLayoutParams lp = ((CellLayoutLayoutParams) child.getLayoutParams());
|
||||
addStaggeredAnimationForView(child, lp.getCellY() + 1, totalRows, duration);
|
||||
addStaggeredAnimationForView(child, lp.getCellY() + 1,
|
||||
totalRows, duration);
|
||||
}
|
||||
} else {
|
||||
final int hotseatRow, qsbRow;
|
||||
@@ -194,7 +194,8 @@ public class StaggeredWorkspaceAnim {
|
||||
for (int i = itemsContainer.getChildCount() - 1; i >= 0; i--) {
|
||||
View child = itemsContainer.getChildAt(i);
|
||||
CellLayoutLayoutParams lp = ((CellLayoutLayoutParams) child.getLayoutParams());
|
||||
addStaggeredAnimationForView(child, lp.getCellY() + lp.cellVSpan, totalRows, duration);
|
||||
addStaggeredAnimationForView(child, lp.getCellY() + lp.cellVSpan,
|
||||
totalRows, duration);
|
||||
}
|
||||
|
||||
mAnimators.addListener(new AnimatorListenerAdapter() {
|
||||
@@ -209,7 +210,7 @@ public class StaggeredWorkspaceAnim {
|
||||
/**
|
||||
* Setup workspace with 0 duration to prepare for our staggered animation.
|
||||
*/
|
||||
private void prepareToAnimate(Launcher launcher, boolean animateOverviewScrim) {
|
||||
private void prepareToAnimate(QuickstepLauncher launcher, boolean animateOverviewScrim) {
|
||||
StateAnimationConfig config = new StateAnimationConfig();
|
||||
config.animFlags = SKIP_OVERVIEW | SKIP_DEPTH_CONTROLLER | SKIP_SCRIM;
|
||||
config.duration = 0;
|
||||
@@ -294,12 +295,10 @@ public class StaggeredWorkspaceAnim {
|
||||
mAnimators.play(alpha);
|
||||
}
|
||||
|
||||
private void addDepthAnimationForState(Launcher launcher, LauncherState state, long duration) {
|
||||
if (!(launcher instanceof QuickstepLauncher)) {
|
||||
return;
|
||||
}
|
||||
private void addDepthAnimationForState(QuickstepLauncher launcher, LauncherState state,
|
||||
long duration) {
|
||||
PendingAnimation builder = new PendingAnimation(duration);
|
||||
DepthController depthController = ((QuickstepLauncher) launcher).getDepthController();
|
||||
DepthController depthController = launcher.getDepthController();
|
||||
depthController.setStateWithAnimation(state, new StateAnimationConfig(), builder);
|
||||
mAnimators.play(builder.buildAnim());
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ import static com.android.launcher3.BaseActivity.EVENT_STOPPED;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.launcher3.BaseActivity;
|
||||
import com.android.quickstep.RecentsModel;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
|
||||
/**
|
||||
* This class tracks the failure of a task launch through the TaskView.launchTask() call, in an
|
||||
@@ -38,7 +38,7 @@ import com.android.quickstep.RecentsModel;
|
||||
*/
|
||||
public class TaskRemovedDuringLaunchListener {
|
||||
|
||||
private BaseActivity mActivity;
|
||||
private RecentsViewContainer mContainer;
|
||||
private int mLaunchedTaskId = INVALID_TASK_ID;
|
||||
private Runnable mTaskLaunchFailedCallback = null;
|
||||
|
||||
@@ -49,16 +49,16 @@ public class TaskRemovedDuringLaunchListener {
|
||||
* Registers a failure listener callback if it detects a scenario in which an app launch
|
||||
* failed before the transition finished.
|
||||
*/
|
||||
public void register(BaseActivity activity, int launchedTaskId,
|
||||
public void register(RecentsViewContainer container, int launchedTaskId,
|
||||
@NonNull Runnable taskLaunchFailedCallback) {
|
||||
// The normal task launch case, Launcher stops and updates its state correctly
|
||||
activity.addEventCallback(EVENT_STOPPED, mUnregisterCallback);
|
||||
container.addEventCallback(EVENT_STOPPED, mUnregisterCallback);
|
||||
// The transition hasn't finished but Launcher was resumed, check if the launch failed
|
||||
activity.addEventCallback(EVENT_RESUMED, mResumeCallback);
|
||||
container.addEventCallback(EVENT_RESUMED, mResumeCallback);
|
||||
// If we somehow don't get any of the above signals, then just unregister this listener
|
||||
activity.addEventCallback(EVENT_DESTROYED, mUnregisterCallback);
|
||||
container.addEventCallback(EVENT_DESTROYED, mUnregisterCallback);
|
||||
|
||||
mActivity = activity;
|
||||
mContainer = container;
|
||||
mLaunchedTaskId = launchedTaskId;
|
||||
mTaskLaunchFailedCallback = taskLaunchFailedCallback;
|
||||
}
|
||||
@@ -67,11 +67,11 @@ public class TaskRemovedDuringLaunchListener {
|
||||
* Unregisters the failure listener.
|
||||
*/
|
||||
private void unregister() {
|
||||
mActivity.removeEventCallback(EVENT_STOPPED, mUnregisterCallback);
|
||||
mActivity.removeEventCallback(EVENT_RESUMED, mResumeCallback);
|
||||
mActivity.removeEventCallback(EVENT_DESTROYED, mUnregisterCallback);
|
||||
mContainer.removeEventCallback(EVENT_STOPPED, mUnregisterCallback);
|
||||
mContainer.removeEventCallback(EVENT_RESUMED, mResumeCallback);
|
||||
mContainer.removeEventCallback(EVENT_DESTROYED, mUnregisterCallback);
|
||||
|
||||
mActivity = null;
|
||||
mContainer = null;
|
||||
mLaunchedTaskId = INVALID_TASK_ID;
|
||||
mTaskLaunchFailedCallback = null;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds;
|
||||
import com.android.launcher3.util.TraceHelper;
|
||||
import com.android.quickstep.BaseActivityInterface;
|
||||
import com.android.quickstep.BaseContainerInterface;
|
||||
import com.android.quickstep.TaskAnimationManager;
|
||||
import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties;
|
||||
import com.android.quickstep.views.TaskView.FullscreenDrawParams;
|
||||
@@ -70,7 +71,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
private final float[] mTempPoint = new float[2];
|
||||
|
||||
private final Context mContext;
|
||||
private final BaseActivityInterface mSizeStrategy;
|
||||
private final BaseContainerInterface mSizeStrategy;
|
||||
|
||||
@NonNull
|
||||
private RecentsOrientedState mOrientationState;
|
||||
@@ -122,7 +123,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
private int mTaskRectTranslationX;
|
||||
private int mTaskRectTranslationY;
|
||||
|
||||
public TaskViewSimulator(Context context, BaseActivityInterface sizeStrategy) {
|
||||
public TaskViewSimulator(Context context, BaseContainerInterface sizeStrategy) {
|
||||
mContext = context;
|
||||
mSizeStrategy = sizeStrategy;
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.launcher3.Hotseat;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.systemui.unfold.updates.RotationChangeProvider;
|
||||
|
||||
/**
|
||||
@@ -28,10 +28,10 @@ import com.android.systemui.unfold.updates.RotationChangeProvider;
|
||||
*/
|
||||
public class UnfoldMoveFromCenterHotseatAnimator extends BaseUnfoldMoveFromCenterAnimator {
|
||||
|
||||
private final Launcher mLauncher;
|
||||
private final QuickstepLauncher mLauncher;
|
||||
|
||||
public UnfoldMoveFromCenterHotseatAnimator(Launcher launcher, WindowManager windowManager,
|
||||
RotationChangeProvider rotationChangeProvider) {
|
||||
public UnfoldMoveFromCenterHotseatAnimator(QuickstepLauncher launcher,
|
||||
WindowManager windowManager, RotationChangeProvider rotationChangeProvider) {
|
||||
super(windowManager, rotationChangeProvider);
|
||||
mLauncher = launcher;
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.launcher3.CellLayout;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.ShortcutAndWidgetContainer;
|
||||
import com.android.launcher3.Workspace;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.systemui.unfold.updates.RotationChangeProvider;
|
||||
|
||||
/**
|
||||
@@ -29,10 +29,10 @@ import com.android.systemui.unfold.updates.RotationChangeProvider;
|
||||
*/
|
||||
public class UnfoldMoveFromCenterWorkspaceAnimator extends BaseUnfoldMoveFromCenterAnimator {
|
||||
|
||||
private final Launcher mLauncher;
|
||||
private final QuickstepLauncher mLauncher;
|
||||
|
||||
public UnfoldMoveFromCenterWorkspaceAnimator(Launcher launcher, WindowManager windowManager,
|
||||
RotationChangeProvider rotationChangeProvider) {
|
||||
public UnfoldMoveFromCenterWorkspaceAnimator(QuickstepLauncher launcher,
|
||||
WindowManager windowManager, RotationChangeProvider rotationChangeProvider) {
|
||||
super(windowManager, rotationChangeProvider);
|
||||
mLauncher = launcher;
|
||||
}
|
||||
|
||||
+2
-2
@@ -21,15 +21,15 @@ import android.view.Surface
|
||||
import com.android.launcher3.Alarm
|
||||
import com.android.launcher3.DeviceProfile
|
||||
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener
|
||||
import com.android.launcher3.Launcher
|
||||
import com.android.launcher3.anim.PendingAnimation
|
||||
import com.android.launcher3.config.FeatureFlags
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher
|
||||
import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter
|
||||
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
|
||||
|
||||
/** Controls animations that are happening during unfolding foldable devices */
|
||||
class LauncherUnfoldTransitionController(
|
||||
private val launcher: Launcher,
|
||||
private val launcher: QuickstepLauncher,
|
||||
private val progressProvider: ProxyUnfoldTransitionProvider
|
||||
) : OnDeviceProfileChangeListener, ActivityLifecycleCallbacksAdapter, TransitionProgressListener {
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ import android.view.ViewGroup
|
||||
import com.android.app.animation.Interpolators.LINEAR
|
||||
import com.android.app.animation.Interpolators.clampToProgress
|
||||
import com.android.launcher3.CellLayout
|
||||
import com.android.launcher3.Launcher
|
||||
import com.android.launcher3.LauncherAnimUtils.HOTSEAT_SCALE_PROPERTY_FACTORY
|
||||
import com.android.launcher3.LauncherAnimUtils.SCALE_INDEX_UNFOLD_ANIMATION
|
||||
import com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X
|
||||
@@ -28,6 +27,7 @@ import com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y
|
||||
import com.android.launcher3.LauncherAnimUtils.WORKSPACE_SCALE_PROPERTY_FACTORY
|
||||
import com.android.launcher3.Workspace
|
||||
import com.android.launcher3.anim.PendingAnimation
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher
|
||||
import com.android.launcher3.util.HorizontalInsettableView
|
||||
|
||||
private typealias ViewGroupAction = (ViewGroup, Boolean) -> Unit
|
||||
@@ -112,7 +112,7 @@ object UnfoldAnimationBuilder {
|
||||
* Builds an animation for the unfold experience and adds it to the provided PendingAnimation
|
||||
*/
|
||||
fun buildUnfoldAnimation(
|
||||
launcher: Launcher,
|
||||
launcher: QuickstepLauncher,
|
||||
isVerticalFold: Boolean,
|
||||
screenSize: Point,
|
||||
anim: PendingAnimation
|
||||
|
||||
@@ -68,7 +68,7 @@ public class ClearAllButton extends Button {
|
||||
}
|
||||
};
|
||||
|
||||
private final StatefulActivity mActivity;
|
||||
private final RecentsViewContainer mContainer;
|
||||
private float mScrollAlpha = 1;
|
||||
private float mContentAlpha = 1;
|
||||
private float mVisibilityAlpha = 1;
|
||||
@@ -92,7 +92,7 @@ public class ClearAllButton extends Button {
|
||||
public ClearAllButton(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mIsRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
|
||||
mActivity = StatefulActivity.fromContext(context);
|
||||
mContainer = RecentsViewContainer.containerFromContext(context);
|
||||
|
||||
if (Flags.enableFocusOutline()) {
|
||||
TypedArray styledAttrs = context.obtainStyledAttributes(attrs,
|
||||
@@ -326,7 +326,7 @@ public class ClearAllButton extends Button {
|
||||
* Get the Y translation that is set in the original layout position, before scrolling.
|
||||
*/
|
||||
private float getOriginalTranslationY() {
|
||||
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
|
||||
DeviceProfile deviceProfile = mContainer.getDeviceProfile();
|
||||
if (deviceProfile.isTablet) {
|
||||
if (enableGridOnlyOverview()) {
|
||||
return (getRecentsView().getLastComputedTaskSize().height()
|
||||
|
||||
@@ -33,6 +33,7 @@ import androidx.annotation.Nullable;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
|
||||
/**
|
||||
* Floating view show on launcher home screen that notifies the user that an app will be launched to
|
||||
@@ -47,7 +48,7 @@ public class DesktopAppSelectView extends LinearLayout {
|
||||
private static final int SHOW_CONTENT_ALPHA_DURATION = 83;
|
||||
private static final int HIDE_DURATION = 83;
|
||||
|
||||
private final Launcher mLauncher;
|
||||
private final RecentsViewContainer mContainer;
|
||||
|
||||
private View mText;
|
||||
private View mCloseButton;
|
||||
@@ -71,7 +72,7 @@ public class DesktopAppSelectView extends LinearLayout {
|
||||
public DesktopAppSelectView(Context context, AttributeSet attrs, int defStyleAttr,
|
||||
int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
mLauncher = Launcher.getLauncher(context);
|
||||
mContainer = RecentsViewContainer.containerFromContext(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,7 +105,7 @@ public class DesktopAppSelectView extends LinearLayout {
|
||||
}
|
||||
|
||||
private void show() {
|
||||
mLauncher.getDragLayer().addView(this);
|
||||
mContainer.getDragLayer().addView(this);
|
||||
|
||||
// Set up initial values
|
||||
getBackground().setAlpha(0);
|
||||
@@ -163,7 +164,7 @@ public class DesktopAppSelectView extends LinearLayout {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
mLauncher.getDragLayer().removeView(DesktopAppSelectView.this);
|
||||
mContainer.getDragLayer().removeView(DesktopAppSelectView.this);
|
||||
mHideAnimation = null;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -118,7 +118,7 @@ public class DesktopTaskView extends TaskView {
|
||||
mBackgroundView = findViewById(R.id.background);
|
||||
|
||||
int topMarginPx =
|
||||
mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
|
||||
mContainer.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
|
||||
FrameLayout.LayoutParams params = (LayoutParams) mBackgroundView.getLayoutParams();
|
||||
params.topMargin = topMarginPx;
|
||||
mBackgroundView.setLayoutParams(params);
|
||||
@@ -303,7 +303,7 @@ public class DesktopTaskView extends TaskView {
|
||||
|
||||
@Override
|
||||
protected void setThumbnailOrientation(RecentsOrientedState orientationState) {
|
||||
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
|
||||
DeviceProfile deviceProfile = mContainer.getDeviceProfile();
|
||||
int thumbnailTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
|
||||
|
||||
LayoutParams snapshotParams = (LayoutParams) mSnapshotView.getLayoutParams();
|
||||
@@ -420,7 +420,7 @@ public class DesktopTaskView extends TaskView {
|
||||
|
||||
setMeasuredDimension(containerWidth, containerHeight);
|
||||
|
||||
int thumbnailTopMarginPx = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
|
||||
int thumbnailTopMarginPx = mContainer.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
|
||||
containerHeight -= thumbnailTopMarginPx;
|
||||
|
||||
int thumbnails = mSnapshotViewMap.size();
|
||||
@@ -428,8 +428,8 @@ public class DesktopTaskView extends TaskView {
|
||||
return;
|
||||
}
|
||||
|
||||
int windowWidth = mActivity.getDeviceProfile().widthPx;
|
||||
int windowHeight = mActivity.getDeviceProfile().heightPx;
|
||||
int windowWidth = mContainer.getDeviceProfile().widthPx;
|
||||
int windowHeight = mContainer.getDeviceProfile().heightPx;
|
||||
|
||||
float scaleWidth = containerWidth / (float) windowWidth;
|
||||
float scaleHeight = containerHeight / (float) windowHeight;
|
||||
|
||||
@@ -45,8 +45,6 @@ import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
@@ -83,7 +81,7 @@ public final class DigitalWellBeingToast {
|
||||
|
||||
private static final String TAG = DigitalWellBeingToast.class.getSimpleName();
|
||||
|
||||
private final BaseDraggingActivity mActivity;
|
||||
private final RecentsViewContainer mContainer;
|
||||
private final TaskView mTaskView;
|
||||
private final LauncherApps mLauncherApps;
|
||||
|
||||
@@ -102,10 +100,10 @@ public final class DigitalWellBeingToast {
|
||||
private float mSplitOffsetTranslationY;
|
||||
private float mSplitOffsetTranslationX;
|
||||
|
||||
public DigitalWellBeingToast(BaseDraggingActivity activity, TaskView taskView) {
|
||||
mActivity = activity;
|
||||
public DigitalWellBeingToast(RecentsViewContainer container, TaskView taskView) {
|
||||
mContainer = container;
|
||||
mTaskView = taskView;
|
||||
mLauncherApps = activity.getSystemService(LauncherApps.class);
|
||||
mLauncherApps = container.asContext().getSystemService(LauncherApps.class);
|
||||
}
|
||||
|
||||
private void setNoLimit() {
|
||||
@@ -120,9 +118,10 @@ public final class DigitalWellBeingToast {
|
||||
mAppUsageLimitTimeMs = appUsageLimitTimeMs;
|
||||
mAppRemainingTimeMs = appRemainingTimeMs;
|
||||
mHasLimit = true;
|
||||
TextView toast = mActivity.getViewCache().getView(R.layout.digital_wellbeing_toast,
|
||||
mActivity, mTaskView);
|
||||
toast.setText(prefixTextWithIcon(mActivity, R.drawable.ic_hourglass_top, getText()));
|
||||
TextView toast = mContainer.getViewCache().getView(R.layout.digital_wellbeing_toast,
|
||||
mContainer.asContext(), mTaskView);
|
||||
toast.setText(prefixTextWithIcon(mContainer.asContext(), R.drawable.ic_hourglass_top,
|
||||
getText()));
|
||||
toast.setOnClickListener(this::openAppUsageSettings);
|
||||
replaceBanner(toast);
|
||||
|
||||
@@ -170,14 +169,14 @@ public final class DigitalWellBeingToast {
|
||||
public void setSplitConfiguration(SplitBounds splitBounds) {
|
||||
mSplitBounds = splitBounds;
|
||||
if (mSplitBounds == null
|
||||
|| !mActivity.getDeviceProfile().isTablet
|
||||
|| !mContainer.getDeviceProfile().isTablet
|
||||
|| mTaskView.isFocusedTask()) {
|
||||
mSplitBannerConfig = SPLIT_BANNER_FULLSCREEN;
|
||||
return;
|
||||
}
|
||||
|
||||
// For portrait grid only height of task changes, not width. So we keep the text the same
|
||||
if (!mActivity.getDeviceProfile().isLeftRightSplit) {
|
||||
if (!mContainer.getDeviceProfile().isLeftRightSplit) {
|
||||
mSplitBannerConfig = SPLIT_GRID_BANNER_LARGE;
|
||||
return;
|
||||
}
|
||||
@@ -226,7 +225,7 @@ public final class DigitalWellBeingToast {
|
||||
|
||||
// Use a specific string for usage less than one minute but non-zero.
|
||||
if (duration.compareTo(Duration.ZERO) > 0) {
|
||||
return mActivity.getString(durationLessThanOneMinuteStringId);
|
||||
return mContainer.asContext().getString(durationLessThanOneMinuteStringId);
|
||||
}
|
||||
|
||||
// Otherwise, return 0-minute string.
|
||||
@@ -250,7 +249,7 @@ public final class DigitalWellBeingToast {
|
||||
R.string.shorter_duration_less_than_one_minute,
|
||||
false /* forceFormatWidth */);
|
||||
if (forContentDesc || mSplitBannerConfig == SPLIT_BANNER_FULLSCREEN) {
|
||||
return mActivity.getString(
|
||||
return mContainer.asContext().getString(
|
||||
R.string.time_left_for_app,
|
||||
readableDuration);
|
||||
}
|
||||
@@ -270,11 +269,12 @@ public final class DigitalWellBeingToast {
|
||||
mTask.getTopComponent().getPackageName()).addFlags(
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
try {
|
||||
final BaseActivity activity = BaseActivity.fromContext(view.getContext());
|
||||
final RecentsViewContainer container =
|
||||
RecentsViewContainer.containerFromContext(view.getContext());
|
||||
final ActivityOptions options = ActivityOptions.makeScaleUpAnimation(
|
||||
view, 0, 0,
|
||||
view.getWidth(), view.getHeight());
|
||||
activity.startActivity(intent, options.toBundle());
|
||||
container.asContext().startActivity(intent, options.toBundle());
|
||||
|
||||
// TODO: add WW logging on the app usage settings click.
|
||||
} catch (ActivityNotFoundException e) {
|
||||
@@ -286,7 +286,7 @@ public final class DigitalWellBeingToast {
|
||||
private String getContentDescriptionForTask(
|
||||
Task task, long appUsageLimitTimeMs, long appRemainingTimeMs) {
|
||||
return appUsageLimitTimeMs >= 0 && appRemainingTimeMs >= 0 ?
|
||||
mActivity.getString(
|
||||
mContainer.asContext().getString(
|
||||
R.string.task_contents_description_with_remaining_time,
|
||||
task.titleDescription,
|
||||
getText(appRemainingTimeMs, true /* forContentDesc */)) :
|
||||
@@ -303,7 +303,7 @@ public final class DigitalWellBeingToast {
|
||||
mBanner.setOutlineProvider(mOldBannerOutlineProvider);
|
||||
mTaskView.removeView(mBanner);
|
||||
mBanner.setOnClickListener(null);
|
||||
mActivity.getViewCache().recycleView(R.layout.digital_wellbeing_toast, mBanner);
|
||||
mContainer.getViewCache().recycleView(R.layout.digital_wellbeing_toast, mBanner);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,7 +318,7 @@ public final class DigitalWellBeingToast {
|
||||
private void setupAndAddBanner() {
|
||||
FrameLayout.LayoutParams layoutParams =
|
||||
(FrameLayout.LayoutParams) mBanner.getLayoutParams();
|
||||
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
|
||||
DeviceProfile deviceProfile = mContainer.getDeviceProfile();
|
||||
layoutParams.bottomMargin = ((ViewGroup.MarginLayoutParams)
|
||||
mTaskView.getThumbnail().getLayoutParams()).bottomMargin;
|
||||
RecentsPagedOrientationHandler orientationHandler = mTaskView.getPagedOrientationHandler();
|
||||
|
||||
@@ -26,7 +26,6 @@ import android.graphics.drawable.Drawable
|
||||
import android.os.Build
|
||||
import android.view.animation.Interpolator
|
||||
import com.android.app.animation.Interpolators
|
||||
import com.android.launcher3.Launcher
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.Utilities
|
||||
import com.android.quickstep.util.AnimUtils
|
||||
@@ -55,7 +54,7 @@ class FloatingAppPairBackground(
|
||||
private val ARRAY_OF_ZEROES = FloatArray(8)
|
||||
}
|
||||
|
||||
private val launcher: Launcher
|
||||
private val container: RecentsViewContainer
|
||||
private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG)
|
||||
|
||||
// Animation interpolators
|
||||
@@ -70,15 +69,15 @@ class FloatingAppPairBackground(
|
||||
private val desiredSplitRatio: Float
|
||||
|
||||
init {
|
||||
launcher = Launcher.getLauncher(context)
|
||||
val dp = launcher.deviceProfile
|
||||
container = RecentsViewContainer.containerFromContext(context)
|
||||
val dp = container.deviceProfile
|
||||
// Set up background paint color
|
||||
val ta = context.theme.obtainStyledAttributes(R.styleable.FolderIconPreview)
|
||||
backgroundPaint.style = Paint.Style.FILL
|
||||
backgroundPaint.color = ta.getColor(R.styleable.FolderIconPreview_folderPreviewColor, 0)
|
||||
ta.recycle()
|
||||
// Set up timings and interpolators
|
||||
val timings = AnimUtils.getDeviceAppPairLaunchTimings(launcher.deviceProfile.isTablet)
|
||||
val timings = AnimUtils.getDeviceAppPairLaunchTimings(container.deviceProfile.isTablet)
|
||||
expandXInterpolator =
|
||||
Interpolators.clampToProgress(
|
||||
timings.getStagedRectScaleXInterpolator(),
|
||||
@@ -105,9 +104,9 @@ class FloatingAppPairBackground(
|
||||
)
|
||||
|
||||
// Find device-specific measurements
|
||||
deviceCornerRadius = QuickStepContract.getWindowCornerRadius(launcher)
|
||||
deviceCornerRadius = QuickStepContract.getWindowCornerRadius(container.asContext())
|
||||
deviceHalfDividerSize =
|
||||
launcher.resources.getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2f
|
||||
container.asContext().resources.getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2f
|
||||
val dividerCenterPos = dividerPos + deviceHalfDividerSize
|
||||
desiredSplitRatio =
|
||||
if (dp.isLeftRightSplit) dividerCenterPos / dp.widthPx
|
||||
@@ -115,7 +114,7 @@ class FloatingAppPairBackground(
|
||||
}
|
||||
|
||||
override fun draw(canvas: Canvas) {
|
||||
if (launcher.deviceProfile.isLeftRightSplit) {
|
||||
if (container.deviceProfile.isLeftRightSplit) {
|
||||
drawLeftRightSplit(canvas)
|
||||
} else {
|
||||
drawTopBottomSplit(canvas)
|
||||
@@ -150,39 +149,37 @@ class FloatingAppPairBackground(
|
||||
val dividerCenterPos = width * desiredSplitRatio
|
||||
|
||||
// The left half of the background image
|
||||
val leftSide = RectF(
|
||||
0f,
|
||||
0f,
|
||||
dividerCenterPos - changingDividerSize,
|
||||
height
|
||||
)
|
||||
val leftSide = RectF(0f, 0f, dividerCenterPos - changingDividerSize, height)
|
||||
// The right half of the background image
|
||||
val rightSide = RectF(
|
||||
dividerCenterPos + changingDividerSize,
|
||||
0f,
|
||||
width,
|
||||
height
|
||||
)
|
||||
val rightSide = RectF(dividerCenterPos + changingDividerSize, 0f, width, height)
|
||||
|
||||
// Draw background
|
||||
drawCustomRoundedRect(
|
||||
canvas,
|
||||
leftSide,
|
||||
floatArrayOf(
|
||||
cornerRadiusX, cornerRadiusY,
|
||||
changingInnerRadiusX, changingInnerRadiusY,
|
||||
changingInnerRadiusX, changingInnerRadiusY,
|
||||
cornerRadiusX, cornerRadiusY
|
||||
cornerRadiusX,
|
||||
cornerRadiusY,
|
||||
changingInnerRadiusX,
|
||||
changingInnerRadiusY,
|
||||
changingInnerRadiusX,
|
||||
changingInnerRadiusY,
|
||||
cornerRadiusX,
|
||||
cornerRadiusY,
|
||||
)
|
||||
)
|
||||
drawCustomRoundedRect(
|
||||
canvas,
|
||||
rightSide,
|
||||
floatArrayOf(
|
||||
changingInnerRadiusX, changingInnerRadiusY,
|
||||
cornerRadiusX, cornerRadiusY,
|
||||
cornerRadiusX, cornerRadiusY,
|
||||
changingInnerRadiusX, changingInnerRadiusY
|
||||
changingInnerRadiusX,
|
||||
changingInnerRadiusY,
|
||||
cornerRadiusX,
|
||||
cornerRadiusY,
|
||||
cornerRadiusX,
|
||||
cornerRadiusY,
|
||||
changingInnerRadiusX,
|
||||
changingInnerRadiusY,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -250,39 +247,37 @@ class FloatingAppPairBackground(
|
||||
val dividerCenterPos = height * desiredSplitRatio
|
||||
|
||||
// The top half of the background image
|
||||
val topSide = RectF(
|
||||
0f,
|
||||
0f,
|
||||
width,
|
||||
dividerCenterPos - changingDividerSize
|
||||
)
|
||||
val topSide = RectF(0f, 0f, width, dividerCenterPos - changingDividerSize)
|
||||
// The bottom half of the background image
|
||||
val bottomSide = RectF(
|
||||
0f,
|
||||
dividerCenterPos + changingDividerSize,
|
||||
width,
|
||||
height
|
||||
)
|
||||
val bottomSide = RectF(0f, dividerCenterPos + changingDividerSize, width, height)
|
||||
|
||||
// Draw background
|
||||
drawCustomRoundedRect(
|
||||
canvas,
|
||||
topSide,
|
||||
floatArrayOf(
|
||||
cornerRadiusX, cornerRadiusY,
|
||||
cornerRadiusX, cornerRadiusY,
|
||||
changingInnerRadiusX, changingInnerRadiusY,
|
||||
changingInnerRadiusX, changingInnerRadiusY
|
||||
cornerRadiusX,
|
||||
cornerRadiusY,
|
||||
cornerRadiusX,
|
||||
cornerRadiusY,
|
||||
changingInnerRadiusX,
|
||||
changingInnerRadiusY,
|
||||
changingInnerRadiusX,
|
||||
changingInnerRadiusY
|
||||
)
|
||||
)
|
||||
drawCustomRoundedRect(
|
||||
canvas,
|
||||
bottomSide,
|
||||
floatArrayOf(
|
||||
changingInnerRadiusX, changingInnerRadiusY,
|
||||
changingInnerRadiusX, changingInnerRadiusY,
|
||||
cornerRadiusX, cornerRadiusY,
|
||||
cornerRadiusX, cornerRadiusY
|
||||
changingInnerRadiusX,
|
||||
changingInnerRadiusY,
|
||||
changingInnerRadiusX,
|
||||
changingInnerRadiusY,
|
||||
cornerRadiusX,
|
||||
cornerRadiusY,
|
||||
cornerRadiusX,
|
||||
cornerRadiusY
|
||||
)
|
||||
)
|
||||
|
||||
@@ -338,8 +333,10 @@ class FloatingAppPairBackground(
|
||||
// Fallback rectangle with uniform rounded corners
|
||||
val scaleFactorX = floatingView.scaleX
|
||||
val scaleFactorY = floatingView.scaleY
|
||||
val cornerRadiusX = QuickStepContract.getWindowCornerRadius(launcher) / scaleFactorX
|
||||
val cornerRadiusY = QuickStepContract.getWindowCornerRadius(launcher) / scaleFactorY
|
||||
val cornerRadiusX =
|
||||
QuickStepContract.getWindowCornerRadius(container.asContext()) / scaleFactorX
|
||||
val cornerRadiusY =
|
||||
QuickStepContract.getWindowCornerRadius(container.asContext()) / scaleFactorY
|
||||
c.drawRoundRect(rect, cornerRadiusX, cornerRadiusY, backgroundPaint)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,12 +36,10 @@ import android.widget.FrameLayout;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.InsettableFrameLayout;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.launcher3.taskbar.TaskbarActivityContext;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions;
|
||||
import com.android.launcher3.views.BaseDragLayer;
|
||||
@@ -54,7 +52,7 @@ import com.android.systemui.shared.system.QuickStepContract;
|
||||
|
||||
/**
|
||||
* Create an instance via
|
||||
* {@link #getFloatingTaskView(StatefulActivity, View, Bitmap, Drawable, RectF)} to
|
||||
* {@link #getFloatingTaskView(RecentsViewContainer, View, Bitmap, Drawable, RectF)} to
|
||||
* which will have the thumbnail from the provided existing TaskView overlaying the taskview itself.
|
||||
*
|
||||
* Can then animate the taskview using
|
||||
@@ -67,32 +65,32 @@ public class FloatingTaskView extends FrameLayout {
|
||||
|
||||
public static final FloatProperty<FloatingTaskView> PRIMARY_TRANSLATE_OFFSCREEN =
|
||||
new FloatProperty<FloatingTaskView>("floatingTaskPrimaryTranslateOffscreen") {
|
||||
@Override
|
||||
public void setValue(FloatingTaskView view, float translation) {
|
||||
((RecentsView) view.mActivity.getOverviewPanel()).getPagedOrientationHandler()
|
||||
.setFloatingTaskPrimaryTranslation(
|
||||
view,
|
||||
translation,
|
||||
view.mActivity.getDeviceProfile()
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public void setValue(FloatingTaskView view, float translation) {
|
||||
((RecentsView) view.mContainer.getOverviewPanel()).getPagedOrientationHandler()
|
||||
.setFloatingTaskPrimaryTranslation(
|
||||
view,
|
||||
translation,
|
||||
view.mContainer.getDeviceProfile()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(FloatingTaskView view) {
|
||||
return ((RecentsView) view.mActivity.getOverviewPanel())
|
||||
.getPagedOrientationHandler()
|
||||
.getFloatingTaskPrimaryTranslation(
|
||||
view,
|
||||
view.mActivity.getDeviceProfile()
|
||||
);
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public Float get(FloatingTaskView view) {
|
||||
return ((RecentsView) view.mContainer.getOverviewPanel())
|
||||
.getPagedOrientationHandler()
|
||||
.getFloatingTaskPrimaryTranslation(
|
||||
view,
|
||||
view.mContainer.getDeviceProfile()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
private int mSplitHolderSize;
|
||||
private FloatingTaskThumbnailView mThumbnailView;
|
||||
private SplitPlaceholderView mSplitPlaceholderView;
|
||||
private RectF mStartingPosition;
|
||||
private final StatefulActivity mActivity;
|
||||
private final RecentsViewContainer mContainer;
|
||||
private final boolean mIsRtl;
|
||||
private final FullscreenDrawParams mFullscreenParams;
|
||||
private RecentsPagedOrientationHandler mOrientationHandler;
|
||||
@@ -110,7 +108,7 @@ public class FloatingTaskView extends FrameLayout {
|
||||
|
||||
public FloatingTaskView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
mActivity = BaseActivity.fromContext(context);
|
||||
mContainer = RecentsViewContainer.containerFromContext(context);
|
||||
mIsRtl = Utilities.isRtl(getResources());
|
||||
mFullscreenParams = new FullscreenDrawParams(context);
|
||||
|
||||
@@ -126,7 +124,7 @@ public class FloatingTaskView extends FrameLayout {
|
||||
mSplitPlaceholderView.setAlpha(0);
|
||||
}
|
||||
|
||||
private void init(StatefulActivity launcher, View originalView, @Nullable Bitmap thumbnail,
|
||||
private void init(RecentsViewContainer launcher, View originalView, @Nullable Bitmap thumbnail,
|
||||
Drawable icon, RectF positionOut) {
|
||||
mStartingPosition = positionOut;
|
||||
updateInitialPositionForView(originalView);
|
||||
@@ -153,7 +151,7 @@ public class FloatingTaskView extends FrameLayout {
|
||||
* Configures and returns a an instance of {@link FloatingTaskView} initially matching the
|
||||
* appearance of {@code originalView}.
|
||||
*/
|
||||
public static FloatingTaskView getFloatingTaskView(StatefulActivity launcher,
|
||||
public static FloatingTaskView getFloatingTaskView(RecentsViewContainer launcher,
|
||||
View originalView, @Nullable Bitmap thumbnail, Drawable icon, RectF positionOut) {
|
||||
final ViewGroup dragLayer = launcher.getDragLayer();
|
||||
final FloatingTaskView floatingView = (FloatingTaskView) launcher.getLayoutInflater()
|
||||
@@ -179,13 +177,13 @@ public class FloatingTaskView extends FrameLayout {
|
||||
originalView.getBoundsOnScreen(mTmpRect);
|
||||
mStartingPosition.set(mTmpRect);
|
||||
int[] dragLayerPositionRelativeToScreen =
|
||||
mActivity.getDragLayer().getLocationOnScreen();
|
||||
mContainer.getDragLayer().getLocationOnScreen();
|
||||
mStartingPosition.offset(
|
||||
-dragLayerPositionRelativeToScreen[0],
|
||||
-dragLayerPositionRelativeToScreen[1]);
|
||||
} else {
|
||||
Rect viewBounds = new Rect(0, 0, originalView.getWidth(), originalView.getHeight());
|
||||
Utilities.getBoundsForViewInDragLayer(mActivity.getDragLayer(), originalView,
|
||||
Utilities.getBoundsForViewInDragLayer(mContainer.getDragLayer(), originalView,
|
||||
viewBounds, false /* ignoreTransform */, null /* recycle */,
|
||||
mStartingPosition);
|
||||
}
|
||||
@@ -235,7 +233,7 @@ public class FloatingTaskView extends FrameLayout {
|
||||
// Position the floating view exactly on top of the original
|
||||
lp.topMargin = Math.round(pos.top);
|
||||
if (mIsRtl) {
|
||||
lp.setMarginStart(mActivity.getDeviceProfile().widthPx - Math.round(pos.right));
|
||||
lp.setMarginStart(mContainer.getDeviceProfile().widthPx - Math.round(pos.right));
|
||||
} else {
|
||||
lp.setMarginStart(Math.round(pos.left));
|
||||
}
|
||||
@@ -252,7 +250,7 @@ public class FloatingTaskView extends FrameLayout {
|
||||
*/
|
||||
public void addStagingAnimation(PendingAnimation animation, RectF startingBounds,
|
||||
Rect endBounds, boolean fadeWithThumbnail, boolean isStagedTask) {
|
||||
boolean isTablet = mActivity.getDeviceProfile().isTablet;
|
||||
boolean isTablet = mContainer.getDeviceProfile().isTablet;
|
||||
boolean splittingFromOverview = fadeWithThumbnail;
|
||||
SplitAnimationTimings timings;
|
||||
|
||||
@@ -276,7 +274,7 @@ public class FloatingTaskView extends FrameLayout {
|
||||
public void addConfirmAnimation(PendingAnimation animation, RectF startingBounds,
|
||||
Rect endBounds, boolean fadeWithThumbnail, boolean isStagedTask) {
|
||||
SplitAnimationTimings timings =
|
||||
AnimUtils.getDeviceSplitToConfirmTimings(mActivity.getDeviceProfile().isTablet);
|
||||
AnimUtils.getDeviceSplitToConfirmTimings(mContainer.getDeviceProfile().isTablet);
|
||||
|
||||
addAnimation(animation, startingBounds, endBounds, fadeWithThumbnail, isStagedTask,
|
||||
timings);
|
||||
@@ -291,7 +289,7 @@ public class FloatingTaskView extends FrameLayout {
|
||||
Rect endBounds, boolean fadeWithThumbnail, boolean isStagedTask,
|
||||
SplitAnimationTimings timings) {
|
||||
mFullscreenParams.setIsStagedTask(isStagedTask);
|
||||
final BaseDragLayer dragLayer = mActivity.getDragLayer();
|
||||
final BaseDragLayer dragLayer = mContainer.getDragLayer();
|
||||
int[] dragLayerBounds = new int[2];
|
||||
dragLayer.getLocationOnScreen(dragLayerBounds);
|
||||
SplitOverlayProperties prop = new SplitOverlayProperties(endBounds,
|
||||
@@ -391,7 +389,7 @@ public class FloatingTaskView extends FrameLayout {
|
||||
mOrientationHandler.updateSplitIconParams(iconView, onScreenRectCenterX,
|
||||
onScreenRectCenterY, mFullscreenParams.mScaleX, mFullscreenParams.mScaleY,
|
||||
iconView.getDrawableWidth(), iconView.getDrawableHeight(),
|
||||
mActivity.getDeviceProfile(), mStagePosition);
|
||||
mContainer.getDeviceProfile(), mStagePosition);
|
||||
}
|
||||
|
||||
public int getStagePosition() {
|
||||
|
||||
@@ -33,10 +33,10 @@ import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.dragndrop.DragLayer;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.launcher3.views.FloatingView;
|
||||
import com.android.launcher3.views.ListenerView;
|
||||
@@ -49,7 +49,7 @@ public class FloatingWidgetView extends FrameLayout implements AnimatorListener,
|
||||
OnGlobalLayoutListener, FloatingView {
|
||||
private static final Matrix sTmpMatrix = new Matrix();
|
||||
|
||||
private final Launcher mLauncher;
|
||||
private final QuickstepLauncher mLauncher;
|
||||
private final ListenerView mListenerView;
|
||||
private final FloatingWidgetBackgroundView mBackgroundView;
|
||||
private final RectF mBackgroundOffset = new RectF();
|
||||
@@ -80,7 +80,7 @@ public class FloatingWidgetView extends FrameLayout implements AnimatorListener,
|
||||
|
||||
public FloatingWidgetView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
mLauncher = Launcher.getLauncher(context);
|
||||
mLauncher = QuickstepLauncher.getLauncher(context);
|
||||
mListenerView = new ListenerView(context, attrs);
|
||||
mBackgroundView = new FloatingWidgetBackgroundView(context, attrs, defStyleAttr);
|
||||
addView(mBackgroundView);
|
||||
@@ -283,7 +283,7 @@ public class FloatingWidgetView extends FrameLayout implements AnimatorListener,
|
||||
* @param windowSize the size of the window when launched
|
||||
* @param windowCornerRadius the corner radius of the window
|
||||
*/
|
||||
public static FloatingWidgetView getFloatingWidgetView(Launcher launcher,
|
||||
public static FloatingWidgetView getFloatingWidgetView(QuickstepLauncher launcher,
|
||||
LauncherAppWidgetHostView originalView, RectF widgetBackgroundPosition,
|
||||
Size windowSize, float windowCornerRadius, boolean appTargetsAreTranslucent,
|
||||
int fallbackBackgroundColor) {
|
||||
|
||||
@@ -41,11 +41,11 @@ import com.android.systemui.shared.recents.utilities.PreviewPositionHelper;
|
||||
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
|
||||
import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition;
|
||||
|
||||
import kotlin.Unit;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import kotlin.Unit;
|
||||
|
||||
/**
|
||||
* TaskView that contains and shows thumbnails for not one, BUT TWO(!!) tasks
|
||||
*
|
||||
@@ -81,7 +81,7 @@ public class GroupedTaskView extends TaskView {
|
||||
|
||||
public GroupedTaskView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
mDigitalWellBeingToast2 = new DigitalWellBeingToast(mActivity, this);
|
||||
mDigitalWellBeingToast2 = new DigitalWellBeingToast(mContainer, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -356,7 +356,7 @@ public class GroupedTaskView extends TaskView {
|
||||
if (initSplitTaskId == INVALID_TASK_ID) {
|
||||
getPagedOrientationHandler().measureGroupedTaskViewThumbnailBounds(mSnapshotView,
|
||||
mSnapshotView2, widthSize, heightSize, mSplitBoundsConfig,
|
||||
mActivity.getDeviceProfile(), getLayoutDirection() == LAYOUT_DIRECTION_RTL);
|
||||
mContainer.getDeviceProfile(), getLayoutDirection() == LAYOUT_DIRECTION_RTL);
|
||||
// Should we be having a separate translation step apart from the measuring above?
|
||||
// The following only applies to large screen for now, but for future reference
|
||||
// we'd want to abstract this out in PagedViewHandlers to get the primary/secondary
|
||||
@@ -373,7 +373,7 @@ public class GroupedTaskView extends TaskView {
|
||||
container.getThumbnailView().measure(widthMeasureSpec,
|
||||
View.MeasureSpec.makeMeasureSpec(
|
||||
heightSize -
|
||||
mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx,
|
||||
mContainer.getDeviceProfile().overviewTaskThumbnailTopMarginPx,
|
||||
MeasureSpec.EXACTLY));
|
||||
}
|
||||
if (!enableOverviewIconMenu()) {
|
||||
@@ -392,7 +392,7 @@ public class GroupedTaskView extends TaskView {
|
||||
|
||||
@Override
|
||||
public void setOrientationState(RecentsOrientedState orientationState) {
|
||||
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
|
||||
DeviceProfile deviceProfile = mContainer.getDeviceProfile();
|
||||
if (enableOverviewIconMenu() && mSplitBoundsConfig != null) {
|
||||
ViewGroup.LayoutParams layoutParams = getLayoutParams();
|
||||
Pair<Point, Point> groupedTaskViewSizes =
|
||||
@@ -425,7 +425,7 @@ public class GroupedTaskView extends TaskView {
|
||||
return;
|
||||
}
|
||||
|
||||
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
|
||||
DeviceProfile deviceProfile = mContainer.getDeviceProfile();
|
||||
int taskIconHeight = deviceProfile.overviewTaskIconSizePx;
|
||||
boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
|
||||
|
||||
public LauncherRecentsView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr, LauncherActivityInterface.INSTANCE);
|
||||
mActivity.getStateManager().addStateListener(this);
|
||||
getStateManager().addStateListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,28 +85,33 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
|
||||
|
||||
@Override
|
||||
protected void handleStartHome(boolean animated) {
|
||||
StateManager stateManager = mActivity.getStateManager();
|
||||
StateManager stateManager = getStateManager();
|
||||
animated &= stateManager.shouldAnimateStateChange();
|
||||
stateManager.goToState(NORMAL, animated);
|
||||
if (FeatureFlags.enableSplitContextually()) {
|
||||
mSplitSelectStateController.getSplitAnimationController()
|
||||
.playPlaceholderDismissAnim(mActivity, LAUNCHER_SPLIT_SELECTION_EXIT_HOME);
|
||||
.playPlaceholderDismissAnim(mContainer, LAUNCHER_SPLIT_SELECTION_EXIT_HOME);
|
||||
}
|
||||
AbstractFloatingView.closeAllOpenViews(mActivity, animated);
|
||||
AbstractFloatingView.closeAllOpenViews(mContainer, animated);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canStartHomeSafely() {
|
||||
return mActivity.canStartHomeSafely();
|
||||
return mContainer.canStartHomeSafely();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateManager<LauncherState> getStateManager() {
|
||||
return mContainer.getStateManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTaskLaunchAnimationEnd(boolean success) {
|
||||
if (success) {
|
||||
mActivity.getStateManager().moveToRestState();
|
||||
getStateManager().moveToRestState();
|
||||
} else {
|
||||
LauncherState state = mActivity.getStateManager().getState();
|
||||
mActivity.getAllAppsController().setState(state);
|
||||
LauncherState state = getStateManager().getState();
|
||||
mContainer.getAllAppsController().setState(state);
|
||||
}
|
||||
super.onTaskLaunchAnimationEnd(success);
|
||||
}
|
||||
@@ -115,14 +120,14 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
|
||||
public void onTaskIconChanged(int taskId) {
|
||||
super.onTaskIconChanged(taskId);
|
||||
// If Launcher needs to return to split select state, do it now, after the icon has updated.
|
||||
if (mActivity.hasPendingSplitSelectInfo()) {
|
||||
PendingSplitSelectInfo recoveryData = mActivity.getPendingSplitSelectInfo();
|
||||
if (mContainer.hasPendingSplitSelectInfo()) {
|
||||
PendingSplitSelectInfo recoveryData = mContainer.getPendingSplitSelectInfo();
|
||||
if (recoveryData.getStagedTaskId() == taskId) {
|
||||
initiateSplitSelect(
|
||||
getTaskViewByTaskId(recoveryData.getStagedTaskId()),
|
||||
recoveryData.getStagePosition(), recoveryData.getSource()
|
||||
);
|
||||
mActivity.finishSplitSelectRecovery();
|
||||
mContainer.finishSplitSelectRecovery();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,7 +144,7 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
|
||||
public void onStateTransitionStart(LauncherState toState) {
|
||||
setOverviewStateEnabled(toState.overviewUi);
|
||||
|
||||
setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
|
||||
setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mContainer.getDeviceProfile()));
|
||||
setOverviewFullscreenEnabled(toState.getOverviewFullscreenProgress() == 1);
|
||||
if (toState == OVERVIEW_MODAL_TASK) {
|
||||
setOverviewSelectEnabled(true);
|
||||
@@ -153,8 +158,8 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
|
||||
}
|
||||
|
||||
setFreezeViewVisibility(true);
|
||||
if (mActivity.getDesktopVisibilityController() != null) {
|
||||
mActivity.getDesktopVisibilityController().onLauncherStateChanged(toState);
|
||||
if (mContainer.getDesktopVisibilityController() != null) {
|
||||
mContainer.getDesktopVisibilityController().onLauncherStateChanged(toState);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,8 +191,8 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
|
||||
public void setOverviewStateEnabled(boolean enabled) {
|
||||
super.setOverviewStateEnabled(enabled);
|
||||
if (enabled) {
|
||||
LauncherState state = mActivity.getStateManager().getState();
|
||||
boolean hasClearAllButton = (state.getVisibleElements(mActivity)
|
||||
LauncherState state = getStateManager().getState();
|
||||
boolean hasClearAllButton = (state.getVisibleElements(mContainer)
|
||||
& CLEAR_ALL_BUTTON) != 0;
|
||||
setDisallowScrollToClearAll(!hasClearAllButton);
|
||||
}
|
||||
@@ -197,30 +202,28 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
boolean result = super.onTouchEvent(ev);
|
||||
// Do not let touch escape to siblings below this view.
|
||||
return result || mActivity.getStateManager().getState().overviewUi;
|
||||
return result || getStateManager().getState().overviewUi;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DepthController getDepthController() {
|
||||
return mActivity.getDepthController();
|
||||
return mContainer.getDepthController();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModalStateEnabled(int taskId, boolean animate) {
|
||||
if (taskId != INVALID_TASK_ID) {
|
||||
setSelectedTask(taskId);
|
||||
mActivity.getStateManager().goToState(LauncherState.OVERVIEW_MODAL_TASK, animate);
|
||||
} else {
|
||||
if (mActivity.isInState(LauncherState.OVERVIEW_MODAL_TASK)) {
|
||||
mActivity.getStateManager().goToState(LauncherState.OVERVIEW, animate);
|
||||
}
|
||||
getStateManager().goToState(LauncherState.OVERVIEW_MODAL_TASK, animate);
|
||||
} else if (mContainer.isInState(LauncherState.OVERVIEW_MODAL_TASK)) {
|
||||
getStateManager().goToState(LauncherState.OVERVIEW, animate);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDismissAnimationEnds() {
|
||||
super.onDismissAnimationEnds();
|
||||
if (mActivity.isInState(OVERVIEW_SPLIT_SELECT)) {
|
||||
if (mContainer.isInState(OVERVIEW_SPLIT_SELECT)) {
|
||||
// We want to keep the tasks translations in this temporary state
|
||||
// after resetting the rest above
|
||||
setTaskViewsPrimarySplitTranslation(mTaskViewsPrimarySplitTranslation);
|
||||
@@ -233,13 +236,13 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
|
||||
@SplitConfigurationOptions.StagePosition int stagePosition,
|
||||
StatsLogManager.EventEnum splitEvent) {
|
||||
super.initiateSplitSelect(taskView, stagePosition, splitEvent);
|
||||
mActivity.getStateManager().goToState(LauncherState.OVERVIEW_SPLIT_SELECT);
|
||||
getStateManager().goToState(LauncherState.OVERVIEW_SPLIT_SELECT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initiateSplitSelect(SplitSelectSource splitSelectSource) {
|
||||
super.initiateSplitSelect(splitSelectSource);
|
||||
mActivity.getStateManager().goToState(LauncherState.OVERVIEW_SPLIT_SELECT);
|
||||
getStateManager().goToState(LauncherState.OVERVIEW_SPLIT_SELECT);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -247,7 +250,7 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
|
||||
if (FeatureFlags.enableSplitContextually()) {
|
||||
return !mSplitSelectStateController.isSplitSelectActive();
|
||||
} else {
|
||||
return !mActivity.isInState(OVERVIEW_SPLIT_SELECT);
|
||||
return !mContainer.isInState(OVERVIEW_SPLIT_SELECT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,7 +259,7 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
|
||||
RotationTouchHelper rotationTouchHelper) {
|
||||
super.onGestureAnimationStart(runningTasks, rotationTouchHelper);
|
||||
DesktopVisibilityController desktopVisibilityController =
|
||||
mActivity.getDesktopVisibilityController();
|
||||
mContainer.getDesktopVisibilityController();
|
||||
if (desktopVisibilityController != null) {
|
||||
desktopVisibilityController.setRecentsGestureStart();
|
||||
}
|
||||
@@ -265,13 +268,14 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
|
||||
@Override
|
||||
public void onGestureAnimationEnd() {
|
||||
DesktopVisibilityController desktopVisibilityController =
|
||||
mActivity.getDesktopVisibilityController();
|
||||
mContainer.getDesktopVisibilityController();
|
||||
boolean showDesktopApps = false;
|
||||
GestureState.GestureEndTarget endTarget = null;
|
||||
if (desktopVisibilityController != null) {
|
||||
desktopVisibilityController = mContainer.getDesktopVisibilityController();
|
||||
endTarget = mCurrentGestureEndTarget;
|
||||
if (endTarget == GestureState.GestureEndTarget.LAST_TASK
|
||||
&& desktopVisibilityController.areFreeformTasksVisible()) {
|
||||
&& desktopVisibilityController.areDesktopTasksVisible()) {
|
||||
// Recents gesture was cancelled and we are returning to the previous task.
|
||||
// After super class has handled clean up, show desktop apps on top again
|
||||
showDesktopApps = true;
|
||||
@@ -282,7 +286,7 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
|
||||
desktopVisibilityController.setRecentsGestureEnd(endTarget);
|
||||
}
|
||||
if (showDesktopApps) {
|
||||
SystemUiProxy.INSTANCE.get(mActivity).showDesktopApps(mActivity.getDisplayId(),
|
||||
SystemUiProxy.INSTANCE.get(mContainer).showDesktopApps(mContainer.getDisplayId(),
|
||||
null /* transition */);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,6 @@ import static com.android.quickstep.util.TaskGridNavHelper.DIRECTION_RIGHT;
|
||||
import static com.android.quickstep.util.TaskGridNavHelper.DIRECTION_TAB;
|
||||
import static com.android.quickstep.util.TaskGridNavHelper.DIRECTION_UP;
|
||||
import static com.android.quickstep.views.ClearAllButton.DISMISS_ALPHA;
|
||||
import static com.android.window.flags.Flags.enableDesktopWindowingMode;
|
||||
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_ACTIONS_IN_MENU;
|
||||
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_DESKTOP;
|
||||
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NON_ZERO_ROTATION;
|
||||
@@ -69,6 +68,7 @@ import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_RECENTS;
|
||||
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_TASKS;
|
||||
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_SPLIT_SCREEN;
|
||||
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_SPLIT_SELECT_ACTIVE;
|
||||
import static com.android.window.flags.Flags.enableDesktopWindowingMode;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
@@ -129,7 +129,6 @@ import androidx.annotation.UiThread;
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
|
||||
import com.android.internal.jank.Cuj;
|
||||
import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.BaseActivity.MultiWindowModeChangedListener;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Insettable;
|
||||
@@ -149,7 +148,7 @@ import com.android.launcher3.logging.StatsLogManager;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.statehandlers.DepthController;
|
||||
import com.android.launcher3.statemanager.BaseState;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
import com.android.launcher3.testing.TestLogging;
|
||||
import com.android.launcher3.testing.shared.TestProtocol;
|
||||
import com.android.launcher3.touch.OverScroll;
|
||||
@@ -163,10 +162,11 @@ import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.launcher3.util.TraceHelper;
|
||||
import com.android.launcher3.util.TranslateEdgeEffect;
|
||||
import com.android.launcher3.util.VibratorWrapper;
|
||||
import com.android.launcher3.util.ViewPool;
|
||||
import com.android.quickstep.BaseActivityInterface;
|
||||
import com.android.quickstep.BaseContainerInterface;
|
||||
import com.android.quickstep.GestureState;
|
||||
import com.android.quickstep.OverviewCommandHelper;
|
||||
import com.android.quickstep.RecentsAnimationController;
|
||||
@@ -226,8 +226,11 @@ import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* A list of recent tasks.
|
||||
* @param <CONTAINER_TYPE> : the container that should host recents view
|
||||
* @param <STATE_TYPE> : the type of base state that will be used
|
||||
*/
|
||||
public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_TYPE>,
|
||||
|
||||
public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewContainer,
|
||||
STATE_TYPE extends BaseState<STATE_TYPE>> extends PagedView implements Insettable,
|
||||
TaskThumbnailCache.HighResLoadingState.HighResLoadingStateChangedCallback,
|
||||
TaskVisualsChangeListener {
|
||||
@@ -443,7 +446,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
private static final float FOREGROUND_SCRIM_TINT = 0.32f;
|
||||
|
||||
protected final RecentsOrientedState mOrientationState;
|
||||
protected final BaseActivityInterface<STATE_TYPE, ACTIVITY_TYPE> mSizeStrategy;
|
||||
protected final BaseContainerInterface<STATE_TYPE, CONTAINER_TYPE> mSizeStrategy;
|
||||
@Nullable
|
||||
protected RecentsAnimationController mRecentsAnimationController;
|
||||
@Nullable
|
||||
@@ -480,7 +483,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
// The threshold at which we update the SystemUI flags when animating from the task into the app
|
||||
public static final float UPDATE_SYSUI_FLAGS_THRESHOLD = 0.85f;
|
||||
|
||||
protected final ACTIVITY_TYPE mActivity;
|
||||
protected final CONTAINER_TYPE mContainer;
|
||||
private final float mFastFlingVelocity;
|
||||
private final int mScrollHapticMinGapMillis;
|
||||
private final RecentsModel mModel;
|
||||
@@ -767,14 +770,14 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
private final RecentsFilterState mFilterState = new RecentsFilterState();
|
||||
|
||||
public RecentsView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
|
||||
BaseActivityInterface sizeStrategy) {
|
||||
BaseContainerInterface sizeStrategy) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
setEnableFreeScroll(true);
|
||||
mSizeStrategy = sizeStrategy;
|
||||
mActivity = BaseActivity.fromContext(context);
|
||||
mContainer = RecentsViewContainer.containerFromContext(context);
|
||||
mOrientationState = new RecentsOrientedState(
|
||||
context, mSizeStrategy, this::animateRecentsRotationInPlace);
|
||||
final int rotation = mActivity.getDisplay().getRotation();
|
||||
final int rotation = mContainer.getDisplay().getRotation();
|
||||
mOrientationState.setRecentsRotation(rotation);
|
||||
|
||||
mScrollHapticMinGapMillis = getResources()
|
||||
@@ -826,7 +829,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
R.string.task_overlay_factory_class);
|
||||
|
||||
// Initialize quickstep specific cache params here, as this is constructed only once
|
||||
mActivity.getViewCache().setCacheSize(R.layout.digital_wellbeing_toast, 5);
|
||||
mContainer.getViewCache().setCacheSize(R.layout.digital_wellbeing_toast, 5);
|
||||
|
||||
mTintingColor = getForegroundScrimDimColor(context);
|
||||
|
||||
@@ -834,9 +837,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
if (FeatureFlags.ENABLE_MULTI_INSTANCE.get()) {
|
||||
// invalidate the current list of tasks if filter changes with a fading in/out animation
|
||||
mFilterState.setOnFilterUpdatedListener(() -> {
|
||||
Animator animatorFade = mActivity.getStateManager().createStateElementAnimation(
|
||||
Animator animatorFade = getStateManager().createStateElementAnimation(
|
||||
RecentsAtomicAnimationFactory.INDEX_RECENTS_FADE_ANIM, 1f, 0f);
|
||||
Animator animatorAppear = mActivity.getStateManager().createStateElementAnimation(
|
||||
Animator animatorAppear = getStateManager().createStateElementAnimation(
|
||||
RecentsAtomicAnimationFactory.INDEX_RECENTS_FADE_ANIM, 0f, 1f);
|
||||
animatorFade.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
@@ -1088,13 +1091,13 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
super.onAttachedToWindow();
|
||||
updateTaskStackListenerState();
|
||||
mModel.getThumbnailCache().getHighResLoadingState().addCallback(this);
|
||||
mActivity.addMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
|
||||
mContainer.addMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
|
||||
TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
|
||||
mSyncTransactionApplier = new SurfaceTransactionApplier(this);
|
||||
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams()
|
||||
.setSyncTransactionApplier(mSyncTransactionApplier));
|
||||
RecentsModel.INSTANCE.get(getContext()).addThumbnailChangeListener(this);
|
||||
mIPipAnimationListener.setActivityAndRecentsView(mActivity, this);
|
||||
mIPipAnimationListener.setActivityAndRecentsView(mContainer, this);
|
||||
SystemUiProxy.INSTANCE.get(getContext()).setPipAnimationListener(
|
||||
mIPipAnimationListener);
|
||||
mOrientationState.initListeners();
|
||||
@@ -1109,7 +1112,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
super.onDetachedFromWindow();
|
||||
updateTaskStackListenerState();
|
||||
mModel.getThumbnailCache().getHighResLoadingState().removeCallback(this);
|
||||
mActivity.removeMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
|
||||
mContainer.removeMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
|
||||
TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
|
||||
mSyncTransactionApplier = null;
|
||||
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams()
|
||||
@@ -1249,7 +1252,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
if (taskView == null || !isTaskViewVisible(taskView)) {
|
||||
// TODO: Refine this animation.
|
||||
SurfaceTransactionApplier surfaceApplier =
|
||||
new SurfaceTransactionApplier(mActivity.getDragLayer());
|
||||
new SurfaceTransactionApplier(mContainer.getDragLayer());
|
||||
ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
|
||||
appAnimator.setDuration(RECENTS_LAUNCH_DURATION);
|
||||
appAnimator.setInterpolator(ACCELERATE_DECELERATE);
|
||||
@@ -1260,9 +1263,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
for (int i = apps.length - 1; i >= 0; --i) {
|
||||
RemoteAnimationTarget app = apps[i];
|
||||
|
||||
float dx = mActivity.getDeviceProfile().widthPx * (1 - percent) / 2
|
||||
float dx = mContainer.getDeviceProfile().widthPx * (1 - percent) / 2
|
||||
+ app.screenSpaceBounds.left * percent;
|
||||
float dy = mActivity.getDeviceProfile().heightPx * (1 - percent) / 2
|
||||
float dy = mContainer.getDeviceProfile().heightPx * (1 - percent) / 2
|
||||
+ app.screenSpaceBounds.top * percent;
|
||||
matrix.setScale(percent, percent);
|
||||
matrix.postTranslate(dx, dy);
|
||||
@@ -1294,7 +1297,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
});
|
||||
} else {
|
||||
TaskViewUtils.composeRecentsLaunchAnimator(anim, taskView, apps, wallpaper, nonApps,
|
||||
true /* launcherClosing */, mActivity.getStateManager(), this,
|
||||
true /* launcherClosing */, getStateManager(), this,
|
||||
getDepthController());
|
||||
}
|
||||
anim.start();
|
||||
@@ -1471,7 +1474,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
@Override
|
||||
protected void onPageBeginTransition() {
|
||||
super.onPageBeginTransition();
|
||||
if (!mActivity.getDeviceProfile().isTablet) {
|
||||
if (!mContainer.getDeviceProfile().isTablet) {
|
||||
mActionsView.updateDisabledFlags(OverviewActionsView.DISABLED_SCROLLING, true);
|
||||
}
|
||||
if (mOverviewStateEnabled) { // only when in overview
|
||||
@@ -1484,7 +1487,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
super.onPageEndTransition();
|
||||
ActiveGestureLog.INSTANCE.addLog(
|
||||
"onPageEndTransition: current page index updated", getNextPage());
|
||||
if (isClearAllHidden() && !mActivity.getDeviceProfile().isTablet) {
|
||||
if (isClearAllHidden() && !mContainer.getDeviceProfile().isTablet) {
|
||||
mActionsView.updateDisabledFlags(OverviewActionsView.DISABLED_SCROLLING, false);
|
||||
}
|
||||
if (getNextPage() > 0) {
|
||||
@@ -1495,7 +1498,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
@Override
|
||||
protected boolean isSignificantMove(float absoluteDelta, int pageOrientedSize) {
|
||||
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
|
||||
DeviceProfile deviceProfile = mContainer.getDeviceProfile();
|
||||
if (!deviceProfile.isTablet) {
|
||||
return super.isSignificantMove(absoluteDelta, pageOrientedSize);
|
||||
}
|
||||
@@ -1504,6 +1507,15 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
> deviceProfile.availableWidthPx * SIGNIFICANT_MOVE_SCREEN_WIDTH_PERCENTAGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
boolean intercept = super.onInterceptTouchEvent(ev);
|
||||
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
||||
Log.d("b/318590728", "onInterceptTouchEvent: " + ev);
|
||||
}
|
||||
return intercept;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
super.onTouchEvent(ev);
|
||||
@@ -1644,7 +1656,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
* required to move the running task in grid.
|
||||
*/
|
||||
public void moveRunningTaskToFront() {
|
||||
if (!mActivity.getDeviceProfile().isTablet) {
|
||||
if (!mContainer.getDeviceProfile().isTablet) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2012,9 +2024,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mInsets.set(insets);
|
||||
|
||||
// Update DeviceProfile dependant state.
|
||||
DeviceProfile dp = mActivity.getDeviceProfile();
|
||||
DeviceProfile dp = mContainer.getDeviceProfile();
|
||||
setOverviewGridEnabled(
|
||||
mActivity.getStateManager().getState().displayOverviewTasksAsGrid(dp));
|
||||
getStateManager().getState().displayOverviewTasksAsGrid(dp));
|
||||
if (enableGridOnlyOverview()) {
|
||||
mActionsView.updateHiddenFlags(HIDDEN_ACTIONS_IN_MENU, dp.isTablet);
|
||||
}
|
||||
@@ -2051,7 +2063,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
if (forceRecreateDragLayerControllers
|
||||
|| !getPagedOrientationHandler().equals(oldOrientationHandler)) {
|
||||
// Changed orientations, update controllers so they intercept accordingly.
|
||||
mActivity.getDragLayer().recreateControllers();
|
||||
mContainer.getDragLayer().recreateControllers();
|
||||
onOrientationChanged();
|
||||
resetTaskVisuals();
|
||||
}
|
||||
@@ -2083,21 +2095,21 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
// Update task size and padding that are dependent on DeviceProfile and insets.
|
||||
private void updateSizeAndPadding() {
|
||||
DeviceProfile dp = mActivity.getDeviceProfile();
|
||||
DeviceProfile dp = mContainer.getDeviceProfile();
|
||||
getTaskSize(mLastComputedTaskSize);
|
||||
mTaskWidth = mLastComputedTaskSize.width();
|
||||
mTaskHeight = mLastComputedTaskSize.height();
|
||||
|
||||
setPadding(mLastComputedTaskSize.left - mInsets.left,
|
||||
mLastComputedTaskSize.top - dp.overviewTaskThumbnailTopMarginPx - mInsets.top,
|
||||
dp.widthPx - mInsets.right - mLastComputedTaskSize.right,
|
||||
dp.heightPx - mInsets.bottom - mLastComputedTaskSize.bottom);
|
||||
|
||||
mSizeStrategy.calculateGridSize(dp, mActivity, mLastComputedGridSize);
|
||||
mSizeStrategy.calculateGridTaskSize(mActivity, dp, mLastComputedGridTaskSize,
|
||||
mSizeStrategy.calculateGridSize(dp, mContainer, mLastComputedGridSize);
|
||||
mSizeStrategy.calculateGridTaskSize(mContainer, dp, mLastComputedGridTaskSize,
|
||||
getPagedOrientationHandler());
|
||||
|
||||
if (enableGridOnlyOverview()) {
|
||||
mSizeStrategy.calculateCarouselTaskSize(mActivity, dp, mLastComputedCarouselTaskSize,
|
||||
mSizeStrategy.calculateCarouselTaskSize(mContainer, dp, mLastComputedCarouselTaskSize,
|
||||
getPagedOrientationHandler());
|
||||
}
|
||||
|
||||
@@ -2131,7 +2143,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
float accumulatedTranslationX = 0;
|
||||
float translateXToMiddle = 0;
|
||||
if (enableGridOnlyOverview() && mActivity.getDeviceProfile().isTablet) {
|
||||
if (enableGridOnlyOverview() && mContainer.getDeviceProfile().isTablet) {
|
||||
translateXToMiddle = mIsRtl
|
||||
? mLastComputedCarouselTaskSize.right - mLastComputedTaskSize.right
|
||||
: mLastComputedCarouselTaskSize.left - mLastComputedTaskSize.left;
|
||||
@@ -2153,7 +2165,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
|
||||
public void getTaskSize(Rect outRect) {
|
||||
mSizeStrategy.calculateTaskSize(mActivity, mActivity.getDeviceProfile(), outRect,
|
||||
mSizeStrategy.calculateTaskSize(mContainer, mContainer.getDeviceProfile(), outRect,
|
||||
getPagedOrientationHandler());
|
||||
}
|
||||
|
||||
@@ -2202,7 +2214,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
/** Gets the task size for modal state. */
|
||||
public void getModalTaskSize(Rect outRect) {
|
||||
mSizeStrategy.calculateModalTaskSize(mActivity, mActivity.getDeviceProfile(), outRect,
|
||||
mSizeStrategy.calculateModalTaskSize(mContainer, mContainer.getDeviceProfile(), outRect,
|
||||
getPagedOrientationHandler());
|
||||
}
|
||||
|
||||
@@ -2268,7 +2280,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
@Override
|
||||
protected int getDestinationPage(int scaledScroll) {
|
||||
if (!mActivity.getDeviceProfile().isTablet) {
|
||||
if (!mContainer.getDeviceProfile().isTablet) {
|
||||
return super.getDestinationPage(scaledScroll);
|
||||
}
|
||||
if (!isPageScrollsInitialized()) {
|
||||
@@ -2418,7 +2430,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
|
||||
public void startHome() {
|
||||
startHome(mActivity.isStarted());
|
||||
startHome(mContainer.isStarted());
|
||||
}
|
||||
|
||||
public void startHome(boolean animated) {
|
||||
@@ -2431,6 +2443,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
/** Returns whether user can start home based on state in {@link OverviewCommandHelper}. */
|
||||
protected abstract boolean canStartHomeSafely();
|
||||
|
||||
public abstract StateManager<STATE_TYPE> getStateManager();
|
||||
|
||||
public void reset() {
|
||||
setCurrentTask(-1);
|
||||
mCurrentPageScrollDiff = 0;
|
||||
@@ -2570,6 +2584,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
*/
|
||||
public void onGestureAnimationStart(
|
||||
Task[] runningTasks, RotationTouchHelper rotationTouchHelper) {
|
||||
Log.d(TAG, "onGestureAnimationStart");
|
||||
mActiveGestureRunningTasks = runningTasks;
|
||||
// This needs to be called before the other states are set since it can create the task view
|
||||
if (mOrientationState.setGestureActive(true)) {
|
||||
@@ -2608,7 +2623,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
AnimatorSet pa = setRecentsChangedOrientation(true);
|
||||
pa.addListener(AnimatorListeners.forSuccessCallback(() -> {
|
||||
setLayoutRotation(newRotation, mOrientationState.getDisplayRotation());
|
||||
mActivity.getDragLayer().recreateControllers();
|
||||
mContainer.getDragLayer().recreateControllers();
|
||||
setRecentsChangedOrientation(false).start();
|
||||
}));
|
||||
pa.start();
|
||||
@@ -2637,7 +2652,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
if (!shouldRotateMenuForFakeRotation) {
|
||||
return;
|
||||
}
|
||||
TaskMenuView tv = (TaskMenuView) getTopOpenViewWithType(mActivity, TYPE_TASK_MENU);
|
||||
TaskMenuView tv = (TaskMenuView) getTopOpenViewWithType(mContainer, TYPE_TASK_MENU);
|
||||
if (tv != null) {
|
||||
// Rotation is supported on phone (details at b/254198019#comment4)
|
||||
tv.onRotationChanged();
|
||||
@@ -2658,7 +2673,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
|
||||
BaseState<?> endState = mSizeStrategy.stateFromGestureEndTarget(endTarget);
|
||||
if (endState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile())) {
|
||||
if (endState.displayOverviewTasksAsGrid(mContainer.getDeviceProfile())) {
|
||||
TaskView runningTaskView = getRunningTaskView();
|
||||
float runningTaskPrimaryGridTranslation = 0;
|
||||
float runningTaskSecondaryGridTranslation = 0;
|
||||
@@ -2921,7 +2936,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
return;
|
||||
}
|
||||
|
||||
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
|
||||
DeviceProfile deviceProfile = mContainer.getDeviceProfile();
|
||||
int taskTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
|
||||
|
||||
int topRowWidth = 0;
|
||||
@@ -3245,7 +3260,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
int secondaryTaskDimension = getPagedOrientationHandler().getSecondaryDimension(taskView);
|
||||
int verticalFactor = getPagedOrientationHandler().getSecondaryTranslationDirectionFactor();
|
||||
|
||||
ResourceProvider rp = DynamicResource.provider(mActivity);
|
||||
ResourceProvider rp = DynamicResource.provider(mContainer);
|
||||
SpringProperty sp = new SpringProperty(SpringProperty.FLAG_CAN_SPRING_ON_START)
|
||||
.setDampingRatio(rp.getFloat(R.dimen.dismiss_task_trans_y_damping_ratio))
|
||||
.setStiffness(rp.getFloat(R.dimen.dismiss_task_trans_y_stiffness));
|
||||
@@ -3273,10 +3288,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
*/
|
||||
private void createInitialSplitSelectAnimation(PendingAnimation anim) {
|
||||
getPagedOrientationHandler().getInitialSplitPlaceholderBounds(mSplitPlaceholderSize,
|
||||
mSplitPlaceholderInset, mActivity.getDeviceProfile(),
|
||||
mSplitPlaceholderInset, mContainer.getDeviceProfile(),
|
||||
mSplitSelectStateController.getActiveSplitStagePosition(), mTempRect);
|
||||
SplitAnimationTimings timings =
|
||||
AnimUtils.getDeviceOverviewToSplitTimings(mActivity.getDeviceProfile().isTablet);
|
||||
AnimUtils.getDeviceOverviewToSplitTimings(mContainer.getDeviceProfile().isTablet);
|
||||
|
||||
RectF startingTaskRect = new RectF();
|
||||
safeRemoveDragLayerView(mSplitSelectStateController.getFirstFloatingTaskView());
|
||||
@@ -3292,7 +3307,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
timings.getIconFadeEndOffset()));
|
||||
}
|
||||
|
||||
FloatingTaskView firstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
|
||||
FloatingTaskView firstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mContainer,
|
||||
splitAnimInitProps.getOriginalView(),
|
||||
splitAnimInitProps.getOriginalBitmap(),
|
||||
splitAnimInitProps.getIconDrawable(), startingTaskRect);
|
||||
@@ -3304,13 +3319,13 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
// Allow user to click staged app to launch into fullscreen
|
||||
firstFloatingTaskView.setOnClickListener(view ->
|
||||
mSplitSelectStateController.getSplitAnimationController().
|
||||
playAnimPlaceholderToFullscreen(mActivity, view,
|
||||
playAnimPlaceholderToFullscreen(mContainer, view,
|
||||
Optional.of(() -> resetFromSplitSelectionState())));
|
||||
|
||||
// SplitInstructionsView: animate in
|
||||
safeRemoveDragLayerView(mSplitSelectStateController.getSplitInstructionsView());
|
||||
SplitInstructionsView splitInstructionsView =
|
||||
SplitInstructionsView.getSplitInstructionsView(mActivity);
|
||||
SplitInstructionsView.getSplitInstructionsView(mContainer);
|
||||
splitInstructionsView.setAlpha(0);
|
||||
anim.setViewAlpha(splitInstructionsView, 1, clampToProgress(LINEAR,
|
||||
timings.getInstructionsContainerFadeInStartOffset(),
|
||||
@@ -3436,7 +3451,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
boolean isClearAllHidden = isClearAllHidden();
|
||||
boolean snapToLastTask = false;
|
||||
boolean isLeftRightSplit =
|
||||
mActivity.getDeviceProfile().isLeftRightSplit && isSplitSelectionActive();
|
||||
mContainer.getDeviceProfile().isLeftRightSplit && isSplitSelectionActive();
|
||||
TaskView lastGridTaskView = showAsGrid ? getLastGridTaskView() : null;
|
||||
int currentPageScroll = getScrollForPage(mCurrentPage);
|
||||
int lastGridTaskScroll = getScrollForPage(indexOfChild(lastGridTaskView));
|
||||
@@ -3481,7 +3496,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
// and adjust accordingly to the new shortTotalCompensation after dismiss.
|
||||
int newClearAllShortTotalWidthTranslation = 0;
|
||||
if (longRowWidth < mLastComputedGridSize.width()) {
|
||||
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
|
||||
DeviceProfile deviceProfile = mContainer.getDeviceProfile();
|
||||
newClearAllShortTotalWidthTranslation =
|
||||
(mIsRtl
|
||||
? mLastComputedTaskSize.right
|
||||
@@ -3568,7 +3583,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
|
||||
SplitAnimationTimings splitTimings =
|
||||
AnimUtils.getDeviceOverviewToSplitTimings(mActivity.getDeviceProfile().isTablet);
|
||||
AnimUtils.getDeviceOverviewToSplitTimings(mContainer.getDeviceProfile().isTablet);
|
||||
|
||||
int distanceFromDismissedTask = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
@@ -3777,7 +3792,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
announceForAccessibility(
|
||||
getResources().getString(R.string.task_view_closed));
|
||||
mActivity.getStatsLogManager().logger()
|
||||
mContainer.getStatsLogManager().logger()
|
||||
.withItemInfo(dismissedTaskView.getItemInfo())
|
||||
.log(LAUNCHER_TASK_DISMISS_SWIPE_UP);
|
||||
}
|
||||
@@ -3943,7 +3958,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
// Update various scroll-dependent UI.
|
||||
dispatchScrollChanged();
|
||||
updateActionsViewFocusedScroll();
|
||||
if (isClearAllHidden() && !mActivity.getDeviceProfile().isTablet) {
|
||||
if (isClearAllHidden() && !mContainer.getDeviceProfile().isTablet) {
|
||||
mActionsView.updateDisabledFlags(OverviewActionsView.DISABLED_SCROLLING,
|
||||
false);
|
||||
}
|
||||
@@ -4165,7 +4180,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
@SuppressWarnings("unused")
|
||||
private void dismissAllTasks(View view) {
|
||||
runDismissAnimation(createAllTasksDismissAnimation(DISMISS_TASK_DURATION));
|
||||
mActivity.getStatsLogManager().logger().log(LAUNCHER_TASK_CLEAR_ALL);
|
||||
mContainer.getStatsLogManager().logger().log(LAUNCHER_TASK_CLEAR_ALL);
|
||||
}
|
||||
|
||||
private void dismissCurrentTask() {
|
||||
@@ -4294,7 +4309,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
* Updates {@link RecentsOrientedState}'s cached RecentsView rotation.
|
||||
*/
|
||||
public void updateRecentsRotation() {
|
||||
final int rotation = mActivity.getDisplay().getRotation();
|
||||
final int rotation = TraceHelper.allowIpcs(
|
||||
"RecentsView.updateRecentsRotation", () -> mContainer.getDisplay().getRotation());
|
||||
mOrientationState.setRecentsRotation(rotation);
|
||||
}
|
||||
|
||||
@@ -4408,14 +4424,14 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
} else {
|
||||
// Only update pivot when it is tablet and not in grid yet, so the pivot is correct
|
||||
// for non-current tasks when swiping up to overview
|
||||
if (enableGridOnlyOverview() && mActivity.getDeviceProfile().isTablet
|
||||
if (enableGridOnlyOverview() && mContainer.getDeviceProfile().isTablet
|
||||
&& !mOverviewGridEnabled) {
|
||||
mTempRect.set(mLastComputedCarouselTaskSize);
|
||||
} else {
|
||||
mTempRect.set(mLastComputedTaskSize);
|
||||
}
|
||||
getPagedViewOrientedState().getFullScreenScaleAndPivot(mTempRect,
|
||||
mActivity.getDeviceProfile(), mTempPointF);
|
||||
mContainer.getDeviceProfile(), mTempPointF);
|
||||
}
|
||||
setPivotX(mTempPointF.x);
|
||||
setPivotY(mTempPointF.y);
|
||||
@@ -4515,7 +4531,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
TaskView taskView = (TaskView) child;
|
||||
outRect.offset(taskView.getPersistentTranslationX(),
|
||||
taskView.getPersistentTranslationY());
|
||||
outRect.top += mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
|
||||
outRect.top += mContainer.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
|
||||
|
||||
mTempMatrix.reset();
|
||||
float persistentScale = taskView.getPersistentScale();
|
||||
@@ -4627,7 +4643,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
if (isTopShift) {
|
||||
distanceToOffscreen = -taskPosition.bottom;
|
||||
} else if (isBottomShift) {
|
||||
distanceToOffscreen = mActivity.getDeviceProfile().heightPx - taskPosition.top;
|
||||
distanceToOffscreen = mContainer.getDeviceProfile().heightPx - taskPosition.top;
|
||||
}
|
||||
return distanceToOffscreen * offsetProgress;
|
||||
}
|
||||
@@ -4683,7 +4699,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
*/
|
||||
public void initiateSplitSelect(TaskView taskView) {
|
||||
int defaultSplitPosition = getPagedOrientationHandler()
|
||||
.getDefaultSplitPosition(mActivity.getDeviceProfile());
|
||||
.getDefaultSplitPosition(mContainer.getDeviceProfile());
|
||||
initiateSplitSelect(taskView, defaultSplitPosition, LAUNCHER_OVERVIEW_ACTIONS_SPLIT);
|
||||
}
|
||||
|
||||
@@ -4748,7 +4764,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
TaskThumbnailView thumbnail = taskIdAttributeContainer.getThumbnailView();
|
||||
mSplitSelectStateController.getSplitAnimationController()
|
||||
.addInitialSplitFromPair(taskIdAttributeContainer, builder,
|
||||
mActivity.getDeviceProfile(),
|
||||
mContainer.getDeviceProfile(),
|
||||
mSplitHiddenTaskView.getWidth(), mSplitHiddenTaskView.getHeight(),
|
||||
primaryTaskSelected);
|
||||
builder.addOnFrameCallback(() ->{
|
||||
@@ -4816,14 +4832,14 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
Rect firstTaskStartingBounds = new Rect();
|
||||
Rect firstTaskEndingBounds = mTempRect;
|
||||
|
||||
boolean isTablet = mActivity.getDeviceProfile().isTablet;
|
||||
boolean isTablet = mContainer.getDeviceProfile().isTablet;
|
||||
SplitAnimationTimings timings = AnimUtils.getDeviceSplitToConfirmTimings(isTablet);
|
||||
PendingAnimation pendingAnimation = new PendingAnimation(timings.getDuration());
|
||||
|
||||
int halfDividerSize = getResources()
|
||||
.getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2;
|
||||
getPagedOrientationHandler().getFinalSplitPlaceholderBounds(halfDividerSize,
|
||||
mActivity.getDeviceProfile(),
|
||||
mContainer.getDeviceProfile(),
|
||||
mSplitSelectStateController.getActiveSplitStagePosition(), firstTaskEndingBounds,
|
||||
secondTaskEndingBounds);
|
||||
|
||||
@@ -4836,7 +4852,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
safeRemoveDragLayerView(mSecondFloatingTaskView);
|
||||
|
||||
mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity, secondView,
|
||||
mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mContainer, secondView,
|
||||
thumbnail, drawable, secondTaskStartingBounds);
|
||||
mSecondFloatingTaskView.setAlpha(1);
|
||||
mSecondFloatingTaskView.addConfirmAnimation(pendingAnimation, secondTaskStartingBounds,
|
||||
@@ -4884,7 +4900,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mSecondFloatingTaskView = null;
|
||||
mSplitSelectSource = null;
|
||||
mSplitSelectStateController.getSplitAnimationController()
|
||||
.removeSplitInstructionsView(mActivity);
|
||||
.removeSplitInstructionsView(mContainer);
|
||||
}
|
||||
|
||||
if (mSecondSplitHiddenView != null) {
|
||||
@@ -4905,7 +4921,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
if (mSplitHiddenTaskViewIndex == -1) {
|
||||
return;
|
||||
}
|
||||
if (!mActivity.getDeviceProfile().isTablet) {
|
||||
if (!mContainer.getDeviceProfile().isTablet) {
|
||||
int pageToSnapTo = mCurrentPage;
|
||||
if (mSplitHiddenTaskViewIndex <= pageToSnapTo) {
|
||||
pageToSnapTo += 1;
|
||||
@@ -4927,7 +4943,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
private void safeRemoveDragLayerView(@Nullable View viewToRemove) {
|
||||
if (viewToRemove != null) {
|
||||
mActivity.getDragLayer().removeView(viewToRemove);
|
||||
mContainer.getDragLayer().removeView(viewToRemove);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4936,11 +4952,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
* Note that the translation can be its primary or secondary dimension.
|
||||
*/
|
||||
public float getSplitSelectTranslation() {
|
||||
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
|
||||
DeviceProfile deviceProfile = mContainer.getDeviceProfile();
|
||||
RecentsPagedOrientationHandler orientationHandler = getPagedOrientationHandler();
|
||||
int splitPosition = getSplitSelectController().getActiveSplitStagePosition();
|
||||
int splitPlaceholderSize =
|
||||
mActivity.getResources().getDimensionPixelSize(R.dimen.split_placeholder_size);
|
||||
mContainer.getResources().getDimensionPixelSize(R.dimen.split_placeholder_size);
|
||||
int direction = orientationHandler.getSplitTranslationDirectionFactor(
|
||||
splitPosition, deviceProfile);
|
||||
|
||||
@@ -4963,7 +4979,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
protected void onRotateInSplitSelectionState() {
|
||||
getPagedOrientationHandler().getInitialSplitPlaceholderBounds(mSplitPlaceholderSize,
|
||||
mSplitPlaceholderInset, mActivity.getDeviceProfile(),
|
||||
mSplitPlaceholderInset, mContainer.getDeviceProfile(),
|
||||
mSplitSelectStateController.getActiveSplitStagePosition(), mTempRect);
|
||||
mTempRectF.set(mTempRect);
|
||||
FloatingTaskView firstFloatingTaskView =
|
||||
@@ -4975,7 +4991,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
Pair<FloatProperty<RecentsView>, FloatProperty<RecentsView>> taskViewsFloat =
|
||||
orientationHandler.getSplitSelectTaskOffset(
|
||||
TASK_PRIMARY_SPLIT_TRANSLATION, TASK_SECONDARY_SPLIT_TRANSLATION,
|
||||
mActivity.getDeviceProfile());
|
||||
mContainer.getDeviceProfile());
|
||||
taskViewsFloat.first.set(this, getSplitSelectTranslation());
|
||||
taskViewsFloat.second.set(this, 0f);
|
||||
|
||||
@@ -5108,10 +5124,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
* Returns the scale up required on the view, so that it coves the screen completely
|
||||
*/
|
||||
public float getMaxScaleForFullScreen() {
|
||||
if (enableGridOnlyOverview() && mActivity.getDeviceProfile().isTablet
|
||||
if (enableGridOnlyOverview() && mContainer.getDeviceProfile().isTablet
|
||||
&& !mOverviewGridEnabled) {
|
||||
if (mLastComputedCarouselTaskSize.isEmpty()) {
|
||||
mSizeStrategy.calculateCarouselTaskSize(mActivity, mActivity.getDeviceProfile(),
|
||||
mSizeStrategy.calculateCarouselTaskSize(mContainer, mContainer.getDeviceProfile(),
|
||||
mLastComputedCarouselTaskSize, getPagedOrientationHandler());
|
||||
}
|
||||
mTempRect.set(mLastComputedCarouselTaskSize);
|
||||
@@ -5122,7 +5138,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mTempRect.set(mLastComputedTaskSize);
|
||||
}
|
||||
return getPagedViewOrientedState().getFullScreenScaleAndPivot(
|
||||
mTempRect, mActivity.getDeviceProfile(), mTempPointF);
|
||||
mTempRect, mContainer.getDeviceProfile(), mTempPointF);
|
||||
}
|
||||
|
||||
public PendingAnimation createTaskLaunchAnimation(
|
||||
@@ -5148,10 +5164,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
// Once we pass a certain threshold, update the sysui flags to match the target
|
||||
// tasks' flags
|
||||
if (animator.getAnimatedFraction() > UPDATE_SYSUI_FLAGS_THRESHOLD) {
|
||||
mActivity.getSystemUiController().updateUiState(
|
||||
mContainer.getSystemUiController().updateUiState(
|
||||
UI_STATE_FULLSCREEN_TASK, targetSysUiFlags);
|
||||
} else {
|
||||
mActivity.getSystemUiController().updateUiState(UI_STATE_FULLSCREEN_TASK, 0);
|
||||
mContainer.getSystemUiController().updateUiState(UI_STATE_FULLSCREEN_TASK, 0);
|
||||
}
|
||||
|
||||
// Passing the threshold from taskview to fullscreen app will vibrate
|
||||
@@ -5173,7 +5189,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
DepthController depthController = getDepthController();
|
||||
if (depthController != null) {
|
||||
ObjectAnimator depthAnimator = ObjectAnimator.ofFloat(depthController.stateDepth,
|
||||
MULTI_PROPERTY_VALUE, BACKGROUND_APP.getDepth(mActivity));
|
||||
MULTI_PROPERTY_VALUE, BACKGROUND_APP.getDepth(mContainer));
|
||||
anim.play(depthAnimator);
|
||||
}
|
||||
anim.play(ObjectAnimator.ofFloat(this, TASK_THUMBNAIL_SPLASH_ALPHA, 0f, 1f));
|
||||
@@ -5206,7 +5222,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
Task task = tv.getTask();
|
||||
if (task != null) {
|
||||
mActivity.getStatsLogManager().logger().withItemInfo(tv.getItemInfo())
|
||||
mContainer.getStatsLogManager().logger().withItemInfo(tv.getItemInfo())
|
||||
.log(LAUNCHER_TASK_LAUNCH_SWIPE_DOWN);
|
||||
}
|
||||
} else {
|
||||
@@ -5333,7 +5349,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
TaskViewSimulator tvs = remoteTargetHandle.getTaskViewSimulator();
|
||||
tvs.setOrientationState(mOrientationState);
|
||||
tvs.setDp(mActivity.getDeviceProfile());
|
||||
tvs.setDp(mContainer.getDeviceProfile());
|
||||
tvs.recentsViewScale.value = 1;
|
||||
});
|
||||
|
||||
@@ -5388,7 +5404,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
// Notify the SysUI to use fade-in animation when entering PiP from live tile.
|
||||
final SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.get(getContext());
|
||||
systemUiProxy.setPipAnimationTypeToAlpha();
|
||||
systemUiProxy.setShelfHeight(true, mActivity.getDeviceProfile().hotseatBarSizePx);
|
||||
systemUiProxy.setShelfHeight(true, mContainer.getDeviceProfile().hotseatBarSizePx);
|
||||
// Transaction to hide the task to avoid flicker for entering PiP from split-screen.
|
||||
// See also {@link AbsSwipeUpHandler#maybeFinishSwipeToHome}.
|
||||
PictureInPictureSurfaceTransaction tx =
|
||||
@@ -5414,6 +5430,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
* Called when a running recents animation has finished or canceled.
|
||||
*/
|
||||
public void onRecentsAnimationComplete() {
|
||||
Log.d(TAG, "onRecentsAnimationComplete - mRecentsAnimationController: "
|
||||
+ mRecentsAnimationController);
|
||||
// At this point, the recents animation is not running and if the animation was canceled
|
||||
// by a display rotation then reset this state to show the screenshot
|
||||
setRunningTaskViewShowScreenshot(true);
|
||||
@@ -5457,7 +5475,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
protected int getClearAllExtraPageSpacing() {
|
||||
return showAsGrid()
|
||||
? Math.max(mActivity.getDeviceProfile().overviewGridSideMargin - mPageSpacing, 0)
|
||||
? Math.max(mContainer.getDeviceProfile().overviewGridSideMargin - mPageSpacing, 0)
|
||||
: 0;
|
||||
}
|
||||
|
||||
@@ -5906,7 +5924,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
return mTaskOverlayFactory;
|
||||
}
|
||||
|
||||
public BaseActivityInterface getSizeStrategy() {
|
||||
public BaseContainerInterface getSizeStrategy() {
|
||||
return mSizeStrategy;
|
||||
}
|
||||
|
||||
@@ -5938,7 +5956,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
requireTaskViewAt(i).setColorTint(mColorTint, mTintingColor);
|
||||
}
|
||||
|
||||
Drawable scrimBg = mActivity.getScrimView().getBackground();
|
||||
Drawable scrimBg = mContainer.getScrimView().getBackground();
|
||||
if (scrimBg != null) {
|
||||
if (tintAmount == 0f) {
|
||||
scrimBg.setTintList(null);
|
||||
@@ -5957,8 +5975,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
/** Returns {@code true} if the overview tasks are displayed as a grid. */
|
||||
public boolean showAsGrid() {
|
||||
return mOverviewGridEnabled || (mCurrentGestureEndTarget != null
|
||||
&& mSizeStrategy.stateFromGestureEndTarget(
|
||||
mCurrentGestureEndTarget).displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
|
||||
&& mSizeStrategy.stateFromGestureEndTarget(mCurrentGestureEndTarget)
|
||||
.displayOverviewTasksAsGrid(mContainer.getDeviceProfile()));
|
||||
}
|
||||
|
||||
private boolean showAsFullscreen() {
|
||||
@@ -6124,7 +6142,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
}
|
||||
|
||||
private static class PinnedStackAnimationListener<T extends BaseActivity> extends
|
||||
private static class PinnedStackAnimationListener<T extends RecentsViewContainer> extends
|
||||
IPipAnimationListener.Stub {
|
||||
@Nullable
|
||||
private T mActivity;
|
||||
@@ -6190,7 +6208,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
public void updateLocusId() {
|
||||
String locusId = "Overview";
|
||||
|
||||
if (mOverviewStateEnabled && mActivity.isStarted()) {
|
||||
if (mOverviewStateEnabled && mContainer.isStarted()) {
|
||||
locusId += "|ENABLED";
|
||||
} else {
|
||||
locusId += "|DISABLED";
|
||||
@@ -6198,7 +6216,28 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
final LocusId id = new LocusId(locusId);
|
||||
// Set locus context is a binder call, don't want it to happen during a transition
|
||||
UI_HELPER_EXECUTOR.post(() -> mActivity.setLocusContext(id, Bundle.EMPTY));
|
||||
UI_HELPER_EXECUTOR.post(() -> mContainer.setLocusContext(id, Bundle.EMPTY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the provided task into desktop mode, and invoke {@code successCallback} if succeeded.
|
||||
*/
|
||||
public void moveTaskToDesktop(TaskIdAttributeContainer taskContainer,
|
||||
Runnable successCallback) {
|
||||
if (!enableDesktopWindowingMode()) {
|
||||
return;
|
||||
}
|
||||
switchToScreenshot(() -> finishRecentsAnimation(/* toRecents= */true, /* shouldPip= */false,
|
||||
() -> moveTaskToDesktopInternal(taskContainer, successCallback)));
|
||||
}
|
||||
|
||||
private void moveTaskToDesktopInternal(TaskIdAttributeContainer taskContainer,
|
||||
Runnable successCallback) {
|
||||
if (mDesktopRecentsTransitionController == null) {
|
||||
return;
|
||||
}
|
||||
mDesktopRecentsTransitionController.moveToDesktop(taskContainer.getTask().key.id);
|
||||
successCallback.run();
|
||||
}
|
||||
|
||||
public interface TaskLaunchListener {
|
||||
|
||||
@@ -43,6 +43,7 @@ import com.android.launcher3.statemanager.BaseState;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
|
||||
import com.android.quickstep.util.SplitSelectStateController;
|
||||
|
||||
/**
|
||||
@@ -57,7 +58,7 @@ public class SplitInstructionsView extends LinearLayout {
|
||||
private static final float BOUNCE_HEIGHT = 20;
|
||||
private static final int DURATION_DEFAULT_SPLIT_DISMISS = 350;
|
||||
|
||||
private final StatefulActivity mLauncher;
|
||||
private final RecentsViewContainer mContainer;
|
||||
public boolean mIsCurrentlyAnimating = false;
|
||||
|
||||
public static final FloatProperty<SplitInstructionsView> UNFOLD =
|
||||
@@ -96,13 +97,13 @@ public class SplitInstructionsView extends LinearLayout {
|
||||
|
||||
public SplitInstructionsView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
mLauncher = (StatefulActivity) context;
|
||||
mContainer = RecentsViewContainer.containerFromContext(context);
|
||||
}
|
||||
|
||||
public static SplitInstructionsView getSplitInstructionsView(StatefulActivity launcher) {
|
||||
ViewGroup dragLayer = launcher.getDragLayer();
|
||||
public static SplitInstructionsView getSplitInstructionsView(RecentsViewContainer container) {
|
||||
ViewGroup dragLayer = container.getDragLayer();
|
||||
final SplitInstructionsView splitInstructionsView =
|
||||
(SplitInstructionsView) launcher.getLayoutInflater().inflate(
|
||||
(SplitInstructionsView) container.getLayoutInflater().inflate(
|
||||
R.layout.split_instructions_view,
|
||||
dragLayer,
|
||||
false
|
||||
@@ -139,12 +140,12 @@ public class SplitInstructionsView extends LinearLayout {
|
||||
}
|
||||
|
||||
private void exitSplitSelection() {
|
||||
SplitSelectStateController splitSelectController =
|
||||
((RecentsView) mLauncher.getOverviewPanel()).getSplitSelectController();
|
||||
RecentsView recentsView = mContainer.getOverviewPanel();
|
||||
SplitSelectStateController splitSelectController = recentsView.getSplitSelectController();
|
||||
|
||||
StateManager stateManager = mLauncher.getStateManager();
|
||||
StateManager stateManager = recentsView.getStateManager();
|
||||
BaseState startState = stateManager.getState();
|
||||
long duration = startState.getTransitionDuration(mLauncher, false);
|
||||
long duration = startState.getTransitionDuration(mContainer.asContext(), false);
|
||||
if (duration == 0) {
|
||||
// Case where we're in contextual on workspace (NORMAL), which by default has 0
|
||||
// transition duration
|
||||
@@ -155,7 +156,7 @@ public class SplitInstructionsView extends LinearLayout {
|
||||
AnimatorSet stateAnim = stateManager.createAtomicAnimation(
|
||||
startState, NORMAL, config);
|
||||
AnimatorSet dismissAnim = splitSelectController.getSplitAnimationController()
|
||||
.createPlaceholderDismissAnim(mLauncher,
|
||||
.createPlaceholderDismissAnim(mContainer,
|
||||
LAUNCHER_SPLIT_SELECTION_EXIT_CANCEL_BUTTON, duration);
|
||||
stateAnim.play(dismissAnim);
|
||||
stateManager.setCurrentAnimation(stateAnim, NORMAL);
|
||||
@@ -163,10 +164,10 @@ public class SplitInstructionsView extends LinearLayout {
|
||||
}
|
||||
|
||||
void ensureProperRotation() {
|
||||
((RecentsView) mLauncher.getOverviewPanel()).getPagedOrientationHandler()
|
||||
((RecentsView) mContainer.getOverviewPanel()).getPagedOrientationHandler()
|
||||
.setSplitInstructionsParams(
|
||||
this,
|
||||
mLauncher.getDeviceProfile(),
|
||||
mContainer.getDeviceProfile(),
|
||||
getMeasuredHeight(),
|
||||
getMeasuredWidth()
|
||||
);
|
||||
|
||||
@@ -46,7 +46,6 @@ import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.app.animation.Interpolators;
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
@@ -69,7 +68,7 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
private static final int REVEAL_OPEN_DURATION = enableOverviewIconMenu() ? 417 : 150;
|
||||
private static final int REVEAL_CLOSE_DURATION = enableOverviewIconMenu() ? 333 : 100;
|
||||
|
||||
private BaseDraggingActivity mActivity;
|
||||
private RecentsViewContainer mContainer;
|
||||
private TextView mTaskName;
|
||||
@Nullable
|
||||
private AnimatorSet mOpenCloseAnimator;
|
||||
@@ -89,7 +88,7 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
public TaskMenuView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
|
||||
mActivity = BaseDraggingActivity.fromContext(context);
|
||||
mContainer = RecentsViewContainer.containerFromContext(context);
|
||||
setClipToOutline(true);
|
||||
}
|
||||
|
||||
@@ -103,7 +102,7 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
@Override
|
||||
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
|
||||
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
BaseDragLayer dl = mActivity.getDragLayer();
|
||||
BaseDragLayer dl = mContainer.getDragLayer();
|
||||
if (!dl.isEventOverView(this, ev)) {
|
||||
// TODO: log this once we have a new container type for it?
|
||||
close(true);
|
||||
@@ -141,7 +140,7 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
if (!(enableOverviewIconMenu()
|
||||
&& ((RecentsView) mActivity.getOverviewPanel()).isOnGridBottomRow(mTaskView))) {
|
||||
&& ((RecentsView) mContainer.getOverviewPanel()).isOnGridBottomRow(mTaskView))) {
|
||||
// TODO(b/326952853): Cap menu height for grid bottom row in a way that doesn't break
|
||||
// additionalTranslationY.
|
||||
int maxMenuHeight = calculateMaxHeight();
|
||||
@@ -166,10 +165,10 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
|
||||
public static boolean showForTask(TaskIdAttributeContainer taskContainer,
|
||||
@Nullable Runnable onClosingStartCallback) {
|
||||
BaseDraggingActivity activity = BaseDraggingActivity.fromContext(
|
||||
RecentsViewContainer container = RecentsViewContainer.containerFromContext(
|
||||
taskContainer.getTaskView().getContext());
|
||||
final TaskMenuView taskMenuView = (TaskMenuView) activity.getLayoutInflater().inflate(
|
||||
R.layout.task_menu, activity.getDragLayer(), false);
|
||||
final TaskMenuView taskMenuView = (TaskMenuView) container.getLayoutInflater().inflate(
|
||||
R.layout.task_menu, container.getDragLayer(), false);
|
||||
taskMenuView.setOnClosingStartCallback(onClosingStartCallback);
|
||||
return taskMenuView.populateAndShowForTask(taskContainer);
|
||||
}
|
||||
@@ -182,7 +181,7 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
if (isAttachedToWindow()) {
|
||||
return false;
|
||||
}
|
||||
mActivity.getDragLayer().addView(this);
|
||||
mContainer.getDragLayer().addView(this);
|
||||
mTaskView = taskContainer.getTaskView();
|
||||
mTaskContainer = taskContainer;
|
||||
if (!populateAndLayoutMenu()) {
|
||||
@@ -215,7 +214,7 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
}
|
||||
|
||||
private void addMenuOption(SystemShortcut menuOption) {
|
||||
LinearLayout menuOptionView = (LinearLayout) mActivity.getLayoutInflater().inflate(
|
||||
LinearLayout menuOptionView = (LinearLayout) mContainer.getLayoutInflater().inflate(
|
||||
R.layout.task_view_menu_option, this, false);
|
||||
if (enableOverviewIconMenu()) {
|
||||
((GradientDrawable) menuOptionView.getBackground()).setCornerRadius(0);
|
||||
@@ -224,7 +223,7 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
menuOptionView.findViewById(R.id.icon), menuOptionView.findViewById(R.id.text));
|
||||
LayoutParams lp = (LayoutParams) menuOptionView.getLayoutParams();
|
||||
mTaskView.getPagedOrientationHandler().setLayoutParamsForTaskMenuOptionItem(lp,
|
||||
menuOptionView, mActivity.getDeviceProfile());
|
||||
menuOptionView, mContainer.getDeviceProfile());
|
||||
// Set an onClick listener on each menu option. The onClick method is responsible for
|
||||
// ending LiveTile mode on the thumbnail if needed.
|
||||
menuOptionView.setOnClickListener(menuOption::onClick);
|
||||
@@ -232,19 +231,19 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
}
|
||||
|
||||
private void orientAroundTaskView(TaskIdAttributeContainer taskContainer) {
|
||||
RecentsView recentsView = mActivity.getOverviewPanel();
|
||||
RecentsView recentsView = mContainer.getOverviewPanel();
|
||||
RecentsPagedOrientationHandler orientationHandler =
|
||||
recentsView.getPagedOrientationHandler();
|
||||
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
|
||||
|
||||
// Get Position
|
||||
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
|
||||
mActivity.getDragLayer().getDescendantRectRelativeToSelf(
|
||||
DeviceProfile deviceProfile = mContainer.getDeviceProfile();
|
||||
mContainer.getDragLayer().getDescendantRectRelativeToSelf(
|
||||
enableOverviewIconMenu()
|
||||
? getIconView().findViewById(R.id.icon_view_menu_anchor)
|
||||
: taskContainer.getThumbnailView(),
|
||||
sTempRect);
|
||||
Rect insets = mActivity.getDragLayer().getInsets();
|
||||
Rect insets = mContainer.getDragLayer().getInsets();
|
||||
BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) getLayoutParams();
|
||||
params.width = orientationHandler.getTaskMenuWidth(taskContainer.getThumbnailView(),
|
||||
deviceProfile, taskContainer.getStagePosition());
|
||||
@@ -325,12 +324,12 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
IconAppChipView iconAppChip = (IconAppChipView) mTaskContainer.getIconView().asView();
|
||||
|
||||
float additionalTranslationY = 0;
|
||||
if (((RecentsView) mActivity.getOverviewPanel()).isOnGridBottomRow(mTaskView)) {
|
||||
if (((RecentsView) mContainer.getOverviewPanel()).isOnGridBottomRow(mTaskView)) {
|
||||
// Animate menu up for enough room to display full menu when task on bottom row.
|
||||
float menuBottom = getHeight() + mMenuTranslationYBeforeOpen;
|
||||
float taskBottom = mTaskView.getHeight() + mTaskView.getPersistentTranslationY();
|
||||
float taskbarTop = mActivity.getDeviceProfile().heightPx
|
||||
- mActivity.getDeviceProfile().getOverviewActionsClaimedSpaceBelow();
|
||||
float taskbarTop = mContainer.getDeviceProfile().heightPx
|
||||
- mContainer.getDeviceProfile().getOverviewActionsClaimedSpaceBelow();
|
||||
float midpoint = (taskBottom + taskbarTop) / 2f;
|
||||
additionalTranslationY = -Math.max(menuBottom - midpoint, 0);
|
||||
}
|
||||
@@ -345,11 +344,11 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
menuTranslationYAnim.setInterpolator(EMPHASIZED);
|
||||
|
||||
float additionalTranslationX = 0;
|
||||
if (mActivity.getDeviceProfile().isLandscape
|
||||
if (mContainer.getDeviceProfile().isLandscape
|
||||
&& mTaskContainer.getStagePosition() == STAGE_POSITION_BOTTOM_OR_RIGHT) {
|
||||
// Animate menu and icon when split task would display off the side of the screen.
|
||||
additionalTranslationX = Math.max(
|
||||
getTranslationX() + getWidth() - (mActivity.getDeviceProfile().widthPx
|
||||
getTranslationX() + getWidth() - (mContainer.getDeviceProfile().widthPx
|
||||
- getResources().getDimensionPixelSize(
|
||||
R.dimen.task_menu_edge_padding) * 2), 0);
|
||||
}
|
||||
@@ -410,7 +409,7 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
private void closeComplete() {
|
||||
testLogD(TEST_TAPL_OVERVIEW_ACTIONS_MENU_FAILURE, "TaskMenuView.java.closeComplete");
|
||||
mIsOpen = false;
|
||||
mActivity.getDragLayer().removeView(this);
|
||||
mContainer.getDragLayer().removeView(this);
|
||||
mRevealAnimator = null;
|
||||
}
|
||||
|
||||
@@ -433,7 +432,7 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
private int calculateMaxHeight() {
|
||||
float taskInsetMargin = getResources().getDimension(R.dimen.task_card_margin);
|
||||
return mTaskView.getPagedOrientationHandler().getTaskMenuHeight(taskInsetMargin,
|
||||
mActivity.getDeviceProfile(), getTranslationX(), getTranslationY());
|
||||
mContainer.getDeviceProfile(), getTranslationX(), getTranslationY());
|
||||
}
|
||||
|
||||
private void setOnClosingStartCallback(Runnable onClosingStartCallback) {
|
||||
|
||||
@@ -29,7 +29,6 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.LinearLayout
|
||||
import com.android.launcher3.BaseDraggingActivity
|
||||
import com.android.launcher3.DeviceProfile
|
||||
import com.android.launcher3.InsettableFrameLayout
|
||||
import com.android.launcher3.R
|
||||
@@ -40,24 +39,22 @@ import com.android.launcher3.util.Themes
|
||||
import com.android.quickstep.TaskOverlayFactory
|
||||
import com.android.quickstep.views.TaskView.TaskIdAttributeContainer
|
||||
|
||||
class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
|
||||
class TaskMenuViewWithArrow<T> : ArrowPopup<T> where T : RecentsViewContainer, T : Context {
|
||||
companion object {
|
||||
const val TAG = "TaskMenuViewWithArrow"
|
||||
|
||||
fun showForTask(
|
||||
fun <T> showForTask(
|
||||
taskContainer: TaskIdAttributeContainer,
|
||||
alignedOptionIndex: Int = 0
|
||||
): Boolean {
|
||||
val activity =
|
||||
BaseDraggingActivity.fromContext<BaseDraggingActivity>(
|
||||
taskContainer.taskView.context
|
||||
)
|
||||
): Boolean where T : RecentsViewContainer, T : Context {
|
||||
val container: RecentsViewContainer =
|
||||
RecentsViewContainer.containerFromContext(taskContainer.taskView.context)
|
||||
val taskMenuViewWithArrow =
|
||||
activity.layoutInflater.inflate(
|
||||
container.layoutInflater.inflate(
|
||||
R.layout.task_menu_with_arrow,
|
||||
activity.dragLayer,
|
||||
container.dragLayer,
|
||||
false
|
||||
) as TaskMenuViewWithArrow<*>
|
||||
) as TaskMenuViewWithArrow<T>
|
||||
|
||||
return taskMenuViewWithArrow.populateAndShowForTask(taskContainer, alignedOptionIndex)
|
||||
}
|
||||
|
||||
@@ -48,7 +48,6 @@ import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
|
||||
import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.MainThreadInitializedObject;
|
||||
@@ -122,7 +121,7 @@ public class TaskThumbnailView extends View {
|
||||
}
|
||||
};
|
||||
|
||||
private final BaseActivity mActivity;
|
||||
private final RecentsViewContainer mContainer;
|
||||
@Nullable
|
||||
private TaskOverlay mOverlay;
|
||||
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
@@ -171,7 +170,7 @@ public class TaskThumbnailView extends View {
|
||||
mBackgroundPaint.setColor(Color.WHITE);
|
||||
mSplashBackgroundPaint.setColor(Color.WHITE);
|
||||
mClearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
|
||||
mActivity = BaseActivity.fromContext(context);
|
||||
mContainer = RecentsViewContainer.containerFromContext(context);
|
||||
// Initialize with placeholder value. It is overridden later by TaskView
|
||||
mFullscreenParams = TEMP_PARAMS.get(context);
|
||||
|
||||
@@ -308,7 +307,7 @@ public class TaskThumbnailView extends View {
|
||||
RectF boundsInBitmapSpace = new RectF();
|
||||
boundsToBitmapSpace.mapRect(boundsInBitmapSpace, viewRect);
|
||||
|
||||
DeviceProfile dp = mActivity.getDeviceProfile();
|
||||
DeviceProfile dp = mContainer.getDeviceProfile();
|
||||
int bottomInset = dp.isTablet
|
||||
? Math.round(bitmapRect.bottom - boundsInBitmapSpace.bottom) : 0;
|
||||
return Insets.of(0, 0, 0, bottomInset);
|
||||
@@ -549,7 +548,7 @@ public class TaskThumbnailView extends View {
|
||||
}
|
||||
|
||||
private void updateThumbnailMatrix() {
|
||||
DeviceProfile dp = mActivity.getDeviceProfile();
|
||||
DeviceProfile dp = mContainer.getDeviceProfile();
|
||||
mPreviewPositionHelper.setOrientationChanged(false);
|
||||
if (mBitmapShader != null && mThumbnailData != null) {
|
||||
mPreviewRect.set(0, 0, mThumbnailData.thumbnail.getWidth(),
|
||||
|
||||
@@ -87,7 +87,6 @@ import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.pm.UserCache;
|
||||
import com.android.launcher3.popup.SystemShortcut;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.launcher3.testing.TestLogging;
|
||||
import com.android.launcher3.testing.shared.TestProtocol;
|
||||
import com.android.launcher3.util.ActivityOptionsWrapper;
|
||||
@@ -119,8 +118,6 @@ import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.QuickStepContract;
|
||||
|
||||
import kotlin.Unit;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -129,6 +126,8 @@ import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import kotlin.Unit;
|
||||
|
||||
/**
|
||||
* A task in the Recents view.
|
||||
*/
|
||||
@@ -335,7 +334,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
private float mNonGridScale = 1;
|
||||
private float mDismissScale = 1;
|
||||
protected final FullscreenDrawParams mCurrentFullscreenParams;
|
||||
protected final StatefulActivity mActivity;
|
||||
protected final RecentsViewContainer mContainer;
|
||||
|
||||
// Various causes of changing primary translation, which we aggregate to setTranslationX/Y().
|
||||
private float mDismissTranslationX;
|
||||
@@ -417,11 +416,11 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
int defStyleRes, BorderAnimator focusBorderAnimator,
|
||||
BorderAnimator hoverBorderAnimator) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
mActivity = StatefulActivity.fromContext(context);
|
||||
mContainer = RecentsViewContainer.containerFromContext(context);
|
||||
setOnClickListener(this::onClick);
|
||||
|
||||
mCurrentFullscreenParams = new FullscreenDrawParams(context);
|
||||
mDigitalWellBeingToast = new DigitalWellBeingToast(mActivity, this);
|
||||
mDigitalWellBeingToast = new DigitalWellBeingToast(mContainer, this);
|
||||
|
||||
boolean keyboardFocusHighlightEnabled = FeatureFlags.ENABLE_KEYBOARD_QUICK_SWITCH.get()
|
||||
|| Flags.enableFocusOutline();
|
||||
@@ -487,7 +486,11 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
return getItemInfo(mTask);
|
||||
}
|
||||
|
||||
protected WorkspaceItemInfo getItemInfo(@Nullable Task task) {
|
||||
/**
|
||||
* Builds proto for logging
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public WorkspaceItemInfo getItemInfo(@Nullable Task task) {
|
||||
WorkspaceItemInfo stubInfo = new WorkspaceItemInfo();
|
||||
stubInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_TASK;
|
||||
stubInfo.container = LauncherSettings.Favorites.CONTAINER_TASKSWITCHER;
|
||||
@@ -613,7 +616,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
float viewHalfHeight = view.getHeight() / 2f;
|
||||
tempCenterCoords[0] = viewHalfWidth;
|
||||
tempCenterCoords[1] = viewHalfHeight;
|
||||
getDescendantCoordRelativeToAncestor(view.asView(), mActivity.getDragLayer(),
|
||||
getDescendantCoordRelativeToAncestor(view.asView(), mContainer.getDragLayer(),
|
||||
tempCenterCoords, false);
|
||||
transformingTouchDelegate.setBounds(
|
||||
(int) (tempCenterCoords[0] - viewHalfWidth),
|
||||
@@ -813,13 +816,19 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
|
||||
private void onClick(View view) {
|
||||
if (getTask() == null) {
|
||||
Log.d("b/310064698", "onClick - task is null");
|
||||
return;
|
||||
}
|
||||
if (confirmSecondSplitSelectApp()) {
|
||||
Log.d("b/310064698", mTask + " - onClick - split select is active");
|
||||
return;
|
||||
}
|
||||
launchTasks();
|
||||
mActivity.getStatsLogManager().logger().withItemInfo(getItemInfo())
|
||||
RunnableList callbackList = launchTasks();
|
||||
Log.d("b/310064698", mTask + " - onClick - callbackList: " + callbackList);
|
||||
if (callbackList != null) {
|
||||
callbackList.add(() -> Log.d("b/310064698", mTask + " - onClick - launchCompleted"));
|
||||
}
|
||||
mContainer.getStatsLogManager().logger().withItemInfo(getItemInfo())
|
||||
.log(LAUNCHER_TASK_LAUNCH_TAP);
|
||||
}
|
||||
|
||||
@@ -861,7 +870,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
"TaskView.launchTaskAnimated: startActivityFromRecentsAsync");
|
||||
TestLogging.recordEvent(
|
||||
TestProtocol.SEQUENCE_MAIN, "startActivityFromRecentsAsync", mTask);
|
||||
ActivityOptionsWrapper opts = mActivity.getActivityLaunchOptions(this, null);
|
||||
ActivityOptionsWrapper opts = mContainer.getActivityLaunchOptions(this, null);
|
||||
opts.options.setLaunchDisplayId(
|
||||
getDisplay() == null ? DEFAULT_DISPLAY : getDisplay().getDisplayId());
|
||||
if (ActivityManagerWrapper.getInstance()
|
||||
@@ -919,7 +928,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
// We only listen for failures to launch in quickswitch because the during this
|
||||
// gesture launcher is in the background state, vs other launches which are in
|
||||
// the actual overview state
|
||||
failureListener.register(mActivity, mTask.key.id, () -> {
|
||||
failureListener.register(mContainer, mTask.key.id, () -> {
|
||||
notifyTaskLaunchFailed(TAG);
|
||||
RecentsView rv = getRecentsView();
|
||||
if (rv != null) {
|
||||
@@ -1022,7 +1031,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
TaskViewUtils.composeRecentsLaunchAnimator(
|
||||
anim, this, targets.apps,
|
||||
targets.wallpapers, targets.nonApps, true /* launcherClosing */,
|
||||
mActivity.getStateManager(), recentsView,
|
||||
recentsView.getStateManager(), recentsView,
|
||||
recentsView.getDepthController());
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
@@ -1133,12 +1142,12 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!mActivity.getDeviceProfile().isTablet
|
||||
if (!mContainer.getDeviceProfile().isTablet
|
||||
&& !getRecentsView().isClearAllHidden()) {
|
||||
getRecentsView().snapToPage(getRecentsView().indexOfChild(this));
|
||||
return false;
|
||||
} else {
|
||||
mActivity.getStatsLogManager().logger().withItemInfo(getItemInfo())
|
||||
mContainer.getStatsLogManager().logger().withItemInfo(getItemInfo())
|
||||
.log(LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS);
|
||||
return showTaskMenuWithContainer(iconView);
|
||||
}
|
||||
@@ -1147,7 +1156,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
protected boolean showTaskMenuWithContainer(TaskViewIcon iconView) {
|
||||
TaskIdAttributeContainer menuContainer =
|
||||
mTaskIdAttributeContainer[iconView == mIconView ? 0 : 1];
|
||||
DeviceProfile dp = mActivity.getDeviceProfile();
|
||||
DeviceProfile dp = mContainer.getDeviceProfile();
|
||||
if (enableOverviewIconMenu() && iconView instanceof IconAppChipView) {
|
||||
((IconAppChipView) iconView).revealAnim(/* isRevealing= */ true);
|
||||
return TaskMenuView.showForTask(menuContainer,
|
||||
@@ -1201,7 +1210,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
}
|
||||
|
||||
protected void setThumbnailOrientation(RecentsOrientedState orientationState) {
|
||||
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
|
||||
DeviceProfile deviceProfile = mContainer.getDeviceProfile();
|
||||
int thumbnailTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
|
||||
|
||||
// TODO(b/271468547), we should default to setting trasnlations only on the snapshot instead
|
||||
@@ -1218,7 +1227,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
* Returns whether the task is part of overview grid and not being focused.
|
||||
*/
|
||||
public boolean isGridTask() {
|
||||
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
|
||||
DeviceProfile deviceProfile = mContainer.getDeviceProfile();
|
||||
return deviceProfile.isTablet && !isFocusedTask();
|
||||
}
|
||||
|
||||
@@ -1325,7 +1334,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
if (mActivity.getDeviceProfile().isTablet) {
|
||||
if (mContainer.getDeviceProfile().isTablet) {
|
||||
setPivotX(getLayoutDirection() == LAYOUT_DIRECTION_RTL ? 0 : right - left);
|
||||
setPivotY(mSnapshotView.getTop());
|
||||
} else {
|
||||
@@ -1682,10 +1691,10 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
mFullscreenProgress = progress;
|
||||
mIconView.setVisibility(progress < 1 ? VISIBLE : INVISIBLE);
|
||||
mSnapshotView.getTaskOverlay().setFullscreenProgress(progress);
|
||||
|
||||
RecentsView recentsView = mContainer.getOverviewPanel();
|
||||
// Animate icons and DWB banners in/out, except in QuickSwitch state, when tiles are
|
||||
// oversized and banner would look disproportionately large.
|
||||
if (mActivity.getStateManager().getState() != BACKGROUND_APP) {
|
||||
if (recentsView.getStateManager().getState() != BACKGROUND_APP) {
|
||||
setIconsAndBannersTransitionProgress(progress, true);
|
||||
}
|
||||
|
||||
@@ -1719,7 +1728,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
float boxTranslationY;
|
||||
int expectedWidth;
|
||||
int expectedHeight;
|
||||
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
|
||||
DeviceProfile deviceProfile = mContainer.getDeviceProfile();
|
||||
final int thumbnailPadding = deviceProfile.overviewTaskThumbnailTopMarginPx;
|
||||
final Rect lastComputedTaskSize = getRecentsView().getLastComputedTaskSize();
|
||||
final int taskWidth = lastComputedTaskSize.width();
|
||||
|
||||
+2
-1
@@ -37,6 +37,7 @@ import com.android.launcher3.util.SplitConfigurationOptions
|
||||
import com.android.quickstep.RecentsModel
|
||||
import com.android.quickstep.SystemUiProxy
|
||||
import com.android.quickstep.util.SplitSelectStateController.SplitFromDesktopController
|
||||
import com.android.quickstep.views.RecentsViewContainer
|
||||
import com.android.systemui.shared.recents.model.Task
|
||||
import com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50
|
||||
import java.util.function.Consumer
|
||||
@@ -63,7 +64,7 @@ class SplitSelectStateControllerTest {
|
||||
private val statsLogger: StatsLogger = mock()
|
||||
private val stateManager: StateManager<LauncherState> = mock()
|
||||
private val handler: Handler = mock()
|
||||
private val context: StatefulActivity<*> = mock()
|
||||
private val context: RecentsViewContainer = mock()
|
||||
private val recentsModel: RecentsModel = mock()
|
||||
private val pendingIntent: PendingIntent = mock()
|
||||
private val splitFromDesktopController: SplitFromDesktopController = mock()
|
||||
|
||||
@@ -23,9 +23,9 @@ import android.os.SystemProperties;
|
||||
import androidx.test.uiautomator.By;
|
||||
import androidx.test.uiautomator.Until;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.tapl.LaunchedAppState;
|
||||
import com.android.launcher3.ui.AbstractLauncherUiTest;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
|
||||
import org.junit.rules.RuleChain;
|
||||
@@ -34,7 +34,7 @@ import org.junit.rules.TestRule;
|
||||
/**
|
||||
* Base class for all instrumentation tests that deal with Quickstep.
|
||||
*/
|
||||
public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest {
|
||||
public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest<QuickstepLauncher> {
|
||||
public static final boolean ENABLE_SHELL_TRANSITIONS =
|
||||
SystemProperties.getBoolean("persist.wm.debug.shell_transit", true);
|
||||
@Override
|
||||
@@ -46,7 +46,7 @@ public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLauncherActivityClose(Launcher launcher) {
|
||||
protected void onLauncherActivityClose(QuickstepLauncher launcher) {
|
||||
RecentsView recentsView = launcher.getOverviewPanel();
|
||||
if (recentsView != null) {
|
||||
recentsView.finishRecentsAnimation(false /* toRecents */, null);
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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 android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.platform.test.flag.junit.SetFlagsRule
|
||||
import com.android.launcher3.AbstractFloatingView
|
||||
import com.android.launcher3.AbstractFloatingViewHelper
|
||||
import com.android.launcher3.Launcher
|
||||
import com.android.launcher3.logging.StatsLogManager
|
||||
import com.android.launcher3.logging.StatsLogManager.LauncherEvent
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher
|
||||
import com.android.launcher3.util.SplitConfigurationOptions
|
||||
import com.android.quickstep.views.LauncherRecentsView
|
||||
import com.android.quickstep.views.TaskView
|
||||
import com.android.systemui.shared.recents.model.Task
|
||||
import com.android.systemui.shared.recents.model.Task.TaskKey
|
||||
import com.android.window.flags.Flags
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.eq
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.whenever
|
||||
|
||||
/** Test for DesktopSystemShortcut */
|
||||
class DesktopSystemShortcutTest {
|
||||
|
||||
@get:Rule val setFlagsRule = SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT)
|
||||
|
||||
private val launcher: QuickstepLauncher = mock()
|
||||
private val statsLogManager: StatsLogManager = mock()
|
||||
private val statsLogger: StatsLogManager.StatsLogger = mock()
|
||||
private val recentsView: LauncherRecentsView = mock()
|
||||
private val taskView: TaskView = mock()
|
||||
private val workspaceItemInfo: WorkspaceItemInfo = mock()
|
||||
private val abstractFloatingViewHelper: AbstractFloatingViewHelper = mock()
|
||||
private val factory: TaskShortcutFactory =
|
||||
DesktopSystemShortcut.createFactory(abstractFloatingViewHelper)
|
||||
|
||||
@Test
|
||||
fun createDesktopTaskShortcutFactory_featureOff() {
|
||||
setFlagsRule.disableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
|
||||
|
||||
val task =
|
||||
Task(TaskKey(1, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
|
||||
isDockable = true
|
||||
}
|
||||
val taskContainer =
|
||||
taskView.TaskIdAttributeContainer(
|
||||
task,
|
||||
null,
|
||||
null,
|
||||
SplitConfigurationOptions.STAGE_POSITION_UNDEFINED
|
||||
)
|
||||
|
||||
val shortcuts = factory.getShortcuts(launcher, taskContainer)
|
||||
assertThat(shortcuts).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun createDesktopTaskShortcutFactory_undockable() {
|
||||
setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
|
||||
|
||||
val task =
|
||||
Task(TaskKey(1, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
|
||||
isDockable = false
|
||||
}
|
||||
val taskContainer =
|
||||
taskView.TaskIdAttributeContainer(
|
||||
task,
|
||||
null,
|
||||
null,
|
||||
SplitConfigurationOptions.STAGE_POSITION_UNDEFINED
|
||||
)
|
||||
|
||||
val shortcuts = factory.getShortcuts(launcher, taskContainer)
|
||||
assertThat(shortcuts).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun desktopSystemShortcutClicked() {
|
||||
setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
|
||||
|
||||
val task =
|
||||
Task(TaskKey(1, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
|
||||
isDockable = true
|
||||
}
|
||||
val taskContainer =
|
||||
taskView.TaskIdAttributeContainer(
|
||||
task,
|
||||
null,
|
||||
null,
|
||||
SplitConfigurationOptions.STAGE_POSITION_UNDEFINED
|
||||
)
|
||||
|
||||
whenever(launcher.getOverviewPanel<LauncherRecentsView>()).thenReturn(recentsView)
|
||||
whenever(launcher.statsLogManager).thenReturn(statsLogManager)
|
||||
whenever(statsLogManager.logger()).thenReturn(statsLogger)
|
||||
whenever(statsLogger.withItemInfo(any())).thenReturn(statsLogger)
|
||||
whenever(taskView.getItemInfo(task)).thenReturn(workspaceItemInfo)
|
||||
whenever(recentsView.moveTaskToDesktop(any(), any())).thenAnswer {
|
||||
val successCallback = it.getArgument<Runnable>(1)
|
||||
successCallback.run()
|
||||
}
|
||||
|
||||
val shortcuts = factory.getShortcuts(launcher, taskContainer)
|
||||
assertThat(shortcuts).hasSize(1)
|
||||
assertThat(shortcuts!!.first()).isInstanceOf(DesktopSystemShortcut::class.java)
|
||||
|
||||
val desktopShortcut = shortcuts.first() as DesktopSystemShortcut
|
||||
|
||||
desktopShortcut.onClick(taskView)
|
||||
|
||||
val allTypesExceptRebindSafe =
|
||||
AbstractFloatingView.TYPE_ALL and AbstractFloatingView.TYPE_REBIND_SAFE.inv()
|
||||
verify(abstractFloatingViewHelper).closeOpenViews(launcher, true, allTypesExceptRebindSafe)
|
||||
verify(recentsView).moveTaskToDesktop(eq(taskContainer), any())
|
||||
verify(statsLogger).withItemInfo(workspaceItemInfo)
|
||||
verify(statsLogger).log(LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_DESKTOP_TAP)
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import android.platform.test.annotations.PlatinumTest;
|
||||
import com.android.launcher3.tapl.OverviewTask.OverviewSplitTask;
|
||||
import com.android.launcher3.tapl.OverviewTaskMenu;
|
||||
import com.android.launcher3.ui.AbstractLauncherUiTest;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.launcher3.util.rule.TestStabilityRule;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -35,7 +36,7 @@ import org.junit.Test;
|
||||
* This test run in both Out of process (Oop) and in-process (Ipc).
|
||||
* Tests the app Icon in overview.
|
||||
*/
|
||||
public class TaplOverviewIconTest extends AbstractLauncherUiTest {
|
||||
public class TaplOverviewIconTest extends AbstractLauncherUiTest<QuickstepLauncher> {
|
||||
|
||||
private static final String CALCULATOR_APP_PACKAGE =
|
||||
resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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 com.android.launcher3.LauncherState.ALL_APPS;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.filters.LargeTest;
|
||||
|
||||
import com.android.launcher3.tapl.LauncherInstrumentation;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
@LargeTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class TaplPrivateSpaceTest extends AbstractQuickStepTest {
|
||||
|
||||
private int mProfileUserId;
|
||||
private boolean mPrivateProfileSetupSuccessful;
|
||||
private static final String TAG = "TaplPrivateSpaceTest";
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
initialize(this);
|
||||
|
||||
createAndStartPrivateProfileUser();
|
||||
assumeTrue("Private Profile Setup not successful, aborting",
|
||||
mPrivateProfileSetupSuccessful);
|
||||
|
||||
mDevice.pressHome();
|
||||
waitForLauncherCondition("Launcher didn't start", Objects::nonNull);
|
||||
waitForStateTransitionToEnd("Launcher internal state didn't switch to Normal",
|
||||
() -> NORMAL);
|
||||
waitForResumed("Launcher internal state is still Background");
|
||||
mLauncher.getWorkspace().switchToAllApps();
|
||||
waitForStateTransitionToEnd("Launcher internal state didn't switch to All Apps",
|
||||
() -> ALL_APPS);
|
||||
|
||||
// Wait for Private Space being available in Launcher.
|
||||
waitForPrivateSpaceSetup();
|
||||
// Wait for Launcher UI to be updated with Private Space Items.
|
||||
waitForLauncherUIUpdate();
|
||||
}
|
||||
|
||||
private void createAndStartPrivateProfileUser() {
|
||||
String createUserOutput = executeShellCommand("pm create-user --profileOf 0 --user-type "
|
||||
+ "android.os.usertype.profile.PRIVATE LauncherPrivateProfile");
|
||||
updatePrivateProfileSetupSuccessful("pm create-user", createUserOutput);
|
||||
String[] tokens = createUserOutput.split("\\s+");
|
||||
mProfileUserId = Integer.parseInt(tokens[tokens.length - 1]);
|
||||
StringBuilder logStr = new StringBuilder().append("profileId: ").append(mProfileUserId);
|
||||
for (String str : tokens) {
|
||||
logStr.append(str).append("\n");
|
||||
}
|
||||
String startUserOutput = executeShellCommand("am start-user " + mProfileUserId);
|
||||
updatePrivateProfileSetupSuccessful("am start-user", startUserOutput);
|
||||
}
|
||||
|
||||
@After
|
||||
public void removePrivateProfile() {
|
||||
String output = executeShellCommand("pm remove-user " + mProfileUserId);
|
||||
updateProfileRemovalSuccessful("pm remove-user", output);
|
||||
waitForPrivateSpaceRemoval();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrivateSpaceContainerIsPresent() {
|
||||
assumeTrue(mPrivateProfileSetupSuccessful);
|
||||
// Scroll to the bottom of All Apps
|
||||
executeOnLauncher(launcher -> launcher.getAppsView().resetAndScrollToPrivateSpaceHeader());
|
||||
waitForResumed("Launcher internal state is still Background");
|
||||
|
||||
// Verify Unlocked View elements are present.
|
||||
assertNotNull("Private Space Unlocked View not found, or is not correct",
|
||||
mLauncher.getAllApps().getPrivateSpaceUnlockedView());
|
||||
}
|
||||
|
||||
private void waitForPrivateSpaceSetup() {
|
||||
waitForLauncherCondition("Private Profile not setup",
|
||||
launcher -> launcher.getAppsView().hasPrivateProfile(),
|
||||
LauncherInstrumentation.WAIT_TIME_MS);
|
||||
}
|
||||
|
||||
private void waitForPrivateSpaceRemoval() {
|
||||
waitForLauncherCondition("Private Profile not setup",
|
||||
launcher -> !launcher.getAppsView().hasPrivateProfile(),
|
||||
LauncherInstrumentation.WAIT_TIME_MS);
|
||||
}
|
||||
|
||||
private void waitForLauncherUIUpdate() {
|
||||
// Wait for model thread completion as it may be processing
|
||||
// the install event from the SystemService
|
||||
mLauncher.waitForModelQueueCleared();
|
||||
// Wait for Launcher UI thread completion, as it may be processing updating the UI in
|
||||
// response to the model update. Not that `waitForLauncherInitialized` is just a proxy
|
||||
// method, we can use any method which touches Launcher UI thread,
|
||||
mLauncher.waitForLauncherInitialized();
|
||||
}
|
||||
|
||||
private void updatePrivateProfileSetupSuccessful(String cli, String output) {
|
||||
Log.d(TAG, "updatePrivateProfileSetupSuccessful, cli=" + cli + " " + "output="
|
||||
+ output);
|
||||
mPrivateProfileSetupSuccessful = output.startsWith("Success");
|
||||
}
|
||||
|
||||
private void updateProfileRemovalSuccessful(String cli, String output) {
|
||||
Log.d(TAG, "updateProfileRemovalSuccessful, cli=" + cli + " " + "output=" + output);
|
||||
assertTrue(output, output.startsWith("Success"));
|
||||
}
|
||||
|
||||
private String executeShellCommand(String command) {
|
||||
try {
|
||||
return mDevice.executeShellCommand(command);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "error running shell command", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import android.view.MotionEvent;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.quickstep.util.BorderAnimator;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
|
||||
@@ -47,7 +48,7 @@ import org.mockito.MockitoAnnotations;
|
||||
public class TaskViewTest {
|
||||
|
||||
@Mock
|
||||
private StatefulActivity mContext;
|
||||
private QuickstepLauncher mContext;
|
||||
@Mock
|
||||
private Resources mResource;
|
||||
@Mock
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
<string name="launcher_restore_event_logger_class" translatable="false"></string>
|
||||
<!-- Used for determining category of a widget presented in widget recommendations. -->
|
||||
<string name="widget_recommendation_category_provider_class" translatable="false"></string>
|
||||
<string name="api_wrapper_class" translatable="false"></string>
|
||||
|
||||
<!-- Default packages -->
|
||||
<string name="wallpaper_picker_package" translatable="false"></string>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user