summaryrefslogtreecommitdiffstats
path: root/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
diff options
context:
space:
mode:
authorKevin <kevhan@google.com>2019-02-25 14:41:54 -0800
committerKevin <kevhan@google.com>2019-02-25 14:53:04 -0800
commit576d203a913680d8d81a3a39c1a19b8207a40985 (patch)
tree548a4c83fd9c0ebc1a921e6a3ac8684779ff21d4 /quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
parent6873fe517b1861e5695a0081152a10d08317b346 (diff)
downloadandroid_packages_apps_Trebuchet-576d203a913680d8d81a3a39c1a19b8207a40985.tar.gz
android_packages_apps_Trebuchet-576d203a913680d8d81a3a39c1a19b8207a40985.tar.bz2
android_packages_apps_Trebuchet-576d203a913680d8d81a3a39c1a19b8207a40985.zip
Remove several files from Recents Go src
As Go will not be using RecentsView, there are several files that are unneeded in the recents Go source. This moves these files to recents_ui_overrides where they will be used for non-Go builds. Bug: 114136250 Test: Build NexusLauncher, aospWithQuickstep, l3GoWithQuickstep Change-Id: I9d0154a75f4f2c71b865d414448e262b3019b2b9
Diffstat (limited to 'quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java')
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java333
1 files changed, 333 insertions, 0 deletions
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
new file mode 100644
index 000000000..42a28fbfa
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskSystemShortcut.java
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2018 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.userevent.nano.LauncherLogProto.Action.Touch.TAP;
+
+import android.app.Activity;
+import android.app.ActivityOptions;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+import android.view.View;
+
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.R;
+import com.android.launcher3.ShortcutInfo;
+import com.android.launcher3.popup.SystemShortcut;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.launcher3.util.InstantAppResolver;
+import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.TaskThumbnailView;
+import com.android.quickstep.views.TaskView;
+import com.android.systemui.shared.recents.ISystemUiProxy;
+import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecCompat;
+import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture;
+import com.android.systemui.shared.recents.view.RecentsTransition;
+import com.android.systemui.shared.system.ActivityCompat;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.ActivityOptionsCompat;
+import com.android.systemui.shared.system.WindowManagerWrapper;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Consumer;
+
+/**
+ * Represents a system shortcut that can be shown for a recent task.
+ */
+public class TaskSystemShortcut<T extends SystemShortcut> extends SystemShortcut {
+
+ private static final String TAG = "TaskSystemShortcut";
+
+ protected T mSystemShortcut;
+
+ public TaskSystemShortcut(T systemShortcut) {
+ super(systemShortcut);
+ mSystemShortcut = systemShortcut;
+ }
+
+ protected TaskSystemShortcut(int iconResId, int labelResId) {
+ super(iconResId, labelResId);
+ }
+
+ @Override
+ public View.OnClickListener getOnClickListener(
+ BaseDraggingActivity activity, ItemInfo itemInfo) {
+ return null;
+ }
+
+ public View.OnClickListener getOnClickListener(BaseDraggingActivity activity, TaskView view) {
+ Task task = view.getTask();
+
+ ShortcutInfo dummyInfo = new ShortcutInfo();
+ dummyInfo.intent = new Intent();
+ ComponentName component = task.getTopComponent();
+ dummyInfo.intent.setComponent(component);
+ dummyInfo.user = UserHandle.of(task.key.userId);
+ dummyInfo.title = TaskUtils.getTitle(activity, task);
+
+ return getOnClickListenerForTask(activity, task, dummyInfo);
+ }
+
+ protected View.OnClickListener getOnClickListenerForTask(
+ BaseDraggingActivity activity, Task task, ItemInfo dummyInfo) {
+ return mSystemShortcut.getOnClickListener(activity, dummyInfo);
+ }
+
+ public static class AppInfo extends TaskSystemShortcut<SystemShortcut.AppInfo> {
+ public AppInfo() {
+ super(new SystemShortcut.AppInfo());
+ }
+ }
+
+ public static abstract class MultiWindow extends TaskSystemShortcut {
+
+ private Handler mHandler;
+
+ public MultiWindow(int iconRes, int textRes) {
+ super(iconRes, textRes);
+ mHandler = new Handler(Looper.getMainLooper());
+ }
+
+ protected abstract boolean isAvailable(BaseDraggingActivity activity);
+ protected abstract ActivityOptions makeLaunchOptions(Activity activity);
+ protected abstract boolean onActivityStarted(BaseDraggingActivity activity);
+
+ @Override
+ public View.OnClickListener getOnClickListener(
+ BaseDraggingActivity activity, TaskView taskView) {
+ if (!isAvailable(activity)) {
+ return null;
+ }
+ final Task task = taskView.getTask();
+ final int taskId = task.key.id;
+ if (!task.isDockable) {
+ return null;
+ }
+ final RecentsView recentsView = activity.getOverviewPanel();
+
+ final TaskThumbnailView thumbnailView = taskView.getThumbnail();
+ return (v -> {
+ final View.OnLayoutChangeListener onLayoutChangeListener =
+ new View.OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int l, int t, int r, int b,
+ int oldL, int oldT, int oldR, int oldB) {
+ taskView.getRootView().removeOnLayoutChangeListener(this);
+ recentsView.clearIgnoreResetTask(taskId);
+
+ // Start animating in the side pages once launcher has been resized
+ recentsView.dismissTask(taskView, false, false);
+ }
+ };
+
+ final DeviceProfile.OnDeviceProfileChangeListener onDeviceProfileChangeListener =
+ new DeviceProfile.OnDeviceProfileChangeListener() {
+ @Override
+ public void onDeviceProfileChanged(DeviceProfile dp) {
+ activity.removeOnDeviceProfileChangeListener(this);
+ if (dp.isMultiWindowMode) {
+ taskView.getRootView().addOnLayoutChangeListener(
+ onLayoutChangeListener);
+ }
+ }
+ };
+
+ dismissTaskMenuView(activity);
+
+ ActivityOptions options = makeLaunchOptions(activity);
+ if (options != null
+ && ActivityManagerWrapper.getInstance().startActivityFromRecents(taskId,
+ options)) {
+ if (!onActivityStarted(activity)) {
+ return;
+ }
+ // Add a device profile change listener to kick off animating the side tasks
+ // once we enter multiwindow mode and relayout
+ activity.addOnDeviceProfileChangeListener(onDeviceProfileChangeListener);
+
+ final Runnable animStartedListener = () -> {
+ // Hide the task view and wait for the window to be resized
+ // TODO: Consider animating in launcher and do an in-place start activity
+ // afterwards
+ recentsView.setIgnoreResetTask(taskId);
+ taskView.setAlpha(0f);
+ };
+
+ final int[] position = new int[2];
+ thumbnailView.getLocationOnScreen(position);
+ final int width = (int) (thumbnailView.getWidth() * taskView.getScaleX());
+ final int height = (int) (thumbnailView.getHeight() * taskView.getScaleY());
+ final Rect taskBounds = new Rect(position[0], position[1],
+ position[0] + width, position[1] + height);
+
+ // Take the thumbnail of the task without a scrim and apply it back after
+ float alpha = thumbnailView.getDimAlpha();
+ thumbnailView.setDimAlpha(0);
+ Bitmap thumbnail = RecentsTransition.drawViewIntoHardwareBitmap(
+ taskBounds.width(), taskBounds.height(), thumbnailView, 1f,
+ Color.BLACK);
+ thumbnailView.setDimAlpha(alpha);
+
+ AppTransitionAnimationSpecsFuture future =
+ new AppTransitionAnimationSpecsFuture(mHandler) {
+ @Override
+ public List<AppTransitionAnimationSpecCompat> composeSpecs() {
+ return Collections.singletonList(new AppTransitionAnimationSpecCompat(
+ taskId, thumbnail, taskBounds));
+ }
+ };
+ WindowManagerWrapper.getInstance().overridePendingAppTransitionMultiThumbFuture(
+ future, animStartedListener, mHandler, true /* scaleUp */,
+ v.getDisplay().getDisplayId());
+ }
+ });
+ }
+ }
+
+ public static class SplitScreen extends MultiWindow {
+ public SplitScreen() {
+ super(R.drawable.ic_split_screen, R.string.recent_task_option_split_screen);
+ }
+
+ @Override
+ protected boolean isAvailable(BaseDraggingActivity activity) {
+ // Don't show menu-item if already in multi-window
+ return !activity.getDeviceProfile().isMultiWindowMode;
+ }
+
+ @Override
+ protected ActivityOptions makeLaunchOptions(Activity activity) {
+ final ActivityCompat act = new ActivityCompat(activity);
+ final int navBarPosition = WindowManagerWrapper.getInstance().getNavBarPosition(
+ act.getDisplayId());
+ if (navBarPosition == WindowManagerWrapper.NAV_BAR_POS_INVALID) {
+ return null;
+ }
+ boolean dockTopOrLeft = navBarPosition != WindowManagerWrapper.NAV_BAR_POS_LEFT;
+ return ActivityOptionsCompat.makeSplitScreenOptions(dockTopOrLeft);
+ }
+
+ @Override
+ protected boolean onActivityStarted(BaseDraggingActivity activity) {
+ ISystemUiProxy sysUiProxy = RecentsModel.INSTANCE.get(activity).getSystemUiProxy();
+ try {
+ sysUiProxy.onSplitScreenInvoked();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to notify SysUI of split screen: ", e);
+ return false;
+ }
+ activity.getUserEventDispatcher().logActionOnControl(TAP,
+ LauncherLogProto.ControlType.SPLIT_SCREEN_TARGET);
+ return true;
+ }
+ }
+
+ public static class Freeform extends MultiWindow {
+ public Freeform() {
+ super(R.drawable.ic_split_screen, R.string.recent_task_option_freeform);
+ }
+
+ @Override
+ protected boolean isAvailable(BaseDraggingActivity activity) {
+ return ActivityManagerWrapper.getInstance().supportsFreeformMultiWindow(activity);
+ }
+
+ @Override
+ protected ActivityOptions makeLaunchOptions(Activity activity) {
+ return ActivityOptionsCompat.makeFreeformOptions();
+ }
+
+ @Override
+ protected boolean onActivityStarted(BaseDraggingActivity activity) {
+ Launcher.getLauncher(activity).getStateManager().goToState(LauncherState.NORMAL);
+ return true;
+ }
+ }
+
+ public static class Pin extends TaskSystemShortcut {
+
+ private static final String TAG = Pin.class.getSimpleName();
+
+ private Handler mHandler;
+
+ public Pin() {
+ super(R.drawable.ic_pin, R.string.recent_task_option_pin);
+ mHandler = new Handler(Looper.getMainLooper());
+ }
+
+ @Override
+ public View.OnClickListener getOnClickListener(
+ BaseDraggingActivity activity, TaskView taskView) {
+ ISystemUiProxy sysUiProxy = RecentsModel.INSTANCE.get(activity).getSystemUiProxy();
+ if (sysUiProxy == null) {
+ return null;
+ }
+ if (!ActivityManagerWrapper.getInstance().isScreenPinningEnabled()) {
+ return null;
+ }
+ if (ActivityManagerWrapper.getInstance().isLockToAppActive()) {
+ // We shouldn't be able to pin while an app is locked.
+ return null;
+ }
+ return view -> {
+ Consumer<Boolean> resultCallback = success -> {
+ if (success) {
+ try {
+ sysUiProxy.startScreenPinning(taskView.getTask().key.id);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to start screen pinning: ", e);
+ }
+ } else {
+ taskView.notifyTaskLaunchFailed(TAG);
+ }
+ };
+ taskView.launchTask(true, resultCallback, mHandler);
+ dismissTaskMenuView(activity);
+ };
+ }
+ }
+
+ public static class Install extends TaskSystemShortcut<SystemShortcut.Install> {
+ public Install() {
+ super(new SystemShortcut.Install());
+ }
+
+ @Override
+ protected View.OnClickListener getOnClickListenerForTask(
+ BaseDraggingActivity activity, Task task, ItemInfo itemInfo) {
+ if (InstantAppResolver.newInstance(activity).isInstantApp(activity,
+ task.getTopComponent().getPackageName())) {
+ return mSystemShortcut.createOnClickListener(activity, itemInfo);
+ }
+ return null;
+ }
+ }
+}