Merge "Added shared lib APIs for Launcher to use split-screen APIs." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
0799ee7fd7
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.recents;
|
||||
|
||||
/**
|
||||
* Listener interface that Launcher attaches to SystemUI to get split-screen callbacks.
|
||||
*/
|
||||
oneway interface ISplitScreenListener {
|
||||
void onStagePositionChanged(int stage, int position);
|
||||
void onTaskStageChanged(int taskId, int stage);
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.shared.recents;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.app.PictureInPictureParams;
|
||||
import android.content.ComponentName;
|
||||
import android.content.pm.ActivityInfo;
|
||||
@@ -23,9 +24,11 @@ import android.graphics.Bitmap;
|
||||
import android.graphics.Insets;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.systemui.shared.recents.IPinnedStackAnimationListener;
|
||||
import com.android.systemui.shared.recents.ISplitScreenListener;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.system.RemoteTransitionCompat;
|
||||
|
||||
@@ -202,4 +205,49 @@ interface ISystemUiProxy {
|
||||
|
||||
/** Unegisters a RemoteTransitionCompat that will handle transitions. */
|
||||
void unregisterRemoteTransition(in RemoteTransitionCompat remoteTransition) = 33;
|
||||
|
||||
// SplitScreen APIs...copied from SplitScreen.java
|
||||
/**
|
||||
* Stage position isn't specified normally meaning to use what ever it is currently set to.
|
||||
*/
|
||||
//int STAGE_POSITION_UNDEFINED = -1;
|
||||
/**
|
||||
* Specifies that a stage is positioned at the top half of the screen if
|
||||
* in portrait mode or at the left half of the screen if in landscape mode.
|
||||
*/
|
||||
//int STAGE_POSITION_TOP_OR_LEFT = 0;
|
||||
/**
|
||||
* Specifies that a stage is positioned at the bottom half of the screen if
|
||||
* in portrait mode or at the right half of the screen if in landscape mode.
|
||||
*/
|
||||
//int STAGE_POSITION_BOTTOM_OR_RIGHT = 1;
|
||||
|
||||
/**
|
||||
* Stage type isn't specified normally meaning to use what ever the default is.
|
||||
* E.g. exit split-screen and launch the app in fullscreen.
|
||||
*/
|
||||
//int STAGE_TYPE_UNDEFINED = -1;
|
||||
/**
|
||||
* The main stage type.
|
||||
* @see MainStage
|
||||
*/
|
||||
//int STAGE_TYPE_MAIN = 0;
|
||||
/**
|
||||
* The side stage type.
|
||||
* @see SideStage
|
||||
*/
|
||||
//int STAGE_TYPE_SIDE = 1;
|
||||
|
||||
void registerSplitScreenListener(in ISplitScreenListener listener) = 34;
|
||||
void unregisterSplitScreenListener(in ISplitScreenListener listener) = 35;
|
||||
|
||||
/** Hides the side-stage if it is currently visible. */
|
||||
void setSideStageVisibility(in boolean visible) = 36;
|
||||
/** Removes the split-screen stages. */
|
||||
void exitSplitScreen() = 37;
|
||||
void startTask(in int taskId, in int stage, in int position, in Bundle options) = 38;
|
||||
void startShortcut(in String packageName, in String shortcutId, in int stage, in int position,
|
||||
in Bundle options, in UserHandle user) = 39;
|
||||
void startIntent(
|
||||
in PendingIntent intent, in int stage, in int position, in Bundle options) = 40;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_T
|
||||
|
||||
import android.annotation.FloatRange;
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.PictureInPictureParams;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
@@ -83,6 +84,7 @@ import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
|
||||
import com.android.systemui.settings.CurrentUserTracker;
|
||||
import com.android.systemui.shared.recents.IOverviewProxy;
|
||||
import com.android.systemui.shared.recents.IPinnedStackAnimationListener;
|
||||
import com.android.systemui.shared.recents.ISplitScreenListener;
|
||||
import com.android.systemui.shared.recents.ISystemUiProxy;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
@@ -98,6 +100,7 @@ import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
|
||||
import com.android.wm.shell.onehanded.OneHanded;
|
||||
import com.android.wm.shell.pip.Pip;
|
||||
import com.android.wm.shell.pip.PipAnimationController;
|
||||
import com.android.wm.shell.splitscreen.SplitScreen;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
@@ -133,7 +136,8 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
||||
private final Context mContext;
|
||||
private final Optional<Pip> mPipOptional;
|
||||
private final Optional<Lazy<StatusBar>> mStatusBarOptionalLazy;
|
||||
private final Optional<LegacySplitScreen> mSplitScreenOptional;
|
||||
private final Optional<LegacySplitScreen> mLegacySplitScreenOptional;
|
||||
private final Optional<SplitScreen> mSplitScreenOptional;
|
||||
private SysUiState mSysUiState;
|
||||
private final Handler mHandler;
|
||||
private final Lazy<NavigationBarController> mNavBarControllerLazy;
|
||||
@@ -263,7 +267,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
||||
}
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return mSplitScreenOptional.map(splitScreen ->
|
||||
return mLegacySplitScreenOptional.map(splitScreen ->
|
||||
splitScreen.getDividerView().getNonMinimizedSplitScreenSecondaryBounds())
|
||||
.orElse(null);
|
||||
} finally {
|
||||
@@ -401,7 +405,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
||||
|
||||
@Override
|
||||
public void setSplitScreenMinimized(boolean minimized) {
|
||||
mSplitScreenOptional.ifPresent(
|
||||
mLegacySplitScreenOptional.ifPresent(
|
||||
splitScreen -> splitScreen.setMinimized(minimized));
|
||||
}
|
||||
|
||||
@@ -559,6 +563,105 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerSplitScreenListener(ISplitScreenListener listener) {
|
||||
if (!verifyCaller("registerSplitScreenListener")) {
|
||||
return;
|
||||
}
|
||||
mISplitScreenListener = listener;
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mSplitScreenOptional.ifPresent(
|
||||
s -> s.registerSplitScreenListener(mSplitScreenListener));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterSplitScreenListener(ISplitScreenListener listener) {
|
||||
if (!verifyCaller("unregisterSplitScreenListener")) {
|
||||
return;
|
||||
}
|
||||
mISplitScreenListener = null;
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mSplitScreenOptional.ifPresent(
|
||||
s -> s.unregisterSplitScreenListener(mSplitScreenListener));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSideStageVisibility(boolean visible) {
|
||||
if (!verifyCaller("setSideStageVisibility")) {
|
||||
return;
|
||||
}
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mSplitScreenOptional.ifPresent(s -> s.setSideStageVisibility(visible));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitSplitScreen() {
|
||||
if (!verifyCaller("exitSplitScreen")) {
|
||||
return;
|
||||
}
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mSplitScreenOptional.ifPresent(s -> s.exitSplitScreen());
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startTask(int taskId, int stage, int position, Bundle options) {
|
||||
if (!verifyCaller("startTask")) {
|
||||
return;
|
||||
}
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mSplitScreenOptional.ifPresent(
|
||||
s -> s.startTask(taskId, stage, position, options));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startShortcut(String packageName, String shortcutId, int stage, int position,
|
||||
Bundle options, UserHandle user) {
|
||||
if (!verifyCaller("startShortcut")) {
|
||||
return;
|
||||
}
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mSplitScreenOptional.ifPresent(s ->
|
||||
s.startShortcut(packageName, shortcutId, stage, position, options, user));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startIntent(PendingIntent intent, int stage, int position, Bundle options) {
|
||||
if (!verifyCaller("startIntent")) {
|
||||
return;
|
||||
}
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mSplitScreenOptional.ifPresent(s ->
|
||||
s.startIntent(intent, stage, position, options));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean verifyCaller(String reason) {
|
||||
final int callerId = Binder.getCallingUserHandle().getIdentifier();
|
||||
if (callerId != mCurrentBoundedUserId) {
|
||||
@@ -658,6 +761,32 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
||||
private final IBinder.DeathRecipient mOverviewServiceDeathRcpt
|
||||
= this::cleanupAfterDeath;
|
||||
|
||||
private ISplitScreenListener mISplitScreenListener;
|
||||
private final SplitScreen.SplitScreenListener mSplitScreenListener =
|
||||
new SplitScreen.SplitScreenListener() {
|
||||
@Override
|
||||
public void onStagePositionChanged(int stage, int position) {
|
||||
try {
|
||||
if (mISplitScreenListener != null) {
|
||||
mISplitScreenListener.onStagePositionChanged(stage, position);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG_OPS, "onStagePositionChanged", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskStageChanged(int taskId, int stage) {
|
||||
try {
|
||||
if (mISplitScreenListener != null) {
|
||||
mISplitScreenListener.onTaskStageChanged(taskId, stage);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG_OPS, "onTaskStageChanged", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
@Inject
|
||||
public OverviewProxyService(Context context, CommandQueue commandQueue,
|
||||
@@ -665,7 +794,8 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
||||
NavigationModeController navModeController,
|
||||
NotificationShadeWindowController statusBarWinController, SysUiState sysUiState,
|
||||
Optional<Pip> pipOptional,
|
||||
Optional<LegacySplitScreen> splitScreenOptional,
|
||||
Optional<LegacySplitScreen> legacySplitScreenOptional,
|
||||
Optional<SplitScreen> splitScreenOptional,
|
||||
Optional<Lazy<StatusBar>> statusBarOptionalLazy,
|
||||
Optional<OneHanded> oneHandedOptional,
|
||||
BroadcastDispatcher broadcastDispatcher,
|
||||
@@ -718,9 +848,10 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
||||
});
|
||||
mCommandQueue = commandQueue;
|
||||
|
||||
splitScreenOptional.ifPresent(splitScreen ->
|
||||
splitScreen.registerBoundsChangeListener(mSplitScreenBoundsChangeListener));
|
||||
mSplitScreenOptional = splitScreenOptional;
|
||||
legacySplitScreenOptional.ifPresent(splitScreen ->
|
||||
splitScreen.registerBoundsChangeListener(mSplitScreenBoundsChangeListener));
|
||||
mLegacySplitScreenOptional = legacySplitScreenOptional;
|
||||
|
||||
// Listen for user setup
|
||||
startTracking();
|
||||
@@ -835,7 +966,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
|
||||
startConnectionToCurrentUser();
|
||||
|
||||
// Clean up the minimized state if launcher dies
|
||||
mSplitScreenOptional.ifPresent(
|
||||
mLegacySplitScreenOptional.ifPresent(
|
||||
splitScreen -> splitScreen.setMinimized(false));
|
||||
|
||||
// Clean up any registered remote transitions
|
||||
|
||||
@@ -42,6 +42,7 @@ import com.android.systemui.statusbar.NotificationShadeWindowController;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
|
||||
import com.android.wm.shell.pip.Pip;
|
||||
import com.android.wm.shell.splitscreen.SplitScreen;
|
||||
import com.android.wm.shell.transition.Transitions;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -71,7 +72,8 @@ public class OverviewProxyServiceTest extends SysuiTestCase {
|
||||
@Mock private NavigationModeController mMockNavModeController;
|
||||
@Mock private NotificationShadeWindowController mMockStatusBarWinController;
|
||||
@Mock private Optional<Pip> mMockPipOptional;
|
||||
@Mock private Optional<LegacySplitScreen> mMockSplitScreenOptional;
|
||||
@Mock private Optional<LegacySplitScreen> mMockLegacySplitScreenOptional;
|
||||
@Mock private Optional<SplitScreen> mMockSplitScreenOptional;
|
||||
@Mock private Optional<Lazy<StatusBar>> mMockStatusBarOptionalLazy;
|
||||
@Mock private Optional<com.android.wm.shell.onehanded.OneHanded> mMockOneHandedOptional;
|
||||
@Mock private PackageManager mPackageManager;
|
||||
@@ -89,8 +91,8 @@ public class OverviewProxyServiceTest extends SysuiTestCase {
|
||||
|
||||
mSpiedOverviewProxyService = spy(new OverviewProxyService(mSpiedContext, mMockCommandQueue,
|
||||
mMockNavBarControllerLazy, mMockNavModeController, mMockStatusBarWinController,
|
||||
mMockSysUiState, mMockPipOptional, mMockSplitScreenOptional,
|
||||
mMockStatusBarOptionalLazy, mMockOneHandedOptional,
|
||||
mMockSysUiState, mMockPipOptional, mMockLegacySplitScreenOptional,
|
||||
mMockSplitScreenOptional, mMockStatusBarOptionalLazy, mMockOneHandedOptional,
|
||||
mMockBroadcastDispatcher, mMockTransitions));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user