diff options
| author | 2017-11-17 13:04:07 -0800 | |
|---|---|---|
| committer | 2017-11-27 19:02:04 +0000 | |
| commit | 42ce900d485bee1c0934543f7cd0f4da652bbb04 (patch) | |
| tree | 82ce6b4f1f73ce5ab8340886fdbceb0575add5b5 | |
| parent | 15176cd986b0970c636036f60e97d5be53f3ce91 (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>
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(); |