mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-03 01:16:49 +00:00
Merge "Allow user to select second split app from Taskbar" into tm-qpr-dev am: d5525c3bda
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/20365694 Change-Id: I8d1e153a3d9f2b04293a41a0e008cc348fe028d9 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -41,8 +41,7 @@ public class FallbackTaskbarUIController extends TaskbarUIController {
|
||||
animateToRecentsState(toState);
|
||||
|
||||
// Handle tapping on live tile.
|
||||
RecentsView recentsView = mRecentsActivity.getOverviewPanel();
|
||||
recentsView.setTaskLaunchListener(toState == RecentsState.DEFAULT
|
||||
getRecentsView().setTaskLaunchListener(toState == RecentsState.DEFAULT
|
||||
? (() -> animateToRecentsState(RecentsState.BACKGROUND_APP)) : null);
|
||||
}
|
||||
};
|
||||
@@ -88,4 +87,9 @@ public class FallbackTaskbarUIController extends TaskbarUIController {
|
||||
anim.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecentsView getRecentsView() {
|
||||
return mRecentsActivity.getOverviewPanel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ import com.android.launcher3.util.DisplayController;
|
||||
import com.android.launcher3.util.OnboardingPrefs;
|
||||
import com.android.quickstep.AnimatedFloat;
|
||||
import com.android.quickstep.RecentsAnimationCallbacks;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Arrays;
|
||||
@@ -391,4 +392,9 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
|
||||
|
||||
mTaskbarLauncherStateController.dumpLogs(prefix + "\t", pw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecentsView getRecentsView() {
|
||||
return mLauncher.getOverviewPanel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,7 @@ import com.android.launcher3.util.SettingsCache;
|
||||
import com.android.launcher3.util.TraceHelper;
|
||||
import com.android.launcher3.util.ViewCache;
|
||||
import com.android.launcher3.views.ActivityContext;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.rotation.RotationButtonController;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
@@ -133,6 +134,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
private final boolean mIsUserSetupComplete;
|
||||
private final boolean mIsNavBarForceVisible;
|
||||
private final boolean mIsNavBarKidsMode;
|
||||
|
||||
private boolean mIsDestroyed = false;
|
||||
// The flag to know if the window is excluded from magnification region computation.
|
||||
private boolean mIsExcludeFromMagnificationRegion = false;
|
||||
@@ -757,42 +759,63 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
if (info.isDisabled()) {
|
||||
ItemClickHandler.handleDisabledItemClicked(info, this);
|
||||
} else {
|
||||
Intent intent = new Intent(info.getIntent())
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
try {
|
||||
if (mIsSafeModeEnabled && !PackageManagerHelper.isSystemApp(this, intent)) {
|
||||
Toast.makeText(this, R.string.safemode_shortcut_error,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
} else if (info.isPromise()) {
|
||||
TestLogging.recordEvent(
|
||||
TestProtocol.SEQUENCE_MAIN, "start: taskbarPromiseIcon");
|
||||
intent = new PackageManagerHelper(this)
|
||||
.getMarketIntent(info.getTargetPackage())
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
TaskbarUIController taskbarUIController = mControllers.uiController;
|
||||
RecentsView recents = taskbarUIController.getRecentsView();
|
||||
if (recents != null
|
||||
&& taskbarUIController.getRecentsView().isSplitSelectionActive()) {
|
||||
// If we are selecting a second app for split, launch the split tasks
|
||||
taskbarUIController.triggerSecondAppForSplit(info, info.intent, view);
|
||||
} else {
|
||||
// Else launch the selected task
|
||||
Intent intent = new Intent(info.getIntent())
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
try {
|
||||
if (mIsSafeModeEnabled && !PackageManagerHelper.isSystemApp(this, intent)) {
|
||||
Toast.makeText(this, R.string.safemode_shortcut_error,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
} else if (info.isPromise()) {
|
||||
TestLogging.recordEvent(
|
||||
TestProtocol.SEQUENCE_MAIN, "start: taskbarPromiseIcon");
|
||||
intent = new PackageManagerHelper(this)
|
||||
.getMarketIntent(info.getTargetPackage())
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
|
||||
} else if (info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
|
||||
TestLogging.recordEvent(
|
||||
TestProtocol.SEQUENCE_MAIN, "start: taskbarDeepShortcut");
|
||||
String id = info.getDeepShortcutId();
|
||||
String packageName = intent.getPackage();
|
||||
getSystemService(LauncherApps.class)
|
||||
.startShortcut(packageName, id, null, null, info.user);
|
||||
} else {
|
||||
startItemInfoActivity(info);
|
||||
} else if (info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
|
||||
TestLogging.recordEvent(
|
||||
TestProtocol.SEQUENCE_MAIN, "start: taskbarDeepShortcut");
|
||||
String id = info.getDeepShortcutId();
|
||||
String packageName = intent.getPackage();
|
||||
getSystemService(LauncherApps.class)
|
||||
.startShortcut(packageName, id, null, null, info.user);
|
||||
} else {
|
||||
startItemInfoActivity(info);
|
||||
}
|
||||
|
||||
mControllers.uiController.onTaskbarIconLaunched(info);
|
||||
} catch (NullPointerException
|
||||
| ActivityNotFoundException
|
||||
| SecurityException e) {
|
||||
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
Log.e(TAG, "Unable to launch. tag=" + info + " intent=" + intent, e);
|
||||
}
|
||||
|
||||
mControllers.uiController.onTaskbarIconLaunched(info);
|
||||
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
|
||||
} catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
|
||||
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
Log.e(TAG, "Unable to launch. tag=" + info + " intent=" + intent, e);
|
||||
}
|
||||
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
|
||||
}
|
||||
} else if (tag instanceof AppInfo) {
|
||||
startItemInfoActivity((AppInfo) tag);
|
||||
mControllers.uiController.onTaskbarIconLaunched((AppInfo) tag);
|
||||
AppInfo info = (AppInfo) tag;
|
||||
TaskbarUIController taskbarUIController = mControllers.uiController;
|
||||
RecentsView recents = taskbarUIController.getRecentsView();
|
||||
if (recents != null
|
||||
&& taskbarUIController.getRecentsView().isSplitSelectionActive()) {
|
||||
// If we are selecting a second app for split, launch the split tasks
|
||||
taskbarUIController.triggerSecondAppForSplit(info, info.intent, view);
|
||||
} else {
|
||||
// Else launch the selected task
|
||||
startItemInfoActivity((AppInfo) tag);
|
||||
mControllers.uiController.onTaskbarIconLaunched((AppInfo) tag);
|
||||
}
|
||||
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
|
||||
} else {
|
||||
Log.e(TAG, "Unknown type clicked: " + tag);
|
||||
|
||||
@@ -15,13 +15,18 @@
|
||||
*/
|
||||
package com.android.launcher3.taskbar;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.ItemInfoWithIcon;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.stream.Stream;
|
||||
@@ -135,4 +140,38 @@ public class TaskbarUIController {
|
||||
prefix,
|
||||
getClass().getSimpleName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns RecentsView. Overwritten in LauncherTaskbarUIController and
|
||||
* FallbackTaskbarUIController with Launcher-specific implementations. Returns null for other
|
||||
* UI controllers (like DesktopTaskbarUIController) that don't have a RecentsView.
|
||||
*/
|
||||
public @Nullable RecentsView getRecentsView() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the clicked Taskbar icon to launch a second app for splitscreen.
|
||||
*/
|
||||
public void triggerSecondAppForSplit(ItemInfoWithIcon info, Intent intent, View startingView) {
|
||||
RecentsView recents = getRecentsView();
|
||||
TaskView foundTaskView = recents.getTaskViewByComponentName(info.getTargetComponent());
|
||||
if (foundTaskView != null) {
|
||||
recents.confirmSplitSelect(
|
||||
foundTaskView,
|
||||
foundTaskView.getTask(),
|
||||
foundTaskView.getIconView().getDrawable(),
|
||||
foundTaskView.getThumbnail(),
|
||||
foundTaskView.getThumbnail().getThumbnail(),
|
||||
/* intent */ null);
|
||||
} else {
|
||||
recents.confirmSplitSelect(
|
||||
/* containerTaskView */ null,
|
||||
/* task */ null,
|
||||
new BitmapDrawable(info.bitmap.icon),
|
||||
startingView,
|
||||
/* thumbnail */ null,
|
||||
intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,9 +74,12 @@ import android.animation.ValueAnimator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.LocusId;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BlendMode;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
@@ -662,8 +665,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
private TaskView mSecondSplitHiddenView;
|
||||
@Nullable
|
||||
private SplitBounds mSplitBoundsConfig;
|
||||
private final Toast mSplitToast = Toast.makeText(getContext(),
|
||||
R.string.toast_split_select_app, Toast.LENGTH_SHORT);
|
||||
private final Toast mSplitUnsupportedToast = Toast.makeText(getContext(),
|
||||
R.string.toast_split_app_unsupported, Toast.LENGTH_SHORT);
|
||||
|
||||
@@ -1213,6 +1214,21 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link TaskView} that has ComponentName matching {@code componentName} or null if
|
||||
* no match.
|
||||
*/
|
||||
@Nullable
|
||||
public TaskView getTaskViewByComponentName(ComponentName componentName) {
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
TaskView taskView = requireTaskViewAt(i);
|
||||
if (taskView.getTask().key.sourceComponent.equals(componentName)) {
|
||||
return taskView;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setOverviewStateEnabled(boolean enabled) {
|
||||
mOverviewStateEnabled = enabled;
|
||||
updateTaskStackListenerState();
|
||||
@@ -4237,24 +4253,39 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
* Confirms the selection of the next split task. The extra data is passed through because the
|
||||
* user may be selecting a subtask in a group.
|
||||
*
|
||||
* @param containerTaskView If our second selected app is currently running in Recents, this is
|
||||
* the "container" TaskView from Recents. If we are starting a fresh
|
||||
* instance of the app from an Intent, this will be null.
|
||||
* @param task The Task corresponding to our second selected app. If we are starting a fresh
|
||||
* instance of the app from an Intent, this will be null.
|
||||
* @param drawable The Drawable corresponding to our second selected app's icon.
|
||||
* @param secondView The View representing the current space on the screen where the second app
|
||||
* is (either the ThumbnailView or the tapped icon).
|
||||
* @param intent If we are launching a fresh instance of the app, this is the Intent for it. If
|
||||
* the second app is already running in Recents, this will be null.
|
||||
* @return true if waiting for confirmation of second app or if split animations are running,
|
||||
* false otherwise
|
||||
*/
|
||||
public boolean confirmSplitSelect(TaskView containerTaskView, Task task, IconView iconView,
|
||||
TaskThumbnailView thumbnailView) {
|
||||
public boolean confirmSplitSelect(TaskView containerTaskView, Task task, Drawable drawable,
|
||||
View secondView, @Nullable Bitmap thumbnail, Intent intent) {
|
||||
if (canLaunchFullscreenTask()) {
|
||||
return false;
|
||||
}
|
||||
if (mSplitSelectStateController.isBothSplitAppsConfirmed()) {
|
||||
return true;
|
||||
}
|
||||
mSplitToast.cancel();
|
||||
if (!task.isDockable) {
|
||||
// Task not split screen supported
|
||||
mSplitUnsupportedToast.show();
|
||||
return true;
|
||||
// Second task is selected either as an already-running Task or an Intent
|
||||
if (task != null) {
|
||||
if (!task.isDockable) {
|
||||
// Task does not support split screen
|
||||
mSplitUnsupportedToast.show();
|
||||
return true;
|
||||
}
|
||||
mSplitSelectStateController.setSecondTask(task);
|
||||
} else {
|
||||
mSplitSelectStateController.setSecondTask(intent);
|
||||
}
|
||||
mSplitSelectStateController.setSecondTask(task);
|
||||
|
||||
RectF secondTaskStartingBounds = new RectF();
|
||||
Rect secondTaskEndingBounds = new Rect();
|
||||
// TODO(194414938) starting bounds seem slightly off, investigate
|
||||
@@ -4281,9 +4312,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
false /* fadeWithThumbnail */, true /* isStagedTask */);
|
||||
|
||||
safeRemoveDragLayerView(mSecondFloatingTaskView);
|
||||
mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
|
||||
thumbnailView, thumbnailView.getThumbnail(),
|
||||
iconView.getDrawable(), secondTaskStartingBounds);
|
||||
|
||||
mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity, secondView,
|
||||
thumbnail, drawable, secondTaskStartingBounds);
|
||||
mSecondFloatingTaskView.setAlpha(1);
|
||||
mSecondFloatingTaskView.addConfirmAnimation(pendingAnimation, secondTaskStartingBounds,
|
||||
secondTaskEndingBounds, true /* fadeWithThumbnail */, false /* isStagedTask */);
|
||||
@@ -4299,7 +4330,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
});
|
||||
|
||||
mSecondSplitHiddenView = containerTaskView;
|
||||
mSecondSplitHiddenView.setThumbnailVisibility(INVISIBLE);
|
||||
if (mSecondSplitHiddenView != null) {
|
||||
mSecondSplitHiddenView.setThumbnailVisibility(INVISIBLE);
|
||||
}
|
||||
|
||||
InteractionJankMonitorWrapper.begin(this,
|
||||
InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER, "Second tile selected");
|
||||
|
||||
@@ -621,7 +621,8 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
TaskIdAttributeContainer container = mTaskIdAttributeContainer[index];
|
||||
if (container != null) {
|
||||
return getRecentsView().confirmSplitSelect(this, container.getTask(),
|
||||
container.getIconView(), container.getThumbnailView());
|
||||
container.getIconView().getDrawable(), container.getThumbnailView(),
|
||||
container.getThumbnailView().getThumbnail(), /* intent */ null);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user