Merge "Add logging for splitscreen" into sc-v2-dev
This commit is contained in:
@@ -158,6 +158,15 @@ public final class SplitLayout {
|
|||||||
return mDividePosition;
|
return mDividePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the divider position as a fraction from 0 to 1.
|
||||||
|
*/
|
||||||
|
public float getDividerPositionAsFraction() {
|
||||||
|
return Math.min(1f, Math.max(0f, isLandscape()
|
||||||
|
? (float) ((mBounds1.right + mBounds2.left) / 2f) / mBounds2.right
|
||||||
|
: (float) ((mBounds1.bottom + mBounds2.top) / 2f) / mBounds2.bottom));
|
||||||
|
}
|
||||||
|
|
||||||
/** Applies new configuration, returns {@code false} if there's no effect to the layout. */
|
/** Applies new configuration, returns {@code false} if there's no effect to the layout. */
|
||||||
public boolean updateConfiguration(Configuration configuration) {
|
public boolean updateConfiguration(Configuration configuration) {
|
||||||
boolean affectsLayout = false;
|
boolean affectsLayout = false;
|
||||||
@@ -342,6 +351,13 @@ public final class SplitLayout {
|
|||||||
return bounds.width() > bounds.height();
|
return bounds.width() > bounds.height();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return if this layout is landscape.
|
||||||
|
*/
|
||||||
|
public boolean isLandscape() {
|
||||||
|
return isLandscape(mRootBounds);
|
||||||
|
}
|
||||||
|
|
||||||
/** Apply recorded surface layout to the {@link SurfaceControl.Transaction}. */
|
/** Apply recorded surface layout to the {@link SurfaceControl.Transaction}. */
|
||||||
public void applySurfaceChanges(SurfaceControl.Transaction t, SurfaceControl leash1,
|
public void applySurfaceChanges(SurfaceControl.Transaction t, SurfaceControl leash1,
|
||||||
SurfaceControl leash2, SurfaceControl dimLayer1, SurfaceControl dimLayer2) {
|
SurfaceControl leash2, SurfaceControl dimLayer1, SurfaceControl dimLayer2) {
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import android.view.ViewGroup;
|
|||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
|
import com.android.internal.logging.InstanceId;
|
||||||
import com.android.internal.logging.UiEventLogger;
|
import com.android.internal.logging.UiEventLogger;
|
||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
import com.android.wm.shell.R;
|
import com.android.wm.shell.R;
|
||||||
@@ -180,11 +181,11 @@ public class DragAndDropController implements DisplayController.OnDisplaysChange
|
|||||||
Slog.w(TAG, "Unexpected drag start during an active drag");
|
Slog.w(TAG, "Unexpected drag start during an active drag");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
InstanceId loggerSessionId = mLogger.logStart(event);
|
||||||
pd.activeDragCount++;
|
pd.activeDragCount++;
|
||||||
pd.dragLayout.prepare(mDisplayController.getDisplayLayout(displayId),
|
pd.dragLayout.prepare(mDisplayController.getDisplayLayout(displayId),
|
||||||
event.getClipData());
|
event.getClipData(), loggerSessionId);
|
||||||
setDropTargetWindowVisibility(pd, View.VISIBLE);
|
setDropTargetWindowVisibility(pd, View.VISIBLE);
|
||||||
mLogger.logStart(event);
|
|
||||||
break;
|
break;
|
||||||
case ACTION_DRAG_ENTERED:
|
case ACTION_DRAG_ENTERED:
|
||||||
pd.dragLayout.show();
|
pd.dragLayout.show();
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public class DragAndDropEventLogger {
|
|||||||
/**
|
/**
|
||||||
* Logs the start of a drag.
|
* Logs the start of a drag.
|
||||||
*/
|
*/
|
||||||
public void logStart(DragEvent event) {
|
public InstanceId logStart(DragEvent event) {
|
||||||
final ClipDescription description = event.getClipDescription();
|
final ClipDescription description = event.getClipDescription();
|
||||||
final ClipData data = event.getClipData();
|
final ClipData data = event.getClipData();
|
||||||
final ClipData.Item item = data.getItemAt(0);
|
final ClipData.Item item = data.getItemAt(0);
|
||||||
@@ -64,6 +64,7 @@ public class DragAndDropEventLogger {
|
|||||||
mUiEventLogger.logWithInstanceId(getStartEnum(description),
|
mUiEventLogger.logWithInstanceId(getStartEnum(description),
|
||||||
mActivityInfo.applicationInfo.uid,
|
mActivityInfo.applicationInfo.uid,
|
||||||
mActivityInfo.applicationInfo.packageName, mInstanceId);
|
mActivityInfo.applicationInfo.packageName, mInstanceId);
|
||||||
|
return mInstanceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
|
import com.android.internal.logging.InstanceId;
|
||||||
import com.android.wm.shell.common.DisplayLayout;
|
import com.android.wm.shell.common.DisplayLayout;
|
||||||
import com.android.wm.shell.common.split.SplitLayout.SplitPosition;
|
import com.android.wm.shell.common.split.SplitLayout.SplitPosition;
|
||||||
import com.android.wm.shell.splitscreen.SplitScreen.StageType;
|
import com.android.wm.shell.splitscreen.SplitScreen.StageType;
|
||||||
@@ -86,6 +87,7 @@ public class DragAndDropPolicy {
|
|||||||
private final SplitScreenController mSplitScreen;
|
private final SplitScreenController mSplitScreen;
|
||||||
private final ArrayList<DragAndDropPolicy.Target> mTargets = new ArrayList<>();
|
private final ArrayList<DragAndDropPolicy.Target> mTargets = new ArrayList<>();
|
||||||
|
|
||||||
|
private InstanceId mLoggerSessionId;
|
||||||
private DragSession mSession;
|
private DragSession mSession;
|
||||||
|
|
||||||
public DragAndDropPolicy(Context context, SplitScreenController splitScreen) {
|
public DragAndDropPolicy(Context context, SplitScreenController splitScreen) {
|
||||||
@@ -104,7 +106,8 @@ public class DragAndDropPolicy {
|
|||||||
/**
|
/**
|
||||||
* Starts a new drag session with the given initial drag data.
|
* Starts a new drag session with the given initial drag data.
|
||||||
*/
|
*/
|
||||||
void start(DisplayLayout displayLayout, ClipData data) {
|
void start(DisplayLayout displayLayout, ClipData data, InstanceId loggerSessionId) {
|
||||||
|
mLoggerSessionId = loggerSessionId;
|
||||||
mSession = new DragSession(mContext, mActivityTaskManager, displayLayout, data);
|
mSession = new DragSession(mContext, mActivityTaskManager, displayLayout, data);
|
||||||
// TODO(b/169894807): Also update the session data with task stack changes
|
// TODO(b/169894807): Also update the session data with task stack changes
|
||||||
mSession.update();
|
mSession.update();
|
||||||
@@ -207,6 +210,8 @@ public class DragAndDropPolicy {
|
|||||||
// Launch in the side stage if we are not in split-screen already.
|
// Launch in the side stage if we are not in split-screen already.
|
||||||
stage = STAGE_TYPE_SIDE;
|
stage = STAGE_TYPE_SIDE;
|
||||||
}
|
}
|
||||||
|
// Add some data for logging splitscreen once it is invoked
|
||||||
|
mSplitScreen.logOnDroppedToSplit(position, mLoggerSessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
final ClipDescription description = data.getDescription();
|
final ClipDescription description = data.getDescription();
|
||||||
@@ -294,7 +299,12 @@ public class DragAndDropPolicy {
|
|||||||
@StageType int stage, @SplitPosition int position,
|
@StageType int stage, @SplitPosition int position,
|
||||||
@Nullable Bundle options);
|
@Nullable Bundle options);
|
||||||
void enterSplitScreen(int taskId, boolean leftOrTop);
|
void enterSplitScreen(int taskId, boolean leftOrTop);
|
||||||
void exitSplitScreen();
|
|
||||||
|
/**
|
||||||
|
* Exits splitscreen, with an associated exit trigger from the SplitscreenUIChanged proto
|
||||||
|
* for logging.
|
||||||
|
*/
|
||||||
|
void exitSplitScreen(int exitTrigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -347,7 +357,7 @@ public class DragAndDropPolicy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exitSplitScreen() {
|
public void exitSplitScreen(int exitTrigger) {
|
||||||
throw new UnsupportedOperationException("exitSplitScreen not implemented by starter");
|
throw new UnsupportedOperationException("exitSplitScreen not implemented by starter");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import android.view.WindowInsets.Type;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import com.android.internal.logging.InstanceId;
|
||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
import com.android.wm.shell.R;
|
import com.android.wm.shell.R;
|
||||||
import com.android.wm.shell.common.DisplayLayout;
|
import com.android.wm.shell.common.DisplayLayout;
|
||||||
@@ -98,8 +99,9 @@ public class DragLayout extends View {
|
|||||||
return mHasDropped;
|
return mHasDropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void prepare(DisplayLayout displayLayout, ClipData initialData) {
|
public void prepare(DisplayLayout displayLayout, ClipData initialData,
|
||||||
mPolicy.start(displayLayout, initialData);
|
InstanceId loggerSessionId) {
|
||||||
|
mPolicy.start(displayLayout, initialData, loggerSessionId);
|
||||||
mHasDropped = false;
|
mHasDropped = false;
|
||||||
mCurrentTarget = null;
|
mCurrentTarget = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ import androidx.annotation.BinderThread;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.android.internal.logging.InstanceId;
|
||||||
|
import com.android.internal.util.FrameworkStatsLog;
|
||||||
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
|
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
|
||||||
import com.android.wm.shell.ShellTaskOrganizer;
|
import com.android.wm.shell.ShellTaskOrganizer;
|
||||||
import com.android.wm.shell.common.DisplayImeController;
|
import com.android.wm.shell.common.DisplayImeController;
|
||||||
@@ -61,7 +63,6 @@ import com.android.wm.shell.common.TransactionPool;
|
|||||||
import com.android.wm.shell.common.annotations.ExternalThread;
|
import com.android.wm.shell.common.annotations.ExternalThread;
|
||||||
import com.android.wm.shell.common.split.SplitLayout.SplitPosition;
|
import com.android.wm.shell.common.split.SplitLayout.SplitPosition;
|
||||||
import com.android.wm.shell.draganddrop.DragAndDropPolicy;
|
import com.android.wm.shell.draganddrop.DragAndDropPolicy;
|
||||||
import com.android.wm.shell.splitscreen.ISplitScreenListener;
|
|
||||||
import com.android.wm.shell.transition.LegacyTransitions;
|
import com.android.wm.shell.transition.LegacyTransitions;
|
||||||
import com.android.wm.shell.transition.Transitions;
|
import com.android.wm.shell.transition.Transitions;
|
||||||
|
|
||||||
@@ -86,6 +87,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
|||||||
private final DisplayImeController mDisplayImeController;
|
private final DisplayImeController mDisplayImeController;
|
||||||
private final Transitions mTransitions;
|
private final Transitions mTransitions;
|
||||||
private final TransactionPool mTransactionPool;
|
private final TransactionPool mTransactionPool;
|
||||||
|
private final SplitscreenEventLogger mLogger;
|
||||||
|
|
||||||
private StageCoordinator mStageCoordinator;
|
private StageCoordinator mStageCoordinator;
|
||||||
|
|
||||||
@@ -102,6 +104,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
|||||||
mDisplayImeController = displayImeController;
|
mDisplayImeController = displayImeController;
|
||||||
mTransitions = transitions;
|
mTransitions = transitions;
|
||||||
mTransactionPool = transactionPool;
|
mTransactionPool = transactionPool;
|
||||||
|
mLogger = new SplitscreenEventLogger();
|
||||||
}
|
}
|
||||||
|
|
||||||
public SplitScreen asSplitScreen() {
|
public SplitScreen asSplitScreen() {
|
||||||
@@ -123,7 +126,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
|||||||
// TODO: Multi-display
|
// TODO: Multi-display
|
||||||
mStageCoordinator = new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
|
mStageCoordinator = new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
|
||||||
mRootTDAOrganizer, mTaskOrganizer, mDisplayImeController, mTransitions,
|
mRootTDAOrganizer, mTaskOrganizer, mDisplayImeController, mTransitions,
|
||||||
mTransactionPool);
|
mTransactionPool, mLogger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,8 +168,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
|||||||
leftOrTop ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT);
|
leftOrTop ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exitSplitScreen() {
|
public void exitSplitScreen(int exitReason) {
|
||||||
mStageCoordinator.exitSplitScreen();
|
mStageCoordinator.exitSplitScreen(exitReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onKeyguardOccludedChanged(boolean occluded) {
|
public void onKeyguardOccludedChanged(boolean occluded) {
|
||||||
@@ -303,6 +306,13 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
|||||||
return new RemoteAnimationTarget[]{mStageCoordinator.getDividerBarLegacyTarget()};
|
return new RemoteAnimationTarget[]{mStageCoordinator.getDividerBarLegacyTarget()};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets drag info to be logged when splitscreen is entered.
|
||||||
|
*/
|
||||||
|
public void logOnDroppedToSplit(@SplitPosition int position, InstanceId dragSessionId) {
|
||||||
|
mStageCoordinator.logOnDroppedToSplit(position, dragSessionId);
|
||||||
|
}
|
||||||
|
|
||||||
public void dump(@NonNull PrintWriter pw, String prefix) {
|
public void dump(@NonNull PrintWriter pw, String prefix) {
|
||||||
pw.println(prefix + TAG);
|
pw.println(prefix + TAG);
|
||||||
if (mStageCoordinator != null) {
|
if (mStageCoordinator != null) {
|
||||||
@@ -495,7 +505,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
|||||||
public void exitSplitScreen() {
|
public void exitSplitScreen() {
|
||||||
executeRemoteCallWithTaskPermission(mController, "exitSplitScreen",
|
executeRemoteCallWithTaskPermission(mController, "exitSplitScreen",
|
||||||
(controller) -> {
|
(controller) -> {
|
||||||
controller.exitSplitScreen();
|
controller.exitSplitScreen(
|
||||||
|
FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__RETURN_HOME);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,324 @@
|
|||||||
|
/*
|
||||||
|
* 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.wm.shell.splitscreen;
|
||||||
|
|
||||||
|
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__ENTER_REASON__OVERVIEW;
|
||||||
|
import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_TOP_OR_LEFT;
|
||||||
|
import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_UNDEFINED;
|
||||||
|
|
||||||
|
import com.android.internal.logging.InstanceId;
|
||||||
|
import com.android.internal.logging.InstanceIdSequence;
|
||||||
|
import com.android.internal.util.FrameworkStatsLog;
|
||||||
|
import com.android.wm.shell.common.split.SplitLayout.SplitPosition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class that to log Drag & Drop UIEvents for a single session, see also go/uievent
|
||||||
|
*/
|
||||||
|
public class SplitscreenEventLogger {
|
||||||
|
|
||||||
|
// Used to generate instance ids for this drag if one is not provided
|
||||||
|
private final InstanceIdSequence mIdSequence;
|
||||||
|
|
||||||
|
// The instance id for the current splitscreen session (from start to end)
|
||||||
|
private InstanceId mLoggerSessionId;
|
||||||
|
|
||||||
|
// Drag info
|
||||||
|
private @SplitPosition int mDragEnterPosition;
|
||||||
|
private InstanceId mDragEnterSessionId;
|
||||||
|
|
||||||
|
// For deduping async events
|
||||||
|
private int mLastMainStagePosition = -1;
|
||||||
|
private int mLastMainStageUid = -1;
|
||||||
|
private int mLastSideStagePosition = -1;
|
||||||
|
private int mLastSideStageUid = -1;
|
||||||
|
private float mLastSplitRatio = -1f;
|
||||||
|
|
||||||
|
public SplitscreenEventLogger() {
|
||||||
|
mIdSequence = new InstanceIdSequence(Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether a splitscreen session has started.
|
||||||
|
*/
|
||||||
|
public boolean hasStartedSession() {
|
||||||
|
return mLoggerSessionId != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* May be called before logEnter() to indicate that the session was started from a drag.
|
||||||
|
*/
|
||||||
|
public void enterRequestedByDrag(@SplitPosition int position, InstanceId dragSessionId) {
|
||||||
|
mDragEnterPosition = position;
|
||||||
|
mDragEnterSessionId = dragSessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs when the user enters splitscreen.
|
||||||
|
*/
|
||||||
|
public void logEnter(float splitRatio,
|
||||||
|
@SplitPosition int mainStagePosition, int mainStageUid,
|
||||||
|
@SplitPosition int sideStagePosition, int sideStageUid,
|
||||||
|
boolean isLandscape) {
|
||||||
|
mLoggerSessionId = mIdSequence.newInstanceId();
|
||||||
|
int enterReason = mDragEnterPosition != SPLIT_POSITION_UNDEFINED
|
||||||
|
? getDragEnterReasonFromSplitPosition(mDragEnterPosition, isLandscape)
|
||||||
|
: SPLITSCREEN_UICHANGED__ENTER_REASON__OVERVIEW;
|
||||||
|
updateMainStageState(getMainStagePositionFromSplitPosition(mainStagePosition, isLandscape),
|
||||||
|
mainStageUid);
|
||||||
|
updateSideStageState(getSideStagePositionFromSplitPosition(sideStagePosition, isLandscape),
|
||||||
|
sideStageUid);
|
||||||
|
updateSplitRatioState(splitRatio);
|
||||||
|
FrameworkStatsLog.write(FrameworkStatsLog.SPLITSCREEN_UI_CHANGED,
|
||||||
|
FrameworkStatsLog.SPLITSCREEN_UICHANGED__ACTION__ENTER,
|
||||||
|
enterReason,
|
||||||
|
0 /* exitReason */,
|
||||||
|
splitRatio,
|
||||||
|
mLastMainStagePosition,
|
||||||
|
mLastMainStageUid,
|
||||||
|
mLastSideStagePosition,
|
||||||
|
mLastSideStageUid,
|
||||||
|
mDragEnterSessionId != null ? mDragEnterSessionId.getId() : 0,
|
||||||
|
mLoggerSessionId.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs when the user exits splitscreen. Only one of the main or side stages should be
|
||||||
|
* specified to indicate which position was focused as a part of exiting (both can be unset).
|
||||||
|
*/
|
||||||
|
public void logExit(int exitReason, @SplitPosition int mainStagePosition, int mainStageUid,
|
||||||
|
@SplitPosition int sideStagePosition, int sideStageUid, boolean isLandscape) {
|
||||||
|
if (mLoggerSessionId == null) {
|
||||||
|
// Ignore changes until we've started logging the session
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((mainStagePosition != SPLIT_POSITION_UNDEFINED
|
||||||
|
&& sideStagePosition != SPLIT_POSITION_UNDEFINED)
|
||||||
|
|| (mainStageUid != 0 && sideStageUid != 0)) {
|
||||||
|
throw new IllegalArgumentException("Only main or side stage should be set");
|
||||||
|
}
|
||||||
|
FrameworkStatsLog.write(FrameworkStatsLog.SPLITSCREEN_UI_CHANGED,
|
||||||
|
FrameworkStatsLog.SPLITSCREEN_UICHANGED__ACTION__EXIT,
|
||||||
|
0 /* enterReason */,
|
||||||
|
exitReason,
|
||||||
|
0f /* splitRatio */,
|
||||||
|
getMainStagePositionFromSplitPosition(mainStagePosition, isLandscape),
|
||||||
|
mainStageUid,
|
||||||
|
getSideStagePositionFromSplitPosition(sideStagePosition, isLandscape),
|
||||||
|
sideStageUid,
|
||||||
|
0 /* dragInstanceId */,
|
||||||
|
mLoggerSessionId.getId());
|
||||||
|
|
||||||
|
// Reset states
|
||||||
|
mLoggerSessionId = null;
|
||||||
|
mDragEnterPosition = SPLIT_POSITION_UNDEFINED;
|
||||||
|
mDragEnterSessionId = null;
|
||||||
|
mLastMainStagePosition = -1;
|
||||||
|
mLastMainStageUid = -1;
|
||||||
|
mLastSideStagePosition = -1;
|
||||||
|
mLastSideStageUid = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs when an app in the main stage changes.
|
||||||
|
*/
|
||||||
|
public void logMainStageAppChange(@SplitPosition int mainStagePosition, int mainStageUid,
|
||||||
|
boolean isLandscape) {
|
||||||
|
if (mLoggerSessionId == null) {
|
||||||
|
// Ignore changes until we've started logging the session
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!updateMainStageState(getMainStagePositionFromSplitPosition(mainStagePosition,
|
||||||
|
isLandscape), mainStageUid)) {
|
||||||
|
// Ignore if there are no user perceived changes
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameworkStatsLog.write(FrameworkStatsLog.SPLITSCREEN_UI_CHANGED,
|
||||||
|
FrameworkStatsLog.SPLITSCREEN_UICHANGED__ACTION__APP_CHANGE,
|
||||||
|
0 /* enterReason */,
|
||||||
|
0 /* exitReason */,
|
||||||
|
0f /* splitRatio */,
|
||||||
|
mLastMainStagePosition,
|
||||||
|
mLastMainStageUid,
|
||||||
|
0 /* sideStagePosition */,
|
||||||
|
0 /* sideStageUid */,
|
||||||
|
0 /* dragInstanceId */,
|
||||||
|
mLoggerSessionId.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs when an app in the side stage changes.
|
||||||
|
*/
|
||||||
|
public void logSideStageAppChange(@SplitPosition int sideStagePosition, int sideStageUid,
|
||||||
|
boolean isLandscape) {
|
||||||
|
if (mLoggerSessionId == null) {
|
||||||
|
// Ignore changes until we've started logging the session
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!updateSideStageState(getSideStagePositionFromSplitPosition(sideStagePosition,
|
||||||
|
isLandscape), sideStageUid)) {
|
||||||
|
// Ignore if there are no user perceived changes
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameworkStatsLog.write(FrameworkStatsLog.SPLITSCREEN_UI_CHANGED,
|
||||||
|
FrameworkStatsLog.SPLITSCREEN_UICHANGED__ACTION__APP_CHANGE,
|
||||||
|
0 /* enterReason */,
|
||||||
|
0 /* exitReason */,
|
||||||
|
0f /* splitRatio */,
|
||||||
|
0 /* mainStagePosition */,
|
||||||
|
0 /* mainStageUid */,
|
||||||
|
mLastSideStagePosition,
|
||||||
|
mLastSideStageUid,
|
||||||
|
0 /* dragInstanceId */,
|
||||||
|
mLoggerSessionId.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs when the splitscreen ratio changes.
|
||||||
|
*/
|
||||||
|
public void logResize(float splitRatio) {
|
||||||
|
if (mLoggerSessionId == null) {
|
||||||
|
// Ignore changes until we've started logging the session
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (splitRatio <= 0f || splitRatio >= 1f) {
|
||||||
|
// Don't bother reporting resizes that end up dismissing the split, that will be logged
|
||||||
|
// via the exit event
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!updateSplitRatioState(splitRatio)) {
|
||||||
|
// Ignore if there are no user perceived changes
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FrameworkStatsLog.write(FrameworkStatsLog.SPLITSCREEN_UI_CHANGED,
|
||||||
|
FrameworkStatsLog.SPLITSCREEN_UICHANGED__ACTION__RESIZE,
|
||||||
|
0 /* enterReason */,
|
||||||
|
0 /* exitReason */,
|
||||||
|
mLastSplitRatio,
|
||||||
|
0 /* mainStagePosition */, 0 /* mainStageUid */,
|
||||||
|
0 /* sideStagePosition */, 0 /* sideStageUid */,
|
||||||
|
0 /* dragInstanceId */,
|
||||||
|
mLoggerSessionId.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs when the apps in splitscreen are swapped.
|
||||||
|
*/
|
||||||
|
public void logSwap(@SplitPosition int mainStagePosition, int mainStageUid,
|
||||||
|
@SplitPosition int sideStagePosition, int sideStageUid, boolean isLandscape) {
|
||||||
|
if (mLoggerSessionId == null) {
|
||||||
|
// Ignore changes until we've started logging the session
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMainStageState(getMainStagePositionFromSplitPosition(mainStagePosition, isLandscape),
|
||||||
|
mainStageUid);
|
||||||
|
updateSideStageState(getSideStagePositionFromSplitPosition(sideStagePosition, isLandscape),
|
||||||
|
sideStageUid);
|
||||||
|
FrameworkStatsLog.write(FrameworkStatsLog.SPLITSCREEN_UI_CHANGED,
|
||||||
|
FrameworkStatsLog.SPLITSCREEN_UICHANGED__ACTION__SWAP,
|
||||||
|
0 /* enterReason */,
|
||||||
|
0 /* exitReason */,
|
||||||
|
0f /* splitRatio */,
|
||||||
|
mLastMainStagePosition,
|
||||||
|
mLastMainStageUid,
|
||||||
|
mLastSideStagePosition,
|
||||||
|
mLastSideStageUid,
|
||||||
|
0 /* dragInstanceId */,
|
||||||
|
mLoggerSessionId.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateMainStageState(int mainStagePosition, int mainStageUid) {
|
||||||
|
boolean changed = (mLastMainStagePosition != mainStagePosition)
|
||||||
|
|| (mLastMainStageUid != mainStageUid);
|
||||||
|
if (!changed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mLastMainStagePosition = mainStagePosition;
|
||||||
|
mLastMainStageUid = mainStageUid;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateSideStageState(int sideStagePosition, int sideStageUid) {
|
||||||
|
boolean changed = (mLastSideStagePosition != sideStagePosition)
|
||||||
|
|| (mLastSideStageUid != sideStageUid);
|
||||||
|
if (!changed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mLastSideStagePosition = sideStagePosition;
|
||||||
|
mLastSideStageUid = sideStageUid;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateSplitRatioState(float splitRatio) {
|
||||||
|
boolean changed = Float.compare(mLastSplitRatio, splitRatio) != 0;
|
||||||
|
if (!changed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mLastSplitRatio = splitRatio;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDragEnterReasonFromSplitPosition(@SplitPosition int position,
|
||||||
|
boolean isLandscape) {
|
||||||
|
if (isLandscape) {
|
||||||
|
return position == SPLIT_POSITION_TOP_OR_LEFT
|
||||||
|
? FrameworkStatsLog.SPLITSCREEN_UICHANGED__ENTER_REASON__DRAG_LEFT
|
||||||
|
: FrameworkStatsLog.SPLITSCREEN_UICHANGED__ENTER_REASON__DRAG_RIGHT;
|
||||||
|
} else {
|
||||||
|
return position == SPLIT_POSITION_TOP_OR_LEFT
|
||||||
|
? FrameworkStatsLog.SPLITSCREEN_UICHANGED__ENTER_REASON__DRAG_TOP
|
||||||
|
: FrameworkStatsLog.SPLITSCREEN_UICHANGED__ENTER_REASON__DRAG_BOTTOM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getMainStagePositionFromSplitPosition(@SplitPosition int position,
|
||||||
|
boolean isLandscape) {
|
||||||
|
if (position == SPLIT_POSITION_UNDEFINED) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (isLandscape) {
|
||||||
|
return position == SPLIT_POSITION_TOP_OR_LEFT
|
||||||
|
? FrameworkStatsLog.SPLITSCREEN_UICHANGED__MAIN_STAGE_POSITION__LEFT
|
||||||
|
: FrameworkStatsLog.SPLITSCREEN_UICHANGED__MAIN_STAGE_POSITION__RIGHT;
|
||||||
|
} else {
|
||||||
|
return position == SPLIT_POSITION_TOP_OR_LEFT
|
||||||
|
? FrameworkStatsLog.SPLITSCREEN_UICHANGED__MAIN_STAGE_POSITION__TOP
|
||||||
|
: FrameworkStatsLog.SPLITSCREEN_UICHANGED__MAIN_STAGE_POSITION__BOTTOM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getSideStagePositionFromSplitPosition(@SplitPosition int position,
|
||||||
|
boolean isLandscape) {
|
||||||
|
if (position == SPLIT_POSITION_UNDEFINED) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (isLandscape) {
|
||||||
|
return position == SPLIT_POSITION_TOP_OR_LEFT
|
||||||
|
? FrameworkStatsLog.SPLITSCREEN_UICHANGED__SIDE_STAGE_POSITION__LEFT
|
||||||
|
: FrameworkStatsLog.SPLITSCREEN_UICHANGED__SIDE_STAGE_POSITION__RIGHT;
|
||||||
|
} else {
|
||||||
|
return position == SPLIT_POSITION_TOP_OR_LEFT
|
||||||
|
? FrameworkStatsLog.SPLITSCREEN_UICHANGED__SIDE_STAGE_POSITION__TOP
|
||||||
|
: FrameworkStatsLog.SPLITSCREEN_UICHANGED__SIDE_STAGE_POSITION__BOTTOM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,12 @@ import static android.view.WindowManager.TRANSIT_TO_BACK;
|
|||||||
import static android.view.WindowManager.TRANSIT_TO_FRONT;
|
import static android.view.WindowManager.TRANSIT_TO_FRONT;
|
||||||
import static android.view.WindowManager.transitTypeToString;
|
import static android.view.WindowManager.transitTypeToString;
|
||||||
|
|
||||||
|
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__APP_DOES_NOT_SUPPORT_MULTIWINDOW;
|
||||||
|
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__APP_FINISHED;
|
||||||
|
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__DEVICE_FOLDED;
|
||||||
|
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__DRAG_DIVIDER;
|
||||||
|
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__RETURN_HOME;
|
||||||
|
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__SCREEN_LOCKED_SHOW_ON_TOP;
|
||||||
import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_BOTTOM_OR_RIGHT;
|
import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_BOTTOM_OR_RIGHT;
|
||||||
import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_TOP_OR_LEFT;
|
import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_TOP_OR_LEFT;
|
||||||
import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_UNDEFINED;
|
import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_UNDEFINED;
|
||||||
@@ -73,6 +79,7 @@ import android.window.WindowContainerTransaction;
|
|||||||
|
|
||||||
import com.android.internal.R;
|
import com.android.internal.R;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
import com.android.internal.logging.InstanceId;
|
||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
|
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
|
||||||
import com.android.wm.shell.ShellTaskOrganizer;
|
import com.android.wm.shell.ShellTaskOrganizer;
|
||||||
@@ -130,6 +137,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
private final List<SplitScreen.SplitScreenListener> mListeners = new ArrayList<>();
|
private final List<SplitScreen.SplitScreenListener> mListeners = new ArrayList<>();
|
||||||
private final DisplayImeController mDisplayImeController;
|
private final DisplayImeController mDisplayImeController;
|
||||||
private final SplitScreenTransitions mSplitTransitions;
|
private final SplitScreenTransitions mSplitTransitions;
|
||||||
|
private final SplitscreenEventLogger mLogger;
|
||||||
private boolean mExitSplitScreenOnHide;
|
private boolean mExitSplitScreenOnHide;
|
||||||
private boolean mKeyguardOccluded;
|
private boolean mKeyguardOccluded;
|
||||||
|
|
||||||
@@ -156,12 +164,13 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
|
StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
|
||||||
RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer,
|
RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer,
|
||||||
DisplayImeController displayImeController, Transitions transitions,
|
DisplayImeController displayImeController, Transitions transitions,
|
||||||
TransactionPool transactionPool) {
|
TransactionPool transactionPool, SplitscreenEventLogger logger) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mDisplayId = displayId;
|
mDisplayId = displayId;
|
||||||
mSyncQueue = syncQueue;
|
mSyncQueue = syncQueue;
|
||||||
mRootTDAOrganizer = rootTDAOrganizer;
|
mRootTDAOrganizer = rootTDAOrganizer;
|
||||||
mTaskOrganizer = taskOrganizer;
|
mTaskOrganizer = taskOrganizer;
|
||||||
|
mLogger = logger;
|
||||||
mMainStage = new MainStage(
|
mMainStage = new MainStage(
|
||||||
mTaskOrganizer,
|
mTaskOrganizer,
|
||||||
mDisplayId,
|
mDisplayId,
|
||||||
@@ -190,7 +199,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
|
StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
|
||||||
RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer,
|
RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer,
|
||||||
MainStage mainStage, SideStage sideStage, DisplayImeController displayImeController,
|
MainStage mainStage, SideStage sideStage, DisplayImeController displayImeController,
|
||||||
SplitLayout splitLayout, Transitions transitions, TransactionPool transactionPool) {
|
SplitLayout splitLayout, Transitions transitions, TransactionPool transactionPool,
|
||||||
|
SplitscreenEventLogger logger) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mDisplayId = displayId;
|
mDisplayId = displayId;
|
||||||
mSyncQueue = syncQueue;
|
mSyncQueue = syncQueue;
|
||||||
@@ -203,6 +213,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
mSplitLayout = splitLayout;
|
mSplitLayout = splitLayout;
|
||||||
mSplitTransitions = new SplitScreenTransitions(transactionPool, transitions,
|
mSplitTransitions = new SplitScreenTransitions(transactionPool, transitions,
|
||||||
mOnTransitionAnimationComplete);
|
mOnTransitionAnimationComplete);
|
||||||
|
mLogger = logger;
|
||||||
transitions.addHandler(this);
|
transitions.addHandler(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,19 +461,20 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
void onKeyguardVisibilityChanged(boolean showing) {
|
void onKeyguardVisibilityChanged(boolean showing) {
|
||||||
if (!showing && mMainStage.isActive()
|
if (!showing && mMainStage.isActive()
|
||||||
&& mTopStageAfterFoldDismiss != STAGE_TYPE_UNDEFINED) {
|
&& mTopStageAfterFoldDismiss != STAGE_TYPE_UNDEFINED) {
|
||||||
exitSplitScreen(mTopStageAfterFoldDismiss == STAGE_TYPE_MAIN ? mMainStage : mSideStage);
|
exitSplitScreen(mTopStageAfterFoldDismiss == STAGE_TYPE_MAIN ? mMainStage : mSideStage,
|
||||||
|
SPLITSCREEN_UICHANGED__EXIT_REASON__DEVICE_FOLDED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void exitSplitScreen() {
|
void exitSplitScreen(int exitReason) {
|
||||||
exitSplitScreen(null /* childrenToTop */);
|
exitSplitScreen(null /* childrenToTop */, exitReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) {
|
void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) {
|
||||||
mExitSplitScreenOnHide = exitSplitScreenOnHide;
|
mExitSplitScreenOnHide = exitSplitScreenOnHide;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void exitSplitScreen(StageTaskListener childrenToTop) {
|
private void exitSplitScreen(StageTaskListener childrenToTop, int exitReason) {
|
||||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||||
mSideStage.removeAllTasks(wct, childrenToTop == mSideStage);
|
mSideStage.removeAllTasks(wct, childrenToTop == mSideStage);
|
||||||
mMainStage.deactivate(wct, childrenToTop == mMainStage);
|
mMainStage.deactivate(wct, childrenToTop == mMainStage);
|
||||||
@@ -470,6 +482,11 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
// Reset divider position.
|
// Reset divider position.
|
||||||
mSplitLayout.resetDividerPosition();
|
mSplitLayout.resetDividerPosition();
|
||||||
mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
|
mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
|
||||||
|
if (childrenToTop != null) {
|
||||||
|
logExitToStage(exitReason, childrenToTop == mMainStage);
|
||||||
|
} else {
|
||||||
|
logExit(exitReason);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -522,9 +539,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onStageChildTaskStatusChanged(
|
private void onStageChildTaskStatusChanged(StageListenerImpl stageListener, int taskId,
|
||||||
StageListenerImpl stageListener, int taskId, boolean present, boolean visible) {
|
boolean present, boolean visible) {
|
||||||
|
|
||||||
int stage;
|
int stage;
|
||||||
if (present) {
|
if (present) {
|
||||||
stage = stageListener == mSideStageListener ? STAGE_TYPE_SIDE : STAGE_TYPE_MAIN;
|
stage = stageListener == mSideStageListener ? STAGE_TYPE_SIDE : STAGE_TYPE_MAIN;
|
||||||
@@ -532,6 +548,13 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
// No longer on any stage
|
// No longer on any stage
|
||||||
stage = STAGE_TYPE_UNDEFINED;
|
stage = STAGE_TYPE_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
if (stage == STAGE_TYPE_MAIN) {
|
||||||
|
mLogger.logMainStageAppChange(getMainStagePosition(), mMainStage.getTopChildTaskUid(),
|
||||||
|
mSplitLayout.isLandscape());
|
||||||
|
} else {
|
||||||
|
mLogger.logSideStageAppChange(getSideStagePosition(), mSideStage.getTopChildTaskUid(),
|
||||||
|
mSplitLayout.isLandscape());
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = mListeners.size() - 1; i >= 0; --i) {
|
for (int i = mListeners.size() - 1; i >= 0; --i) {
|
||||||
mListeners.get(i).onTaskStageChanged(taskId, stage, visible);
|
mListeners.get(i).onTaskStageChanged(taskId, stage, visible);
|
||||||
@@ -598,7 +621,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
// Don't dismiss staged split when both stages are not visible due to sleeping display,
|
// Don't dismiss staged split when both stages are not visible due to sleeping display,
|
||||||
// like the cases keyguard showing or screen off.
|
// like the cases keyguard showing or screen off.
|
||||||
|| (!mMainStage.mRootTaskInfo.isSleeping && !mSideStage.mRootTaskInfo.isSleeping)) {
|
|| (!mMainStage.mRootTaskInfo.isSleeping && !mSideStage.mRootTaskInfo.isSleeping)) {
|
||||||
exitSplitScreen();
|
exitSplitScreen(SPLITSCREEN_UICHANGED__EXIT_REASON__RETURN_HOME);
|
||||||
}
|
}
|
||||||
} else if (mKeyguardOccluded) {
|
} else if (mKeyguardOccluded) {
|
||||||
// At least one of the stages is visible while keyguard occluded. Dismiss split because
|
// At least one of the stages is visible while keyguard occluded. Dismiss split because
|
||||||
@@ -606,7 +629,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
// task contains show-when-locked activity remains on top after split dismissed.
|
// task contains show-when-locked activity remains on top after split dismissed.
|
||||||
final StageTaskListener toTop =
|
final StageTaskListener toTop =
|
||||||
mainStageVisible ? mMainStage : (sideStageVisible ? mSideStage : null);
|
mainStageVisible ? mMainStage : (sideStageVisible ? mSideStage : null);
|
||||||
exitSplitScreen(toTop);
|
exitSplitScreen(toTop, SPLITSCREEN_UICHANGED__EXIT_REASON__SCREEN_LOCKED_SHOW_ON_TOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When both stage's visibility changed to visible, main stage might receives visibility
|
// When both stage's visibility changed to visible, main stage might receives visibility
|
||||||
@@ -683,17 +706,16 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void onStageHasChildrenChanged(StageListenerImpl stageListener) {
|
private void onStageHasChildrenChanged(StageListenerImpl stageListener) {
|
||||||
final boolean hasChildren = stageListener.mHasChildren;
|
final boolean hasChildren = stageListener.mHasChildren;
|
||||||
final boolean isSideStage = stageListener == mSideStageListener;
|
final boolean isSideStage = stageListener == mSideStageListener;
|
||||||
if (!hasChildren) {
|
if (!hasChildren) {
|
||||||
if (isSideStage && mMainStageListener.mVisible) {
|
if (isSideStage && mMainStageListener.mVisible) {
|
||||||
// Exit to main stage if side stage no longer has children.
|
// Exit to main stage if side stage no longer has children.
|
||||||
exitSplitScreen(mMainStage);
|
exitSplitScreen(mMainStage, SPLITSCREEN_UICHANGED__EXIT_REASON__APP_FINISHED);
|
||||||
} else if (!isSideStage && mSideStageListener.mVisible) {
|
} else if (!isSideStage && mSideStageListener.mVisible) {
|
||||||
// Exit to side stage if main stage no longer has children.
|
// Exit to side stage if main stage no longer has children.
|
||||||
exitSplitScreen(mSideStage);
|
exitSplitScreen(mSideStage, SPLITSCREEN_UICHANGED__EXIT_REASON__APP_FINISHED);
|
||||||
}
|
}
|
||||||
} else if (isSideStage) {
|
} else if (isSideStage) {
|
||||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||||
@@ -702,6 +724,13 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
mSideStage.setBounds(getSideStageBounds(), wct);
|
mSideStage.setBounds(getSideStageBounds(), wct);
|
||||||
mTaskOrganizer.applyTransaction(wct);
|
mTaskOrganizer.applyTransaction(wct);
|
||||||
}
|
}
|
||||||
|
if (!mLogger.hasStartedSession() && mMainStageListener.mHasChildren
|
||||||
|
&& mSideStageListener.mHasChildren) {
|
||||||
|
mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(),
|
||||||
|
getMainStagePosition(), mMainStage.getTopChildTaskUid(),
|
||||||
|
getSideStagePosition(), mSideStage.getTopChildTaskUid(),
|
||||||
|
mSplitLayout.isLandscape());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -720,13 +749,17 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
onSnappedToDismissTransition(mainStageToTop);
|
onSnappedToDismissTransition(mainStageToTop);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
exitSplitScreen(mainStageToTop ? mMainStage : mSideStage);
|
exitSplitScreen(mainStageToTop ? mMainStage : mSideStage,
|
||||||
|
SPLITSCREEN_UICHANGED__EXIT_REASON__DRAG_DIVIDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDoubleTappedDivider() {
|
public void onDoubleTappedDivider() {
|
||||||
setSideStagePosition(mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
|
setSideStagePosition(mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
|
||||||
? SPLIT_POSITION_BOTTOM_OR_RIGHT : SPLIT_POSITION_TOP_OR_LEFT, null /* wct */);
|
? SPLIT_POSITION_BOTTOM_OR_RIGHT : SPLIT_POSITION_TOP_OR_LEFT, null /* wct */);
|
||||||
|
mLogger.logSwap(getMainStagePosition(), mMainStage.getTopChildTaskUid(),
|
||||||
|
getSideStagePosition(), mSideStage.getTopChildTaskUid(),
|
||||||
|
mSplitLayout.isLandscape());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -740,6 +773,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
updateWindowBounds(layout, wct);
|
updateWindowBounds(layout, wct);
|
||||||
mSyncQueue.queue(wct);
|
mSyncQueue.queue(wct);
|
||||||
mSyncQueue.runInSync(t -> updateSurfaceBounds(layout, t));
|
mSyncQueue.runInSync(t -> updateSurfaceBounds(layout, t));
|
||||||
|
mLogger.logResize(mSplitLayout.getDividerPositionAsFraction());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1139,6 +1173,36 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
mMainStageListener.mHasChildren = mSideStageListener.mHasChildren = visible;
|
mMainStageListener.mHasChildren = mSideStageListener.mHasChildren = visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets drag info to be logged when splitscreen is next entered.
|
||||||
|
*/
|
||||||
|
public void logOnDroppedToSplit(@SplitPosition int position, InstanceId dragSessionId) {
|
||||||
|
mLogger.enterRequestedByDrag(position, dragSessionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs the exit of splitscreen.
|
||||||
|
*/
|
||||||
|
private void logExit(int exitReason) {
|
||||||
|
mLogger.logExit(exitReason,
|
||||||
|
SPLIT_POSITION_UNDEFINED, 0 /* mainStageUid */,
|
||||||
|
SPLIT_POSITION_UNDEFINED, 0 /* sideStageUid */,
|
||||||
|
mSplitLayout.isLandscape());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs the exit of splitscreen to a specific stage. This must be called before the exit is
|
||||||
|
* executed.
|
||||||
|
*/
|
||||||
|
private void logExitToStage(int exitReason, boolean toMainStage) {
|
||||||
|
mLogger.logExit(exitReason,
|
||||||
|
toMainStage ? getMainStagePosition() : SPLIT_POSITION_UNDEFINED,
|
||||||
|
toMainStage ? mMainStage.getTopChildTaskUid() : 0 /* mainStageUid */,
|
||||||
|
!toMainStage ? getSideStagePosition() : SPLIT_POSITION_UNDEFINED,
|
||||||
|
!toMainStage ? mSideStage.getTopChildTaskUid() : 0 /* sideStageUid */,
|
||||||
|
mSplitLayout.isLandscape());
|
||||||
|
}
|
||||||
|
|
||||||
class StageListenerImpl implements StageTaskListener.StageListenerCallbacks {
|
class StageListenerImpl implements StageTaskListener.StageListenerCallbacks {
|
||||||
boolean mHasRootTask = false;
|
boolean mHasRootTask = false;
|
||||||
boolean mVisible = false;
|
boolean mVisible = false;
|
||||||
@@ -1178,7 +1242,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
@Override
|
@Override
|
||||||
public void onNoLongerSupportMultiWindow() {
|
public void onNoLongerSupportMultiWindow() {
|
||||||
if (mMainStage.isActive()) {
|
if (mMainStage.isActive()) {
|
||||||
StageCoordinator.this.exitSplitScreen();
|
StageCoordinator.this.exitSplitScreen(
|
||||||
|
SPLITSCREEN_UICHANGED__EXIT_REASON__APP_DOES_NOT_SUPPORT_MULTIWINDOW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,6 +97,20 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
|||||||
return mChildrenTaskInfo.contains(taskId);
|
return mChildrenTaskInfo.contains(taskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the top activity uid for the top child task.
|
||||||
|
*/
|
||||||
|
int getTopChildTaskUid() {
|
||||||
|
for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
|
||||||
|
final ActivityManager.RunningTaskInfo info = mChildrenTaskInfo.valueAt(i);
|
||||||
|
if (info.topActivityInfo == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return info.topActivityInfo.applicationInfo.uid;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** @return {@code true} if this listener contains the currently focused task. */
|
/** @return {@code true} if this listener contains the currently focused task. */
|
||||||
boolean isFocused() {
|
boolean isFocused() {
|
||||||
if (mRootTaskInfo.isFocused) return true;
|
if (mRootTaskInfo.isFocused) return true;
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ import android.view.DisplayInfo;
|
|||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
|
import com.android.internal.logging.InstanceId;
|
||||||
import com.android.wm.shell.common.DisplayLayout;
|
import com.android.wm.shell.common.DisplayLayout;
|
||||||
import com.android.wm.shell.draganddrop.DragAndDropPolicy.Target;
|
import com.android.wm.shell.draganddrop.DragAndDropPolicy.Target;
|
||||||
import com.android.wm.shell.splitscreen.SplitScreenController;
|
import com.android.wm.shell.splitscreen.SplitScreenController;
|
||||||
@@ -96,6 +97,9 @@ public class DragAndDropPolicyTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private SplitScreenController mSplitScreenStarter;
|
private SplitScreenController mSplitScreenStarter;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private InstanceId mLoggerSessionId;
|
||||||
|
|
||||||
private DisplayLayout mLandscapeDisplayLayout;
|
private DisplayLayout mLandscapeDisplayLayout;
|
||||||
private DisplayLayout mPortraitDisplayLayout;
|
private DisplayLayout mPortraitDisplayLayout;
|
||||||
private Insets mInsets;
|
private Insets mInsets;
|
||||||
@@ -201,7 +205,7 @@ public class DragAndDropPolicyTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testDragAppOverFullscreenHome_expectOnlyFullscreenTarget() {
|
public void testDragAppOverFullscreenHome_expectOnlyFullscreenTarget() {
|
||||||
setRunningTask(mHomeTask);
|
setRunningTask(mHomeTask);
|
||||||
mPolicy.start(mLandscapeDisplayLayout, mActivityClipData);
|
mPolicy.start(mLandscapeDisplayLayout, mActivityClipData, mLoggerSessionId);
|
||||||
ArrayList<Target> targets = assertExactTargetTypes(
|
ArrayList<Target> targets = assertExactTargetTypes(
|
||||||
mPolicy.getTargets(mInsets), TYPE_FULLSCREEN);
|
mPolicy.getTargets(mInsets), TYPE_FULLSCREEN);
|
||||||
|
|
||||||
@@ -213,7 +217,7 @@ public class DragAndDropPolicyTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testDragAppOverFullscreenApp_expectSplitScreenTargets() {
|
public void testDragAppOverFullscreenApp_expectSplitScreenTargets() {
|
||||||
setRunningTask(mFullscreenAppTask);
|
setRunningTask(mFullscreenAppTask);
|
||||||
mPolicy.start(mLandscapeDisplayLayout, mActivityClipData);
|
mPolicy.start(mLandscapeDisplayLayout, mActivityClipData, mLoggerSessionId);
|
||||||
ArrayList<Target> targets = assertExactTargetTypes(
|
ArrayList<Target> targets = assertExactTargetTypes(
|
||||||
mPolicy.getTargets(mInsets), TYPE_SPLIT_LEFT, TYPE_SPLIT_RIGHT);
|
mPolicy.getTargets(mInsets), TYPE_SPLIT_LEFT, TYPE_SPLIT_RIGHT);
|
||||||
|
|
||||||
@@ -230,7 +234,7 @@ public class DragAndDropPolicyTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testDragAppOverFullscreenAppPhone_expectVerticalSplitScreenTargets() {
|
public void testDragAppOverFullscreenAppPhone_expectVerticalSplitScreenTargets() {
|
||||||
setRunningTask(mFullscreenAppTask);
|
setRunningTask(mFullscreenAppTask);
|
||||||
mPolicy.start(mPortraitDisplayLayout, mActivityClipData);
|
mPolicy.start(mPortraitDisplayLayout, mActivityClipData, mLoggerSessionId);
|
||||||
ArrayList<Target> targets = assertExactTargetTypes(
|
ArrayList<Target> targets = assertExactTargetTypes(
|
||||||
mPolicy.getTargets(mInsets), TYPE_SPLIT_TOP, TYPE_SPLIT_BOTTOM);
|
mPolicy.getTargets(mInsets), TYPE_SPLIT_TOP, TYPE_SPLIT_BOTTOM);
|
||||||
|
|
||||||
@@ -248,7 +252,7 @@ public class DragAndDropPolicyTest {
|
|||||||
public void testDragAppOverSplitApp_expectSplitTargets_DropLeft() {
|
public void testDragAppOverSplitApp_expectSplitTargets_DropLeft() {
|
||||||
setInSplitScreen(true);
|
setInSplitScreen(true);
|
||||||
setRunningTask(mSplitPrimaryAppTask);
|
setRunningTask(mSplitPrimaryAppTask);
|
||||||
mPolicy.start(mLandscapeDisplayLayout, mActivityClipData);
|
mPolicy.start(mLandscapeDisplayLayout, mActivityClipData, mLoggerSessionId);
|
||||||
ArrayList<Target> targets = assertExactTargetTypes(
|
ArrayList<Target> targets = assertExactTargetTypes(
|
||||||
mPolicy.getTargets(mInsets), TYPE_SPLIT_LEFT, TYPE_SPLIT_RIGHT);
|
mPolicy.getTargets(mInsets), TYPE_SPLIT_LEFT, TYPE_SPLIT_RIGHT);
|
||||||
|
|
||||||
@@ -261,7 +265,7 @@ public class DragAndDropPolicyTest {
|
|||||||
public void testDragAppOverSplitApp_expectSplitTargets_DropRight() {
|
public void testDragAppOverSplitApp_expectSplitTargets_DropRight() {
|
||||||
setInSplitScreen(true);
|
setInSplitScreen(true);
|
||||||
setRunningTask(mSplitPrimaryAppTask);
|
setRunningTask(mSplitPrimaryAppTask);
|
||||||
mPolicy.start(mLandscapeDisplayLayout, mActivityClipData);
|
mPolicy.start(mLandscapeDisplayLayout, mActivityClipData, mLoggerSessionId);
|
||||||
ArrayList<Target> targets = assertExactTargetTypes(
|
ArrayList<Target> targets = assertExactTargetTypes(
|
||||||
mPolicy.getTargets(mInsets), TYPE_SPLIT_LEFT, TYPE_SPLIT_RIGHT);
|
mPolicy.getTargets(mInsets), TYPE_SPLIT_LEFT, TYPE_SPLIT_RIGHT);
|
||||||
|
|
||||||
@@ -274,7 +278,7 @@ public class DragAndDropPolicyTest {
|
|||||||
public void testDragAppOverSplitAppPhone_expectVerticalSplitTargets_DropTop() {
|
public void testDragAppOverSplitAppPhone_expectVerticalSplitTargets_DropTop() {
|
||||||
setInSplitScreen(true);
|
setInSplitScreen(true);
|
||||||
setRunningTask(mSplitPrimaryAppTask);
|
setRunningTask(mSplitPrimaryAppTask);
|
||||||
mPolicy.start(mPortraitDisplayLayout, mActivityClipData);
|
mPolicy.start(mPortraitDisplayLayout, mActivityClipData, mLoggerSessionId);
|
||||||
ArrayList<Target> targets = assertExactTargetTypes(
|
ArrayList<Target> targets = assertExactTargetTypes(
|
||||||
mPolicy.getTargets(mInsets), TYPE_SPLIT_TOP, TYPE_SPLIT_BOTTOM);
|
mPolicy.getTargets(mInsets), TYPE_SPLIT_TOP, TYPE_SPLIT_BOTTOM);
|
||||||
|
|
||||||
@@ -287,7 +291,7 @@ public class DragAndDropPolicyTest {
|
|||||||
public void testDragAppOverSplitAppPhone_expectVerticalSplitTargets_DropBottom() {
|
public void testDragAppOverSplitAppPhone_expectVerticalSplitTargets_DropBottom() {
|
||||||
setInSplitScreen(true);
|
setInSplitScreen(true);
|
||||||
setRunningTask(mSplitPrimaryAppTask);
|
setRunningTask(mSplitPrimaryAppTask);
|
||||||
mPolicy.start(mPortraitDisplayLayout, mActivityClipData);
|
mPolicy.start(mPortraitDisplayLayout, mActivityClipData, mLoggerSessionId);
|
||||||
ArrayList<Target> targets = assertExactTargetTypes(
|
ArrayList<Target> targets = assertExactTargetTypes(
|
||||||
mPolicy.getTargets(mInsets), TYPE_SPLIT_TOP, TYPE_SPLIT_BOTTOM);
|
mPolicy.getTargets(mInsets), TYPE_SPLIT_TOP, TYPE_SPLIT_BOTTOM);
|
||||||
|
|
||||||
@@ -299,7 +303,7 @@ public class DragAndDropPolicyTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testTargetHitRects() {
|
public void testTargetHitRects() {
|
||||||
setRunningTask(mFullscreenAppTask);
|
setRunningTask(mFullscreenAppTask);
|
||||||
mPolicy.start(mLandscapeDisplayLayout, mActivityClipData);
|
mPolicy.start(mLandscapeDisplayLayout, mActivityClipData, mLoggerSessionId);
|
||||||
ArrayList<Target> targets = mPolicy.getTargets(mInsets);
|
ArrayList<Target> targets = mPolicy.getTargets(mInsets);
|
||||||
for (Target t : targets) {
|
for (Target t : targets) {
|
||||||
assertTrue(mPolicy.getTargetAtLocation(t.hitRegion.left, t.hitRegion.top) == t);
|
assertTrue(mPolicy.getTargetAtLocation(t.hitRegion.left, t.hitRegion.top) == t);
|
||||||
|
|||||||
@@ -65,9 +65,10 @@ public class SplitTestUtils {
|
|||||||
TestStageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
|
TestStageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
|
||||||
RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer,
|
RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer,
|
||||||
MainStage mainStage, SideStage sideStage, DisplayImeController imeController,
|
MainStage mainStage, SideStage sideStage, DisplayImeController imeController,
|
||||||
SplitLayout splitLayout, Transitions transitions, TransactionPool transactionPool) {
|
SplitLayout splitLayout, Transitions transitions, TransactionPool transactionPool,
|
||||||
|
SplitscreenEventLogger logger) {
|
||||||
super(context, displayId, syncQueue, rootTDAOrganizer, taskOrganizer, mainStage,
|
super(context, displayId, syncQueue, rootTDAOrganizer, taskOrganizer, mainStage,
|
||||||
sideStage, imeController, splitLayout, transitions, transactionPool);
|
sideStage, imeController, splitLayout, transitions, transactionPool, logger);
|
||||||
|
|
||||||
// Prepare default TaskDisplayArea for testing.
|
// Prepare default TaskDisplayArea for testing.
|
||||||
mDisplayAreaInfo = new DisplayAreaInfo(
|
mDisplayAreaInfo = new DisplayAreaInfo(
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ public class SplitTransitionTests extends ShellTestCase {
|
|||||||
@Mock private TransactionPool mTransactionPool;
|
@Mock private TransactionPool mTransactionPool;
|
||||||
@Mock private Transitions mTransitions;
|
@Mock private Transitions mTransitions;
|
||||||
@Mock private SurfaceSession mSurfaceSession;
|
@Mock private SurfaceSession mSurfaceSession;
|
||||||
|
@Mock private SplitscreenEventLogger mLogger;
|
||||||
private SplitLayout mSplitLayout;
|
private SplitLayout mSplitLayout;
|
||||||
private MainStage mMainStage;
|
private MainStage mMainStage;
|
||||||
private SideStage mSideStage;
|
private SideStage mSideStage;
|
||||||
@@ -107,7 +108,8 @@ public class SplitTransitionTests extends ShellTestCase {
|
|||||||
mSideStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
|
mSideStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
|
||||||
mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY,
|
mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY,
|
||||||
mSyncQueue, mRootTDAOrganizer, mTaskOrganizer, mMainStage, mSideStage,
|
mSyncQueue, mRootTDAOrganizer, mTaskOrganizer, mMainStage, mSideStage,
|
||||||
mDisplayImeController, mSplitLayout, mTransitions, mTransactionPool);
|
mDisplayImeController, mSplitLayout, mTransitions, mTransactionPool,
|
||||||
|
mLogger);
|
||||||
mSplitScreenTransitions = mStageCoordinator.getSplitTransitions();
|
mSplitScreenTransitions = mStageCoordinator.getSplitTransitions();
|
||||||
doAnswer((Answer<IBinder>) invocation -> mock(IBinder.class))
|
doAnswer((Answer<IBinder>) invocation -> mock(IBinder.class))
|
||||||
.when(mTransitions).startTransition(anyInt(), any(), any());
|
.when(mTransitions).startTransition(anyInt(), any(), any());
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ public class StageCoordinatorTests extends ShellTestCase {
|
|||||||
@Mock private DisplayImeController mDisplayImeController;
|
@Mock private DisplayImeController mDisplayImeController;
|
||||||
@Mock private Transitions mTransitions;
|
@Mock private Transitions mTransitions;
|
||||||
@Mock private TransactionPool mTransactionPool;
|
@Mock private TransactionPool mTransactionPool;
|
||||||
|
@Mock private SplitscreenEventLogger mLogger;
|
||||||
private StageCoordinator mStageCoordinator;
|
private StageCoordinator mStageCoordinator;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -66,7 +67,8 @@ public class StageCoordinatorTests extends ShellTestCase {
|
|||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY,
|
mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY,
|
||||||
mSyncQueue, mRootTDAOrganizer, mTaskOrganizer, mMainStage, mSideStage,
|
mSyncQueue, mRootTDAOrganizer, mTaskOrganizer, mMainStage, mSideStage,
|
||||||
mDisplayImeController, null /* splitLayout */, mTransitions, mTransactionPool);
|
mDisplayImeController, null /* splitLayout */, mTransitions, mTransactionPool,
|
||||||
|
mLogger);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user