summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Winson Chung <winsonc@google.com> 2017-11-17 13:04:07 -0800
committer Winson Chung <winsonc@google.com> 2017-11-27 19:02:04 +0000
commit42ce900d485bee1c0934543f7cd0f4da652bbb04 (patch)
tree82ce6b4f1f73ce5ab8340886fdbceb0575add5b5
parent15176cd986b0970c636036f60e97d5be53f3ce91 (diff)
Expose methods to invoke split screen.
- Also remove duplicate code in shortcut key dispatcher. Bug: 67510855 Test: Drag and dock in Recents Change-Id: I46634ab0585d29edd2068a6149cffa928f729d33 Signed-off-by: Winson Chung <winsonc@google.com>
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java43
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java41
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java18
6 files changed, 114 insertions, 84 deletions
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index f6fab86cefaa..eb2d12edd059 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -319,32 +319,39 @@ public class ActivityManagerWrapper {
mBackgroundExecutor.submit(new Runnable() {
@Override
public void run() {
+ boolean result = false;
try {
- ActivityManager.getService().startActivityFromRecents(taskKey.id,
- finalOptions == null ? null : finalOptions.toBundle());
- if (resultCallback != null) {
- resultCallbackHandler.post(new Runnable() {
- @Override
- public void run() {
- resultCallback.accept(true);
- }
- });
- }
+ result = startActivityFromRecents(taskKey.id, finalOptions);
} catch (Exception e) {
- if (resultCallback != null) {
- resultCallbackHandler.post(new Runnable() {
- @Override
- public void run() {
- resultCallback.accept(false);
- }
- });
- }
+ // Fall through
+ }
+ final boolean finalResult = result;
+ if (resultCallback != null) {
+ resultCallbackHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ resultCallback.accept(finalResult);
+ }
+ });
}
}
});
}
/**
+ * Starts a task from Recents synchronously.
+ */
+ public boolean startActivityFromRecents(int taskId, ActivityOptions options) {
+ try {
+ Bundle optsBundle = options == null ? null : options.toBundle();
+ ActivityManager.getService().startActivityFromRecents(taskId, optsBundle);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
* Registers a task stack listener with the system.
* This should be called on the main thread.
*/
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java
new file mode 100644
index 000000000000..705a21522b0a
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java
@@ -0,0 +1,41 @@
+/*
+ * 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.systemui.shared.system;
+
+import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT;
+import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+
+import android.app.ActivityOptions;
+
+/**
+ * Wrapper around internal ActivityOptions creation.
+ */
+public abstract class ActivityOptionsCompat {
+
+ /**
+ * @return ActivityOptions for starting a task in split screen.
+ */
+ public static ActivityOptions makeSplitScreenOptions(boolean dockTopLeft) {
+ final ActivityOptions options = ActivityOptions.makeBasic();
+ options.setLaunchWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+ options.setSplitScreenCreateMode(dockTopLeft
+ ? SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT
+ : SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT);
+ return options;
+ }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
index 1477558a0e97..225dbb4aafbe 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
@@ -19,8 +19,15 @@ package com.android.systemui.shared.system;
import static android.view.Display.DEFAULT_DISPLAY;
import android.graphics.Rect;
+import android.os.Handler;
+import android.os.IRemoteCallback;
+import android.os.RemoteException;
+import android.util.Log;
import android.view.WindowManagerGlobal;
+import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture;
+import com.android.systemui.shared.recents.view.RecentsTransition;
+
public class WindowManagerWrapper {
private static final String TAG = "WindowManagerWrapper";
@@ -38,8 +45,24 @@ public class WindowManagerWrapper {
try {
WindowManagerGlobal.getWindowManagerService().getStableInsets(DEFAULT_DISPLAY,
outStableInsets);
- } catch (Exception e) {
- e.printStackTrace();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to get stable insets", e);
+ }
+ }
+
+ /**
+ * Overrides a pending app transition.
+ */
+ public void overridePendingAppTransitionMultiThumbFuture(
+ AppTransitionAnimationSpecsFuture animationSpecFuture,
+ Runnable animStartedCallback, Handler animStartedCallbackHandler, boolean scaleUp) {
+ try {
+ WindowManagerGlobal.getWindowManagerService()
+ .overridePendingAppTransitionMultiThumbFuture(animationSpecFuture.getFuture(),
+ RecentsTransition.wrapStartedListener(animStartedCallbackHandler,
+ animStartedCallback), scaleUp);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to override pending app transition (multi-thumbnail future): ", e);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index d89bab758bd0..cf3cae5a7c04 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -21,12 +21,10 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager.StackInfo;
import android.app.ActivityOptions;
@@ -49,9 +47,6 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.IRemoteCallback;
-import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
@@ -63,7 +58,6 @@ import android.service.dreams.IDreamManager;
import android.util.Log;
import android.util.MutableBoolean;
import android.view.Display;
-import android.view.IAppTransitionAnimationSpecsFuture;
import android.view.IDockedStackListener;
import android.view.IWindowManager;
import android.view.WindowManager;
@@ -78,12 +72,9 @@ import com.android.systemui.R;
import com.android.systemui.UiOffloadThread;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsImpl;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.systemui.statusbar.policy.UserInfoController;
import java.util.List;
-import java.util.function.Consumer;
/**
* Acts as a shim around the real system services that we need to access data from, and provides
@@ -268,22 +259,6 @@ public class SystemServicesProxy {
return mIsSafeMode;
}
- /** Docks a task to the side of the screen and starts it. */
- public boolean startTaskInDockedMode(int taskId, int createMode) {
- if (mIam == null) return false;
-
- try {
- final ActivityOptions options = ActivityOptions.makeBasic();
- options.setSplitScreenCreateMode(createMode);
- options.setLaunchWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
- mIam.startActivityFromRecents(taskId, options.toBundle());
- return true;
- } catch (Exception e) {
- Log.e(TAG, "Failed to dock task: " + taskId + " with createMode: " + createMode, e);
- }
- return false;
- }
-
/** Moves an already resumed task to the side of the screen to initiate split screen. */
public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
Rect initialBounds) {
@@ -540,16 +515,6 @@ public class SystemServicesProxy {
}
}
- public void overridePendingAppTransitionMultiThumbFuture(
- IAppTransitionAnimationSpecsFuture future, IRemoteCallback animStartedListener,
- boolean scaleUp) {
- try {
- mIwm.overridePendingAppTransitionMultiThumbFuture(future, animStartedListener, scaleUp);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to override transition: " + e);
- }
- }
-
/**
* Updates the visibility of recents.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 1440fc168cc6..e3ed1aaa5506 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -16,13 +16,14 @@
package com.android.systemui.recents.views;
+import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
+
import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.Nullable;
import android.app.ActivityOptions;
-import android.app.ActivityOptions.OnAnimationStartedListener;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
@@ -33,11 +34,11 @@ import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
+import android.os.IRemoteCallback;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.Log;
import android.util.MathUtils;
-import android.view.AppTransitionAnimationSpec;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -86,13 +87,15 @@ import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
import com.android.systemui.recents.misc.ReferenceCountedTrigger;
import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.shared.recents.utilities.Utilities;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.TaskStack;
+import com.android.systemui.shared.recents.utilities.Utilities;
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.ActivityManagerWrapper;
+import com.android.systemui.shared.system.ActivityOptionsCompat;
+import com.android.systemui.shared.system.WindowManagerWrapper;
import com.android.systemui.stackdivider.WindowManagerProxy;
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.phone.ScrimController;
@@ -608,16 +611,17 @@ public class RecentsView extends FrameLayout {
// rect to its final layout-space rect
Utilities.setViewFrameFromTranslation(event.taskView);
- // Dock the task and launch it
- SystemServicesProxy ssp = Recents.getSystemServices();
- if (ssp.startTaskInDockedMode(event.task.key.id, dockState.createMode)) {
+ final ActivityOptions options = ActivityOptionsCompat.makeSplitScreenOptions(
+ dockState.createMode == SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT);
+ if (ActivityManagerWrapper.getInstance().startActivityFromRecents(event.task.key.id,
+ options)) {
final Runnable animStartedListener = () -> {
EventBus.getDefault().send(new DockedFirstAnimationFrameEvent());
- // Remove the task and don't bother relaying out, as all the tasks will be
- // relaid out when the stack changes on the multiwindow change event
+ // Remove the task and don't bother relaying out, as all the tasks
+ // will be relaid out when the stack changes on the multiwindow
+ // change event
getStack().removeTask(event.task, null, true /* fromDockGesture */);
};
-
final Rect taskRect = getTaskRect(event.taskView);
AppTransitionAnimationSpecsFuture future = new AppTransitionAnimationSpecsFuture(
getHandler()) {
@@ -626,10 +630,8 @@ public class RecentsView extends FrameLayout {
return mTransitionHelper.composeDockAnimationSpec(event.taskView, taskRect);
}
};
- ssp.overridePendingAppTransitionMultiThumbFuture(future.getFuture(),
- RecentsTransition.wrapStartedListener(getHandler(), animStartedListener),
- true /* scaleUp */);
-
+ WindowManagerWrapper.getInstance().overridePendingAppTransitionMultiThumbFuture(
+ future, animStartedListener, getHandler(), true /* scaleUp */);
MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_DRAG_DROP,
event.task.getTopComponent().flattenToShortString());
} else {
@@ -1032,11 +1034,9 @@ public class RecentsView extends FrameLayout {
if (taskIndex > -1) {
taskIndexFromFront = stack.getTaskCount() - taskIndex - 1;
}
- EventBus.getDefault().send(new LaunchTaskSucceededEvent(
- taskIndexFromFront));
+ EventBus.getDefault().send(new LaunchTaskSucceededEvent(taskIndexFromFront));
} else {
- Log.e(TAG, mContext.getString(R.string.recents_launch_error_message,
- task.title));
+ Log.e(TAG, mContext.getString(R.string.recents_launch_error_message, task.title));
// Dismiss the task if we fail to launch it
if (taskView != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
index 1cda30111db8..da798848f7e8 100644
--- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
@@ -20,6 +20,8 @@ import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIG
import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
import static android.os.UserHandle.USER_CURRENT;
+import static com.android.systemui.statusbar.phone.NavigationBarGestureHelper.DRAG_MODE_NONE;
+
import android.app.ActivityManager;
import android.content.res.Configuration;
import android.os.RemoteException;
@@ -36,6 +38,7 @@ import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.stackdivider.DividerView;
+import com.android.systemui.statusbar.phone.NavigationBarGestureHelper;
import java.util.List;
@@ -89,20 +92,11 @@ public class ShortcutKeyDispatcher extends SystemUI
try {
int dockSide = mWindowManagerService.getDockedStackSide();
if (dockSide == WindowManager.DOCKED_INVALID) {
- // If there is no window docked, we dock the top-most window.
+ // Split the screen
Recents recents = getComponent(Recents.class);
- int dockMode = (shortcutCode == SC_DOCK_LEFT)
+ recents.splitPrimaryTask(DRAG_MODE_NONE, (shortcutCode == SC_DOCK_LEFT)
? SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT
- : SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT;
- List<ActivityManager.RecentTaskInfo> taskList =
- ActivityManagerWrapper.getInstance().getRecentTasks(1, USER_CURRENT);
- recents.showRecentApps(
- false /* triggeredFromAltTab */,
- false /* fromHome */);
- if (!taskList.isEmpty()) {
- SystemServicesProxy.getInstance(mContext).startTaskInDockedMode(
- taskList.get(0).id, dockMode);
- }
+ : SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT, null, -1);
} else {
// If there is already a docked window, we respond by resizing the docking pane.
DividerView dividerView = getComponent(Divider.class).getView();