mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-19 18:58:19 +00:00
Merge "Launch initial split from taskbar in overview app menu" into tm-qpr-dev
This commit is contained in:
@@ -15,38 +15,14 @@
|
||||
*/
|
||||
package com.android.launcher3.popup;
|
||||
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE;
|
||||
import static com.android.launcher3.util.SplitConfigurationOptions.getLogEventForPosition;
|
||||
import static com.android.quickstep.util.SplitAnimationTimings.TABLET_HOME_TO_SPLIT;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.logging.StatsLogManager;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.splitscreen.SplitShortcut;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
|
||||
import com.android.quickstep.util.SplitSelectStateController;
|
||||
import com.android.quickstep.views.FloatingTaskView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/** {@link SystemShortcut.Factory} implementation to create workspace split shortcuts */
|
||||
public interface QuickstepSystemShortcut {
|
||||
|
||||
String TAG = QuickstepSystemShortcut.class.getSimpleName();
|
||||
@@ -58,116 +34,12 @@ public interface QuickstepSystemShortcut {
|
||||
originalView, position);
|
||||
}
|
||||
|
||||
class SplitSelectSystemShortcut extends SystemShortcut<QuickstepLauncher> {
|
||||
|
||||
private final int mSplitPlaceholderSize;
|
||||
private final int mSplitPlaceholderInset;
|
||||
|
||||
private final Rect mTempRect = new Rect();
|
||||
private final SplitPositionOption mPosition;
|
||||
class SplitSelectSystemShortcut extends SplitShortcut<QuickstepLauncher> {
|
||||
|
||||
public SplitSelectSystemShortcut(QuickstepLauncher launcher, ItemInfo itemInfo,
|
||||
View originalView, SplitPositionOption position) {
|
||||
super(position.iconResId, position.textResId, launcher, itemInfo, originalView);
|
||||
|
||||
mPosition = position;
|
||||
|
||||
mSplitPlaceholderSize = launcher.getResources().getDimensionPixelSize(
|
||||
R.dimen.split_placeholder_size);
|
||||
mSplitPlaceholderInset = launcher.getResources().getDimensionPixelSize(
|
||||
R.dimen.split_placeholder_inset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
// Initiate splitscreen from the Home screen or Home All Apps
|
||||
Bitmap bitmap;
|
||||
Intent intent;
|
||||
if (mItemInfo instanceof WorkspaceItemInfo) {
|
||||
final WorkspaceItemInfo workspaceItemInfo = (WorkspaceItemInfo) mItemInfo;
|
||||
bitmap = workspaceItemInfo.bitmap.icon;
|
||||
intent = workspaceItemInfo.intent;
|
||||
} else if (mItemInfo instanceof com.android.launcher3.model.data.AppInfo) {
|
||||
final com.android.launcher3.model.data.AppInfo appInfo =
|
||||
(com.android.launcher3.model.data.AppInfo) mItemInfo;
|
||||
bitmap = appInfo.bitmap.icon;
|
||||
intent = appInfo.intent;
|
||||
} else {
|
||||
Log.e(TAG, "unknown item type");
|
||||
return;
|
||||
}
|
||||
|
||||
StatsLogManager.EventEnum splitEvent = getLogEventForPosition(mPosition.stagePosition);
|
||||
RecentsView recentsView = mTarget.getOverviewPanel();
|
||||
// Check if there is already an instance of this app running, if so, initiate the split
|
||||
// using that.
|
||||
recentsView.findLastActiveTaskAndRunCallback(
|
||||
intent.getComponent(),
|
||||
(Consumer<Task>) foundTask -> {
|
||||
SplitSelectSource source = new SplitSelectSource(mOriginalView,
|
||||
new BitmapDrawable(bitmap), intent, mPosition, mItemInfo,
|
||||
splitEvent, foundTask);
|
||||
if (ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
|
||||
startSplitToHome(source);
|
||||
} else {
|
||||
recentsView.initiateSplitSelect(source);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void startSplitToHome(SplitSelectSource source) {
|
||||
AbstractFloatingView.closeAllOpenViews(mTarget);
|
||||
|
||||
SplitSelectStateController controller = mTarget.getSplitSelectStateController();
|
||||
controller.setInitialTaskSelect(source.intent, source.position.stagePosition,
|
||||
source.itemInfo, source.splitEvent, source.alreadyRunningTask);
|
||||
|
||||
RecentsView recentsView = mTarget.getOverviewPanel();
|
||||
recentsView.getPagedOrientationHandler().getInitialSplitPlaceholderBounds(
|
||||
mSplitPlaceholderSize, mSplitPlaceholderInset, mTarget.getDeviceProfile(),
|
||||
controller.getActiveSplitStagePosition(), mTempRect);
|
||||
|
||||
PendingAnimation anim = new PendingAnimation(TABLET_HOME_TO_SPLIT.getDuration());
|
||||
RectF startingTaskRect = new RectF();
|
||||
final FloatingTaskView floatingTaskView = FloatingTaskView.getFloatingTaskView(mTarget,
|
||||
source.view, null /* thumbnail */, source.drawable, startingTaskRect);
|
||||
floatingTaskView.setAlpha(1);
|
||||
floatingTaskView.addStagingAnimation(anim, startingTaskRect, mTempRect,
|
||||
false /* fadeWithThumbnail */, true /* isStagedTask */);
|
||||
controller.setFirstFloatingTaskView(floatingTaskView);
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
mTarget.getDragLayer().removeView(floatingTaskView);
|
||||
controller.resetState();
|
||||
}
|
||||
});
|
||||
anim.buildAnim().start();
|
||||
}
|
||||
}
|
||||
|
||||
class SplitSelectSource {
|
||||
|
||||
public final View view;
|
||||
public final Drawable drawable;
|
||||
public final Intent intent;
|
||||
public final SplitPositionOption position;
|
||||
public final ItemInfo itemInfo;
|
||||
public final StatsLogManager.EventEnum splitEvent;
|
||||
@Nullable
|
||||
public final Task alreadyRunningTask;
|
||||
|
||||
public SplitSelectSource(View view, Drawable drawable, Intent intent,
|
||||
SplitPositionOption position, ItemInfo itemInfo,
|
||||
StatsLogManager.EventEnum splitEvent, @Nullable Task foundTask) {
|
||||
this.view = view;
|
||||
this.drawable = drawable;
|
||||
this.intent = intent;
|
||||
this.position = position;
|
||||
this.itemInfo = itemInfo;
|
||||
this.splitEvent = splitEvent;
|
||||
this.alreadyRunningTask = foundTask;
|
||||
super(position.iconResId, position.textResId, launcher, itemInfo, originalView,
|
||||
position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.splitscreen
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import com.android.launcher3.model.data.ItemInfo
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo
|
||||
import com.android.launcher3.popup.QuickstepSystemShortcut
|
||||
import com.android.launcher3.popup.SystemShortcut
|
||||
import com.android.launcher3.util.SplitConfigurationOptions
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource
|
||||
import com.android.launcher3.views.ActivityContext
|
||||
|
||||
/**
|
||||
* Shortcut to allow starting split. Default interaction for [onClick] is to launch
|
||||
* split selection mode
|
||||
*/
|
||||
abstract class SplitShortcut<T>(
|
||||
iconResId: Int,
|
||||
labelResId: Int,
|
||||
target: T,
|
||||
itemInfo: ItemInfo?,
|
||||
originalView: View?,
|
||||
protected val position: SplitPositionOption
|
||||
) : SystemShortcut<T>(iconResId, labelResId, target, itemInfo, originalView) where
|
||||
T : Context?,
|
||||
T : ActivityContext? {
|
||||
private val TAG = SystemShortcut::class.java.simpleName
|
||||
|
||||
// Initiate splitscreen from the Home screen or Home All Apps
|
||||
protected val splitSelectSource: SplitSelectSource?
|
||||
get() {
|
||||
// Initiate splitscreen from the Home screen or Home All Apps
|
||||
val bitmap: Bitmap
|
||||
val intent: Intent
|
||||
when (mItemInfo) {
|
||||
is WorkspaceItemInfo -> {
|
||||
val workspaceItemInfo = mItemInfo
|
||||
bitmap = workspaceItemInfo.bitmap.icon
|
||||
intent = workspaceItemInfo.intent
|
||||
}
|
||||
is com.android.launcher3.model.data.AppInfo -> {
|
||||
val appInfo = mItemInfo
|
||||
bitmap = appInfo.bitmap.icon
|
||||
intent = appInfo.intent
|
||||
}
|
||||
else -> {
|
||||
Log.e(TAG, "unknown item type")
|
||||
return null
|
||||
}
|
||||
}
|
||||
val splitEvent =
|
||||
SplitConfigurationOptions.getLogEventForPosition(position.stagePosition)
|
||||
return SplitSelectSource(
|
||||
mOriginalView,
|
||||
BitmapDrawable(bitmap),
|
||||
intent,
|
||||
position,
|
||||
mItemInfo,
|
||||
splitEvent
|
||||
)
|
||||
}
|
||||
|
||||
/** Starts split selection on the provided [mTarget] */
|
||||
override fun onClick(view: View?) {
|
||||
val splitSelectSource = splitSelectSource
|
||||
if (splitSelectSource == null) {
|
||||
Log.w(QuickstepSystemShortcut.TAG, "no split selection source")
|
||||
return
|
||||
}
|
||||
mTarget!!.startSplitSelection(splitSelectSource)
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.android.launcher3.taskbar;
|
||||
|
||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
import static android.content.pm.PackageManager.FEATURE_PC;
|
||||
import static android.os.Trace.TRACE_TAG_APP;
|
||||
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
@@ -92,6 +93,7 @@ import com.android.launcher3.util.DisplayController;
|
||||
import com.android.launcher3.util.NavigationMode;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
import com.android.launcher3.util.SettingsCache;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource;
|
||||
import com.android.launcher3.util.TraceHelper;
|
||||
import com.android.launcher3.util.ViewCache;
|
||||
import com.android.launcher3.views.ActivityContext;
|
||||
@@ -754,6 +756,11 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startSplitSelection(SplitSelectSource splitSelectSource) {
|
||||
mControllers.uiController.startSplitSelection(splitSelectSource);
|
||||
}
|
||||
|
||||
protected void onTaskbarIconClicked(View view) {
|
||||
Object tag = view.getTag();
|
||||
if (tag instanceof Task) {
|
||||
|
||||
@@ -125,7 +125,8 @@ import java.util.StringJoiner;
|
||||
mControllers.taskbarDragController.setDisallowLongClick(disallowLongClick);
|
||||
mControllers.taskbarAllAppsController.setDisallowGlobalDrag(disallowGlobalDrag);
|
||||
mControllers.taskbarAllAppsController.setDisallowLongClick(disallowLongClick);
|
||||
mControllers.taskbarPopupController.setHideSplitOptions(disallowGlobalDrag);
|
||||
mControllers.taskbarPopupController.setAllowInitialSplitSelection(
|
||||
disallowGlobalDrag);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -17,11 +17,9 @@ package com.android.launcher3.taskbar;
|
||||
|
||||
import static com.android.launcher3.util.SplitConfigurationOptions.getLogEventForPosition;
|
||||
|
||||
import android.content.ClipDescription;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.graphics.Point;
|
||||
import android.os.Bundle;
|
||||
import android.util.Pair;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@@ -46,6 +44,7 @@ import com.android.launcher3.popup.PopupDataProvider;
|
||||
import com.android.launcher3.popup.PopupLiveUpdateHandler;
|
||||
import com.android.launcher3.popup.SystemShortcut;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutView;
|
||||
import com.android.launcher3.splitscreen.SplitShortcut;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.launcher3.util.LauncherBindableItemsContainer;
|
||||
import com.android.launcher3.util.PackageUserKey;
|
||||
@@ -75,7 +74,7 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba
|
||||
|
||||
// Initialized in init.
|
||||
private TaskbarControllers mControllers;
|
||||
private boolean mHideSplitOptions;
|
||||
private boolean mAllowInitialSplitSelection;
|
||||
|
||||
public TaskbarPopupController(TaskbarActivityContext context) {
|
||||
mContext = context;
|
||||
@@ -101,8 +100,8 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba
|
||||
mPopupDataProvider.setDeepShortcutMap(deepShortcutMapCopy);
|
||||
}
|
||||
|
||||
public void setHideSplitOptions(boolean hideSplitOptions) {
|
||||
mHideSplitOptions = hideSplitOptions;
|
||||
public void setAllowInitialSplitSelection(boolean allowInitialSplitSelection) {
|
||||
mAllowInitialSplitSelection = allowInitialSplitSelection;
|
||||
}
|
||||
|
||||
private void updateNotificationDots(Predicate<PackageUserKey> updatedDots) {
|
||||
@@ -188,13 +187,9 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba
|
||||
}
|
||||
|
||||
// Create a Stream of all applicable system shortcuts
|
||||
// TODO(b/227800345): Add "Split bottom" option when tablet is in portrait mode.
|
||||
private Stream<SystemShortcut.Factory> getSystemShortcuts() {
|
||||
// concat a Stream of split options with a Stream of APP_INFO
|
||||
Stream<SystemShortcut.Factory> appInfo = Stream.of(APP_INFO);
|
||||
if (mHideSplitOptions) {
|
||||
return appInfo;
|
||||
}
|
||||
|
||||
return Stream.concat(
|
||||
Utilities.getSplitPositionOptions(mContext.getDeviceProfile())
|
||||
@@ -261,7 +256,7 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba
|
||||
private SystemShortcut.Factory<BaseTaskbarContext> createSplitShortcutFactory(
|
||||
SplitPositionOption position) {
|
||||
return (context, itemInfo, originalView) -> new TaskbarSplitShortcut(context, itemInfo,
|
||||
originalView, position);
|
||||
originalView, position, mAllowInitialSplitSelection);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -269,32 +264,43 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba
|
||||
* from the taskbar, as if the user performed a drag and drop split.
|
||||
* Includes an onClick method that initiates the actual split.
|
||||
*/
|
||||
private static class TaskbarSplitShortcut extends SystemShortcut<BaseTaskbarContext> {
|
||||
private final SplitPositionOption mPosition;
|
||||
private static class TaskbarSplitShortcut extends
|
||||
SplitShortcut<BaseTaskbarContext> {
|
||||
/**
|
||||
* If {@code true}, clicking this shortcut will not attempt to start a split app directly,
|
||||
* but be the first app in split selection mode
|
||||
*/
|
||||
private final boolean mAllowInitialSplitSelection;
|
||||
|
||||
TaskbarSplitShortcut(BaseTaskbarContext context, ItemInfo itemInfo, View originalView,
|
||||
SplitPositionOption position) {
|
||||
super(position.iconResId, position.textResId, context, itemInfo, originalView);
|
||||
mPosition = position;
|
||||
}
|
||||
TaskbarSplitShortcut(BaseTaskbarContext context, ItemInfo itemInfo, View originalView,
|
||||
SplitPositionOption position, boolean allowInitialSplitSelection) {
|
||||
super(position.iconResId, position.textResId, context, itemInfo, originalView,
|
||||
position);
|
||||
mAllowInitialSplitSelection = allowInitialSplitSelection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
AbstractFloatingView.closeAllOpenViews(mTarget);
|
||||
if (mAllowInitialSplitSelection) {
|
||||
super.onClick(view);
|
||||
return;
|
||||
}
|
||||
|
||||
// Initiate splitscreen from the in-app Taskbar or Taskbar All Apps
|
||||
Pair<InstanceId, com.android.launcher3.logging.InstanceId> instanceIds =
|
||||
LogUtils.getShellShareableInstanceId();
|
||||
mTarget.getStatsLogManager().logger()
|
||||
.withItemInfo(mItemInfo)
|
||||
.withInstanceId(instanceIds.second)
|
||||
.log(getLogEventForPosition(mPosition.stagePosition));
|
||||
.log(getLogEventForPosition(getPosition().stagePosition));
|
||||
|
||||
AbstractFloatingView.closeAllOpenViews(mTarget);
|
||||
if (mItemInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
|
||||
WorkspaceItemInfo workspaceItemInfo = (WorkspaceItemInfo) mItemInfo;
|
||||
SystemUiProxy.INSTANCE.get(mTarget).startShortcut(
|
||||
workspaceItemInfo.getIntent().getPackage(),
|
||||
workspaceItemInfo.getDeepShortcutId(),
|
||||
mPosition.stagePosition,
|
||||
getPosition().stagePosition,
|
||||
null,
|
||||
workspaceItemInfo.user,
|
||||
instanceIds.first);
|
||||
@@ -305,7 +311,7 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba
|
||||
null,
|
||||
mItemInfo.user),
|
||||
new Intent(),
|
||||
mPosition.stagePosition,
|
||||
getPosition().stagePosition,
|
||||
null,
|
||||
instanceIds.first);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.android.launcher3.taskbar;
|
||||
|
||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.view.MotionEvent;
|
||||
@@ -26,6 +28,7 @@ import androidx.annotation.Nullable;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.ItemInfoWithIcon;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
@@ -165,6 +168,23 @@ public class TaskbarUIController {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void startSplitSelection(SplitConfigurationOptions.SplitSelectSource splitSelectSource) {
|
||||
RecentsView recentsView = getRecentsView();
|
||||
if (recentsView == null) {
|
||||
return;
|
||||
}
|
||||
recentsView.findLastActiveTaskAndRunCallback(
|
||||
splitSelectSource.intent.getComponent(),
|
||||
(Consumer<Task>) foundTask -> {
|
||||
splitSelectSource.alreadyRunningTaskId = foundTask == null
|
||||
? INVALID_TASK_ID
|
||||
: foundTask.key.id;
|
||||
splitSelectSource.animateCurrentTaskDismissal = foundTask != null;
|
||||
recentsView.initiateSplitSelect(splitSelectSource);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the clicked Taskbar icon to launch a second app for splitscreen.
|
||||
*/
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.android.launcher3.taskbar.overlay;
|
||||
|
||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
|
||||
@@ -28,7 +30,13 @@ import com.android.launcher3.taskbar.TaskbarActivityContext;
|
||||
import com.android.launcher3.taskbar.TaskbarControllers;
|
||||
import com.android.launcher3.taskbar.TaskbarDragController;
|
||||
import com.android.launcher3.taskbar.TaskbarStashController;
|
||||
import com.android.launcher3.taskbar.TaskbarUIController;
|
||||
import com.android.launcher3.taskbar.allapps.TaskbarAllAppsContainerView;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Window context for the taskbar overlays such as All Apps and EDU.
|
||||
@@ -46,6 +54,7 @@ public class TaskbarOverlayContext extends BaseTaskbarContext {
|
||||
// We automatically stash taskbar when All Apps is opened in gesture navigation mode.
|
||||
private final boolean mWillTaskbarBeVisuallyStashed;
|
||||
private final int mStashedTaskbarHeight;
|
||||
private final TaskbarUIController mUiController;
|
||||
|
||||
public TaskbarOverlayContext(
|
||||
Context windowContext,
|
||||
@@ -61,6 +70,8 @@ public class TaskbarOverlayContext extends BaseTaskbarContext {
|
||||
TaskbarStashController taskbarStashController = controllers.taskbarStashController;
|
||||
mWillTaskbarBeVisuallyStashed = taskbarStashController.supportsVisualStashing();
|
||||
mStashedTaskbarHeight = taskbarStashController.getStashedHeight();
|
||||
|
||||
mUiController = controllers.uiController;
|
||||
}
|
||||
|
||||
boolean willTaskbarBeVisuallyStashed() {
|
||||
@@ -110,6 +121,11 @@ public class TaskbarOverlayContext extends BaseTaskbarContext {
|
||||
return mTaskbarContext.getPopupDataProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startSplitSelection(SplitSelectSource splitSelectSource) {
|
||||
mUiController.startSplitSelection(splitSelectSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DotInfo getDotInfoForItem(ItemInfo info) {
|
||||
return mTaskbarContext.getDotInfoForItem(info);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.android.launcher3.uioverrides;
|
||||
|
||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
import static android.os.Trace.TRACE_TAG_APP;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_OPTIMIZE_MEASURE;
|
||||
import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED;
|
||||
@@ -32,6 +33,7 @@ import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
|
||||
import static com.android.launcher3.anim.Interpolators.EMPHASIZED;
|
||||
import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_WIDGET_PICKER_DEPTH;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
|
||||
import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
|
||||
@@ -46,8 +48,11 @@ import static com.android.launcher3.testing.shared.TestProtocol.QUICK_SWITCH_STA
|
||||
import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
|
||||
import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
import static com.android.quickstep.util.SplitAnimationTimings.TABLET_HOME_TO_SPLIT;
|
||||
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.app.ActivityManager;
|
||||
@@ -57,6 +62,8 @@ import android.content.Intent;
|
||||
import android.content.IntentSender;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.hardware.SensorManager;
|
||||
import android.hardware.devicestate.DeviceStateManager;
|
||||
import android.media.permission.SafeCloseable;
|
||||
@@ -80,6 +87,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.app.viewcapture.ViewCapture;
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherSettings.Favorites;
|
||||
@@ -92,6 +100,7 @@ import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.Workspace;
|
||||
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.appprediction.PredictionRowView;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.dragndrop.DragOptions;
|
||||
@@ -133,6 +142,7 @@ import com.android.launcher3.util.PendingRequestArgs;
|
||||
import com.android.launcher3.util.PendingSplitSelectInfo;
|
||||
import com.android.launcher3.util.RunnableList;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource;
|
||||
import com.android.launcher3.util.TouchController;
|
||||
import com.android.launcher3.widget.LauncherWidgetHolder;
|
||||
import com.android.quickstep.OverviewCommandHelper;
|
||||
@@ -150,9 +160,11 @@ import com.android.quickstep.util.SplitToWorkspaceController;
|
||||
import com.android.quickstep.util.SplitWithKeyboardShortcutController;
|
||||
import com.android.quickstep.util.TISBindHelper;
|
||||
import com.android.quickstep.views.DesktopTaskView;
|
||||
import com.android.quickstep.views.FloatingTaskView;
|
||||
import com.android.quickstep.views.OverviewActionsView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.unfold.UnfoldSharedComponent;
|
||||
import com.android.systemui.unfold.UnfoldTransitionFactory;
|
||||
@@ -168,6 +180,7 @@ import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -362,7 +375,7 @@ public class QuickstepLauncher extends Launcher {
|
||||
Stream<SystemShortcut.Factory> base = Stream.of(WellbeingModel.SHORTCUT_FACTORY);
|
||||
if (ENABLE_SPLIT_FROM_WORKSPACE.get() && mDeviceProfile.isTablet) {
|
||||
RecentsView recentsView = getOverviewPanel();
|
||||
// TODO: Pull it out of PagedOrentationHandler for split from workspace.
|
||||
// TODO(b/266482558): Pull it out of PagedOrentationHandler for split from workspace.
|
||||
List<SplitPositionOption> positions =
|
||||
recentsView.getPagedOrientationHandler().getSplitPositionOptions(
|
||||
mDeviceProfile);
|
||||
@@ -548,6 +561,64 @@ public class QuickstepLauncher extends Launcher {
|
||||
getWindow().addPrivateFlags(PRIVATE_FLAG_OPTIMIZE_MEASURE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startSplitSelection(SplitSelectSource splitSelectSource) {
|
||||
RecentsView recentsView = getOverviewPanel();
|
||||
// Check if there is already an instance of this app running, if so, initiate the split
|
||||
// using that.
|
||||
recentsView.findLastActiveTaskAndRunCallback(
|
||||
splitSelectSource.intent.getComponent(),
|
||||
(Consumer<Task>) foundTask -> {
|
||||
splitSelectSource.alreadyRunningTaskId = foundTask == null
|
||||
? INVALID_TASK_ID
|
||||
: foundTask.key.id;
|
||||
if (ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
|
||||
startSplitToHome(splitSelectSource);
|
||||
} else {
|
||||
recentsView.initiateSplitSelect(splitSelectSource);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/** TODO(b/266482558) Migrate into SplitSelectStateController or someplace split specific. */
|
||||
private void startSplitToHome(
|
||||
SplitSelectSource source) {
|
||||
AbstractFloatingView.closeAllOpenViews(this);
|
||||
int splitPlaceholderSize = getResources().getDimensionPixelSize(
|
||||
R.dimen.split_placeholder_size);
|
||||
int splitPlaceholderInset = getResources().getDimensionPixelSize(
|
||||
R.dimen.split_placeholder_inset);
|
||||
Rect tempRect = new Rect();
|
||||
|
||||
SplitSelectStateController controller = getSplitSelectStateController();
|
||||
controller.setInitialTaskSelect(source.intent, source.position.stagePosition,
|
||||
source.itemInfo, source.splitEvent, source.alreadyRunningTaskId);
|
||||
|
||||
RecentsView recentsView = getOverviewPanel();
|
||||
recentsView.getPagedOrientationHandler().getInitialSplitPlaceholderBounds(
|
||||
splitPlaceholderSize, splitPlaceholderInset, getDeviceProfile(),
|
||||
controller.getActiveSplitStagePosition(), tempRect);
|
||||
|
||||
PendingAnimation anim = new PendingAnimation(TABLET_HOME_TO_SPLIT.getDuration());
|
||||
RectF startingTaskRect = new RectF();
|
||||
final FloatingTaskView floatingTaskView = FloatingTaskView.getFloatingTaskView(this,
|
||||
source.view, null /* thumbnail */, source.drawable, startingTaskRect);
|
||||
floatingTaskView.setAlpha(1);
|
||||
floatingTaskView.addStagingAnimation(anim, startingTaskRect, tempRect,
|
||||
false /* fadeWithThumbnail */, true /* isStagedTask */);
|
||||
controller.setFirstFloatingTaskView(floatingTaskView);
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
getDragLayer().removeView(floatingTaskView);
|
||||
controller.resetState();
|
||||
}
|
||||
});
|
||||
anim.buildAnim().start();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
@@ -34,9 +34,9 @@ import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.logging.StatsLogManager;
|
||||
import com.android.launcher3.popup.QuickstepSystemShortcut;
|
||||
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource;
|
||||
import com.android.quickstep.FallbackActivityInterface;
|
||||
import com.android.quickstep.GestureState;
|
||||
import com.android.quickstep.RecentsActivity;
|
||||
@@ -269,7 +269,7 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initiateSplitSelect(QuickstepSystemShortcut.SplitSelectSource splitSelectSource) {
|
||||
public void initiateSplitSelect(SplitSelectSource splitSelectSource) {
|
||||
super.initiateSplitSelect(splitSelectSource);
|
||||
mActivity.getStateManager().goToState(OVERVIEW_SPLIT_SELECT);
|
||||
}
|
||||
|
||||
@@ -90,6 +90,8 @@ public class SplitSelectStateController {
|
||||
private Intent mSecondTaskIntent;
|
||||
private int mSecondTaskId = INVALID_TASK_ID;
|
||||
private boolean mRecentsAnimationRunning;
|
||||
/** If {@code true}, animates the existing task view split placeholder view */
|
||||
private boolean mAnimateCurrentTaskDismissal;
|
||||
@Nullable
|
||||
private UserHandle mUser;
|
||||
/** If not null, this is the TaskView we want to launch from */
|
||||
@@ -111,22 +113,15 @@ public class SplitSelectStateController {
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called after first task selected in Overview.
|
||||
* @param alreadyRunningTask if set to {@link android.app.ActivityTaskManager#INVALID_TASK_ID}
|
||||
* then @param intent will be used to launch the initial task
|
||||
* @param intent will be ignored if @param alreadyRunningTask is set
|
||||
*/
|
||||
public void setInitialTaskSelect(Task task, @StagePosition int stagePosition,
|
||||
StatsLogManager.EventEnum splitEvent, ItemInfo itemInfo) {
|
||||
mInitialTaskId = task.key.id;
|
||||
setInitialData(stagePosition, splitEvent, itemInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called after first task selected from home or all apps.
|
||||
*/
|
||||
public void setInitialTaskSelect(Intent intent, @StagePosition int stagePosition,
|
||||
public void setInitialTaskSelect(@Nullable Intent intent, @StagePosition int stagePosition,
|
||||
@NonNull ItemInfo itemInfo, StatsLogManager.EventEnum splitEvent,
|
||||
@Nullable Task alreadyRunningTask) {
|
||||
if (alreadyRunningTask != null) {
|
||||
mInitialTaskId = alreadyRunningTask.key.id;
|
||||
int alreadyRunningTask) {
|
||||
if (alreadyRunningTask != INVALID_TASK_ID) {
|
||||
mInitialTaskId = alreadyRunningTask;
|
||||
} else {
|
||||
mInitialTaskIntent = intent;
|
||||
mUser = itemInfo.user;
|
||||
@@ -348,6 +343,14 @@ public class SplitSelectStateController {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isAnimateCurrentTaskDismissal() {
|
||||
return mAnimateCurrentTaskDismissal;
|
||||
}
|
||||
|
||||
public void setAnimateCurrentTaskDismissal(boolean animateCurrentTaskDismissal) {
|
||||
mAnimateCurrentTaskDismissal = animateCurrentTaskDismissal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requires Shell Transitions
|
||||
*/
|
||||
@@ -454,6 +457,7 @@ public class SplitSelectStateController {
|
||||
mLaunchingTaskView = null;
|
||||
mItemInfo = null;
|
||||
mSplitEvent = null;
|
||||
mAnimateCurrentTaskDismissal = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,13 +34,13 @@ import androidx.annotation.Nullable;
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.logging.StatsLogManager;
|
||||
import com.android.launcher3.popup.QuickstepSystemShortcut;
|
||||
import com.android.launcher3.statehandlers.DepthController;
|
||||
import com.android.launcher3.statehandlers.DesktopVisibilityController;
|
||||
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.launcher3.util.PendingSplitSelectInfo;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource;
|
||||
import com.android.quickstep.LauncherActivityInterface;
|
||||
import com.android.quickstep.RotationTouchHelper;
|
||||
import com.android.quickstep.util.SplitSelectStateController;
|
||||
@@ -199,7 +199,7 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initiateSplitSelect(QuickstepSystemShortcut.SplitSelectSource splitSelectSource) {
|
||||
public void initiateSplitSelect(SplitSelectSource splitSelectSource) {
|
||||
super.initiateSplitSelect(splitSelectSource);
|
||||
mActivity.getStateManager().goToState(LauncherState.OVERVIEW_SPLIT_SELECT);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.quickstep.views;
|
||||
|
||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
import static android.view.Surface.ROTATION_0;
|
||||
import static android.view.View.MeasureSpec.EXACTLY;
|
||||
import static android.view.View.MeasureSpec.makeMeasureSpec;
|
||||
@@ -144,7 +145,6 @@ import com.android.launcher3.compat.AccessibilityManagerCompat;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.icons.cache.HandlerRunnable;
|
||||
import com.android.launcher3.logging.StatsLogManager;
|
||||
import com.android.launcher3.popup.QuickstepSystemShortcut;
|
||||
import com.android.launcher3.statehandlers.DepthController;
|
||||
import com.android.launcher3.statemanager.BaseState;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
@@ -156,6 +156,7 @@ import com.android.launcher3.util.IntSet;
|
||||
import com.android.launcher3.util.ResourceBasedOverride.Overrides;
|
||||
import com.android.launcher3.util.RunnableList;
|
||||
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.TranslateEdgeEffect;
|
||||
@@ -677,7 +678,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
private SplitInstructionsView mSplitInstructionsView;
|
||||
|
||||
@Nullable
|
||||
private QuickstepSystemShortcut.SplitSelectSource mSplitSelectSource;
|
||||
private SplitSelectSource mSplitSelectSource;
|
||||
|
||||
/**
|
||||
* Keeps track of the index of the TaskView that split screen was initialized with so we know
|
||||
@@ -1607,8 +1608,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
// If we are entering Overview as a result of initiating a split from somewhere else
|
||||
// (e.g. split from Home), we need to make sure the staged app is not drawn as a thumbnail.
|
||||
Task stagedTaskToBeRemovedFromGrid =
|
||||
mSplitSelectSource != null ? mSplitSelectSource.alreadyRunningTask : null;
|
||||
int stagedTaskIdToBeRemovedFromGrid = mSplitSelectSource != null
|
||||
? mSplitSelectSource.alreadyRunningTaskId
|
||||
: INVALID_TASK_ID;
|
||||
|
||||
// update the map of instance counts
|
||||
mFilterState.updateInstanceCountMap(taskGroups);
|
||||
@@ -1617,8 +1619,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
// taskGroups backwards populates the thumbnail grid from least recent to most recent.
|
||||
for (int i = taskGroups.size() - 1; i >= 0; i--) {
|
||||
GroupTask groupTask = taskGroups.get(i);
|
||||
boolean isRemovalNeeded = stagedTaskToBeRemovedFromGrid != null
|
||||
&& groupTask.containsTask(stagedTaskToBeRemovedFromGrid.key.id);
|
||||
boolean isRemovalNeeded = stagedTaskIdToBeRemovedFromGrid != INVALID_TASK_ID
|
||||
&& groupTask.containsTask(stagedTaskIdToBeRemovedFromGrid);
|
||||
|
||||
TaskView taskView;
|
||||
if (isRemovalNeeded && groupTask.hasMultipleTasks()) {
|
||||
@@ -1632,7 +1634,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
addView(taskView);
|
||||
|
||||
if (isRemovalNeeded && groupTask.hasMultipleTasks()) {
|
||||
if (groupTask.task1.equals(stagedTaskToBeRemovedFromGrid)) {
|
||||
if (groupTask.task1.key.id == stagedTaskIdToBeRemovedFromGrid) {
|
||||
taskView.bind(groupTask.task2, mOrientationState);
|
||||
} else {
|
||||
taskView.bind(groupTask.task1, mOrientationState);
|
||||
@@ -3019,7 +3021,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
RectF startingTaskRect = new RectF();
|
||||
safeRemoveDragLayerView(mFirstFloatingTaskView);
|
||||
if (mSplitHiddenTaskView != null) {
|
||||
if (mSplitSelectStateController.isAnimateCurrentTaskDismissal()) {
|
||||
// Create the split select animation from Overview
|
||||
mSplitHiddenTaskView.setThumbnailVisibility(INVISIBLE);
|
||||
anim.setViewAlpha(mSplitHiddenTaskView.getIconView(), 0, clampToProgress(LINEAR,
|
||||
@@ -4393,29 +4395,38 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
initiateSplitSelect(taskView, defaultSplitPosition, LAUNCHER_OVERVIEW_ACTIONS_SPLIT);
|
||||
}
|
||||
|
||||
/** TODO(b/266477929): Consolidate this call w/ the one below */
|
||||
public void initiateSplitSelect(TaskView taskView, @StagePosition int stagePosition,
|
||||
StatsLogManager.EventEnum splitEvent) {
|
||||
mSplitHiddenTaskView = taskView;
|
||||
mSplitSelectStateController.setInitialTaskSelect(taskView.getTask(),
|
||||
stagePosition, splitEvent, taskView.getItemInfo());
|
||||
mSplitSelectStateController.setInitialTaskSelect(null /*intent*/,
|
||||
stagePosition, taskView.getItemInfo(), splitEvent, taskView.mTask.key.id);
|
||||
mSplitSelectStateController.setAnimateCurrentTaskDismissal(
|
||||
true /*animateCurrentTaskDismissal*/);
|
||||
mSplitHiddenTaskViewIndex = indexOfChild(taskView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when staging a split from Home/AllApps, using the icon long-press menu.
|
||||
* Called when staging a split from Home/AllApps/Overview (Taskbar),
|
||||
* using the icon long-press menu.
|
||||
* Attempts to initiate split with an existing taskView, if one exists
|
||||
*/
|
||||
public void initiateSplitSelect(QuickstepSystemShortcut.SplitSelectSource splitSelectSource) {
|
||||
public void initiateSplitSelect(SplitSelectSource splitSelectSource) {
|
||||
mSplitSelectSource = splitSelectSource;
|
||||
mSplitHiddenTaskView = getTaskViewByTaskId(splitSelectSource.alreadyRunningTaskId);
|
||||
mSplitHiddenTaskViewIndex = indexOfChild(mSplitHiddenTaskView);
|
||||
mSplitSelectStateController
|
||||
.setAnimateCurrentTaskDismissal(splitSelectSource.animateCurrentTaskDismissal);
|
||||
mSplitSelectStateController.setInitialTaskSelect(splitSelectSource.intent,
|
||||
splitSelectSource.position.stagePosition, splitSelectSource.itemInfo,
|
||||
splitSelectSource.splitEvent, splitSelectSource.alreadyRunningTask);
|
||||
splitSelectSource.splitEvent, splitSelectSource.alreadyRunningTaskId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies a PendingAnimation with the animations for entering split staging
|
||||
*/
|
||||
public void createSplitSelectInitAnimation(PendingAnimation builder, int duration) {
|
||||
if (mSplitHiddenTaskView != null) {
|
||||
if (mSplitSelectStateController.isAnimateCurrentTaskDismissal()) {
|
||||
// Splitting from Overview
|
||||
createTaskDismissAnimation(builder, mSplitHiddenTaskView, true, false, duration,
|
||||
true /* dismissingForSplitSelection*/);
|
||||
|
||||
@@ -40,6 +40,7 @@ import java.util.List;
|
||||
public abstract class SystemShortcut<T extends Context & ActivityContext> extends ItemInfo
|
||||
implements View.OnClickListener {
|
||||
|
||||
private static final String TAG = SystemShortcut.class.getSimpleName();
|
||||
private final int mIconResId;
|
||||
protected final int mLabelResId;
|
||||
protected int mAccessibilityActionId;
|
||||
|
||||
@@ -21,11 +21,15 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
|
||||
import com.android.launcher3.logging.StatsLogManager;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -190,4 +194,35 @@ public final class SplitConfigurationOptions {
|
||||
return position == STAGE_POSITION_TOP_OR_LEFT ? STAGE_POSITION_BOTTOM_OR_RIGHT
|
||||
: STAGE_POSITION_TOP_OR_LEFT;
|
||||
}
|
||||
|
||||
public static class SplitSelectSource {
|
||||
|
||||
/** Keep in sync w/ ActivityTaskManager#INVALID_TASK_ID (unreference-able) */
|
||||
private static final int INVALID_TASK_ID = -1;
|
||||
|
||||
public final View view;
|
||||
public final Drawable drawable;
|
||||
public final Intent intent;
|
||||
public final SplitPositionOption position;
|
||||
public final ItemInfo itemInfo;
|
||||
public final StatsLogManager.EventEnum splitEvent;
|
||||
/** Represents the taskId of the first app to start in split screen */
|
||||
public int alreadyRunningTaskId = INVALID_TASK_ID;
|
||||
/**
|
||||
* If {@code true}, animates the view represented by {@link #alreadyRunningTaskId} into the
|
||||
* split placeholder view
|
||||
*/
|
||||
public boolean animateCurrentTaskDismissal;
|
||||
|
||||
public SplitSelectSource(View view, Drawable drawable, Intent intent,
|
||||
SplitPositionOption position, ItemInfo itemInfo,
|
||||
StatsLogManager.EventEnum splitEvent) {
|
||||
this.view = view;
|
||||
this.drawable = drawable;
|
||||
this.intent = intent;
|
||||
this.position = position;
|
||||
this.itemInfo = itemInfo;
|
||||
this.splitEvent = splitEvent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ import com.android.launcher3.util.OnboardingPrefs;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
import com.android.launcher3.util.Preconditions;
|
||||
import com.android.launcher3.util.RunnableList;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions;
|
||||
import com.android.launcher3.util.ViewCache;
|
||||
|
||||
import java.util.List;
|
||||
@@ -130,6 +131,12 @@ public interface ActivityContext {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Called when the first app in split screen has been selected */
|
||||
default void startSplitSelection(
|
||||
SplitConfigurationOptions.SplitSelectSource splitSelectSource) {
|
||||
// Overridden, intentionally empty
|
||||
}
|
||||
|
||||
/**
|
||||
* The root view to support drag-and-drop and popup support.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user