Introduce Multiwindow Fullscreen API
An API to let app launched in default freeform windowing mode request entering fullscreen windowing mode. This is useful to let apps, such as video streaming apps, to provide a unified and immersive experience to their users. The request will only be approved if the freeform window is not requested by the user, i.e., the app is launched in default freeform windowing mode. If the user get the app from recent screen, or the app is in other multi-window mode involves user interaction, such as split-screen, the request will be rejected, and a corresponding callback will be sent to the app. The app can provide an optional consumer to receive callback from the system to learn about the result of the validation. When the WM core approves the request, a shell transition will be initialted and the shell will have control of the final result and the animation of the transition. When shell transition is not enabled, a direct windowing mode change will be applied. Bug: 222454650 Test: atest CtsWindowManagerDeviceTestCases:FreeformWindowingModeTests Change-Id: I921e230ad08b0b2ce6df9e2ad6e01377cb459f3d
This commit is contained in:
@@ -4291,6 +4291,7 @@ package android.app {
|
||||
method @Deprecated public final void removeDialog(int);
|
||||
method public void reportFullyDrawn();
|
||||
method public android.view.DragAndDropPermissions requestDragAndDropPermissions(android.view.DragEvent);
|
||||
method public void requestFullscreenMode(@NonNull int, @Nullable android.os.OutcomeReceiver<java.lang.Void,java.lang.Throwable>);
|
||||
method public final void requestPermissions(@NonNull String[], int);
|
||||
method public final void requestShowKeyboardShortcuts();
|
||||
method @Deprecated public boolean requestVisibleBehind(boolean);
|
||||
@@ -4377,6 +4378,8 @@ package android.app {
|
||||
field public static final int DEFAULT_KEYS_SEARCH_LOCAL = 3; // 0x3
|
||||
field public static final int DEFAULT_KEYS_SHORTCUT = 2; // 0x2
|
||||
field protected static final int[] FOCUSED_STATE_SET;
|
||||
field public static final int FULLSCREEN_MODE_REQUEST_ENTER = 1; // 0x1
|
||||
field public static final int FULLSCREEN_MODE_REQUEST_EXIT = 0; // 0x0
|
||||
field public static final int RESULT_CANCELED = 0; // 0x0
|
||||
field public static final int RESULT_FIRST_USER = 1; // 0x1
|
||||
field public static final int RESULT_OK = -1; // 0xffffffff
|
||||
|
||||
@@ -83,6 +83,7 @@ import android.os.GraphicsEnvironment;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.OutcomeReceiver;
|
||||
import android.os.Parcelable;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.Process;
|
||||
@@ -987,6 +988,17 @@ public class Activity extends ContextThemeWrapper
|
||||
/** @hide */
|
||||
boolean mIsInPictureInPictureMode;
|
||||
|
||||
/** @hide */
|
||||
@IntDef(prefix = { "FULLSCREEN_REQUEST_" }, value = {
|
||||
FULLSCREEN_MODE_REQUEST_EXIT,
|
||||
FULLSCREEN_MODE_REQUEST_ENTER
|
||||
})
|
||||
public @interface FullscreenModeRequest {}
|
||||
|
||||
public static final int FULLSCREEN_MODE_REQUEST_EXIT = 0;
|
||||
|
||||
public static final int FULLSCREEN_MODE_REQUEST_ENTER = 1;
|
||||
|
||||
private boolean mShouldDockBigOverlays;
|
||||
|
||||
private UiTranslationController mUiTranslationController;
|
||||
@@ -3000,6 +3012,36 @@ public class Activity extends ContextThemeWrapper
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request to put the a freeform activity into fullscreen. This will only be allowed if the
|
||||
* activity is on a freeform display, such as a desktop device. The requester has to be the
|
||||
* top-most activity and the request should be a response to a user input. When getting
|
||||
* fullscreen and receiving corresponding {@link #onConfigurationChanged(Configuration)} and
|
||||
* {@link #onMultiWindowModeChanged(boolean, Configuration)}, the activity should relayout
|
||||
* itself and the system bars' visibilities can be controlled as usual fullscreen apps.
|
||||
*
|
||||
* Calling it again with the exit request can restore the activity to the previous status.
|
||||
* This will only happen when it got into fullscreen through this API.
|
||||
*
|
||||
* If an app wants to be in fullscreen always, it should claim as not being resizable
|
||||
* by setting
|
||||
* <a href="https://developer.android.com/guide/topics/large-screens/multi-window-support#resizeableActivity">
|
||||
* {@code android:resizableActivity="false"}</a> instead of calling this API.
|
||||
*
|
||||
* @param request Can be {@link #FULLSCREEN_MODE_REQUEST_ENTER} or
|
||||
* {@link #FULLSCREEN_MODE_REQUEST_EXIT} to indicate this request is to get
|
||||
* fullscreen or get restored.
|
||||
* @param approvalCallback Optional callback, use {@code null} when not necessary. When the
|
||||
* request is approved or rejected, the callback will be triggered. This
|
||||
* will happen before any configuration change. The callback will be
|
||||
* dispatched on the main thread.
|
||||
*/
|
||||
public void requestFullscreenMode(@NonNull @FullscreenModeRequest int request,
|
||||
@Nullable OutcomeReceiver<Void, Throwable> approvalCallback) {
|
||||
FullscreenRequestHandler.requestFullscreenMode(
|
||||
request, approvalCallback, mCurrentConfig, getActivityToken());
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a preference to dock big overlays like the expanded picture-in-picture on TV
|
||||
* (see {@link PictureInPictureParams.Builder#setExpandedAspectRatio}). Docking puts the
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.IRemoteCallback;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Singleton;
|
||||
@@ -372,6 +373,14 @@ public class ActivityClient {
|
||||
}
|
||||
}
|
||||
|
||||
void requestMultiwindowFullscreen(IBinder token, int request, IRemoteCallback callback) {
|
||||
try {
|
||||
getActivityClientController().requestMultiwindowFullscreen(token, request, callback);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
void startLockTaskModeByToken(IBinder token) {
|
||||
try {
|
||||
getActivityClientController().startLockTaskModeByToken(token);
|
||||
|
||||
@@ -61,6 +61,12 @@ public class ActivityTaskManager {
|
||||
*/
|
||||
public static final int INVALID_TASK_ID = -1;
|
||||
|
||||
/**
|
||||
* Invalid windowing mode.
|
||||
* @hide
|
||||
*/
|
||||
public static final int INVALID_WINDOWING_MODE = -1;
|
||||
|
||||
/**
|
||||
* Input parameter to {@link IActivityTaskManager#resizeTask} which indicates
|
||||
* that the resize doesn't need to preserve the window, and can be skipped if bounds
|
||||
|
||||
123
core/java/android/app/FullscreenRequestHandler.java
Normal file
123
core/java/android/app/FullscreenRequestHandler.java
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 android.app;
|
||||
|
||||
import static android.app.Activity.FULLSCREEN_MODE_REQUEST_ENTER;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.IRemoteCallback;
|
||||
import android.os.OutcomeReceiver;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class FullscreenRequestHandler {
|
||||
@IntDef(prefix = { "RESULT_" }, value = {
|
||||
RESULT_APPROVED,
|
||||
RESULT_FAILED_NOT_IN_FREEFORM,
|
||||
RESULT_FAILED_NOT_IN_FULLSCREEN_WITH_HISTORY,
|
||||
RESULT_FAILED_NOT_DEFAULT_FREEFORM,
|
||||
RESULT_FAILED_NOT_TOP_FOCUSED
|
||||
})
|
||||
public @interface RequestResult {}
|
||||
|
||||
public static final int RESULT_APPROVED = 0;
|
||||
public static final int RESULT_FAILED_NOT_IN_FREEFORM = 1;
|
||||
public static final int RESULT_FAILED_NOT_IN_FULLSCREEN_WITH_HISTORY = 2;
|
||||
public static final int RESULT_FAILED_NOT_DEFAULT_FREEFORM = 3;
|
||||
public static final int RESULT_FAILED_NOT_TOP_FOCUSED = 4;
|
||||
|
||||
public static final String REMOTE_CALLBACK_RESULT_KEY = "result";
|
||||
|
||||
static void requestFullscreenMode(@NonNull @Activity.FullscreenModeRequest int request,
|
||||
@Nullable OutcomeReceiver<Void, Throwable> approvalCallback, Configuration config,
|
||||
IBinder token) {
|
||||
int earlyCheck = earlyCheckRequestMatchesWindowingMode(
|
||||
request, config.windowConfiguration.getWindowingMode());
|
||||
if (earlyCheck != RESULT_APPROVED) {
|
||||
if (approvalCallback != null) {
|
||||
notifyFullscreenRequestResult(approvalCallback, earlyCheck);
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (approvalCallback != null) {
|
||||
ActivityClient.getInstance().requestMultiwindowFullscreen(token, request,
|
||||
new IRemoteCallback.Stub() {
|
||||
@Override
|
||||
public void sendResult(Bundle res) {
|
||||
notifyFullscreenRequestResult(
|
||||
approvalCallback, res.getInt(REMOTE_CALLBACK_RESULT_KEY));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ActivityClient.getInstance().requestMultiwindowFullscreen(token, request, null);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (approvalCallback != null) {
|
||||
approvalCallback.onError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void notifyFullscreenRequestResult(
|
||||
OutcomeReceiver<Void, Throwable> callback, int result) {
|
||||
Throwable e = null;
|
||||
switch (result) {
|
||||
case RESULT_FAILED_NOT_IN_FREEFORM:
|
||||
e = new IllegalStateException("The window is not a freeform window, the request "
|
||||
+ "to get into fullscreen cannot be approved.");
|
||||
break;
|
||||
case RESULT_FAILED_NOT_IN_FULLSCREEN_WITH_HISTORY:
|
||||
e = new IllegalStateException("The window is not in fullscreen by calling the "
|
||||
+ "requestFullscreenMode API before, such that cannot be restored.");
|
||||
break;
|
||||
case RESULT_FAILED_NOT_DEFAULT_FREEFORM:
|
||||
e = new IllegalStateException("The window is not launched in freeform by default.");
|
||||
break;
|
||||
case RESULT_FAILED_NOT_TOP_FOCUSED:
|
||||
e = new IllegalStateException("The window is not the top focused window.");
|
||||
break;
|
||||
default:
|
||||
callback.onResult(null);
|
||||
break;
|
||||
}
|
||||
if (e != null) {
|
||||
callback.onError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static int earlyCheckRequestMatchesWindowingMode(int request, int windowingMode) {
|
||||
if (request == FULLSCREEN_MODE_REQUEST_ENTER) {
|
||||
if (windowingMode != WINDOWING_MODE_FREEFORM) {
|
||||
return RESULT_FAILED_NOT_IN_FREEFORM;
|
||||
}
|
||||
} else {
|
||||
if (windowingMode != WINDOWING_MODE_FULLSCREEN) {
|
||||
return RESULT_FAILED_NOT_IN_FULLSCREEN_WITH_HISTORY;
|
||||
}
|
||||
}
|
||||
return RESULT_APPROVED;
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.os.IRemoteCallback;
|
||||
import android.os.PersistableBundle;
|
||||
import android.view.RemoteAnimationDefinition;
|
||||
import android.window.SizeConfigurationBuckets;
|
||||
@@ -102,6 +103,8 @@ interface IActivityClientController {
|
||||
void setPictureInPictureParams(in IBinder token, in PictureInPictureParams params);
|
||||
oneway void setShouldDockBigOverlays(in IBinder token, in boolean shouldDockBigOverlays);
|
||||
void toggleFreeformWindowingMode(in IBinder token);
|
||||
oneway void requestMultiwindowFullscreen(in IBinder token, in int request,
|
||||
in IRemoteCallback callback);
|
||||
|
||||
oneway void startLockTaskModeByToken(in IBinder token);
|
||||
oneway void stopLockTaskModeByToken(in IBinder token);
|
||||
|
||||
@@ -619,6 +619,12 @@
|
||||
"group": "WM_DEBUG_CONFIGURATION",
|
||||
"at": "com\/android\/server\/wm\/ActivityStarter.java"
|
||||
},
|
||||
"-1484988952": {
|
||||
"message": "Creating Pending Multiwindow Fullscreen Request: %s",
|
||||
"level": "VERBOSE",
|
||||
"group": "WM_DEBUG_WINDOW_TRANSITIONS",
|
||||
"at": "com\/android\/server\/wm\/ActivityClientController.java"
|
||||
},
|
||||
"-1483435730": {
|
||||
"message": "InsetsSource setWin %s for type %s",
|
||||
"level": "DEBUG",
|
||||
|
||||
@@ -17,7 +17,15 @@
|
||||
package com.android.server.wm;
|
||||
|
||||
import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
|
||||
import static android.app.Activity.FULLSCREEN_MODE_REQUEST_ENTER;
|
||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
import static android.app.ActivityTaskManager.INVALID_WINDOWING_MODE;
|
||||
import static android.app.FullscreenRequestHandler.REMOTE_CALLBACK_RESULT_KEY;
|
||||
import static android.app.FullscreenRequestHandler.RESULT_APPROVED;
|
||||
import static android.app.FullscreenRequestHandler.RESULT_FAILED_NOT_DEFAULT_FREEFORM;
|
||||
import static android.app.FullscreenRequestHandler.RESULT_FAILED_NOT_IN_FREEFORM;
|
||||
import static android.app.FullscreenRequestHandler.RESULT_FAILED_NOT_IN_FULLSCREEN_WITH_HISTORY;
|
||||
import static android.app.FullscreenRequestHandler.RESULT_FAILED_NOT_TOP_FOCUSED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
@@ -27,6 +35,7 @@ import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
|
||||
import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.Display.INVALID_DISPLAY;
|
||||
import static android.view.WindowManager.TRANSIT_CHANGE;
|
||||
import static android.view.WindowManager.TRANSIT_TO_BACK;
|
||||
import static android.view.WindowManager.TRANSIT_TO_FRONT;
|
||||
|
||||
@@ -52,6 +61,7 @@ import android.annotation.Nullable;
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.app.FullscreenRequestHandler;
|
||||
import android.app.IActivityClientController;
|
||||
import android.app.ICompatCameraControlCallback;
|
||||
import android.app.IRequestFinishCallback;
|
||||
@@ -71,6 +81,7 @@ import android.content.res.Configuration;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.IRemoteCallback;
|
||||
import android.os.Parcel;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.RemoteException;
|
||||
@@ -85,6 +96,7 @@ import android.window.TransitionInfo;
|
||||
|
||||
import com.android.internal.app.AssistUtils;
|
||||
import com.android.internal.policy.IKeyguardDismissCallback;
|
||||
import com.android.internal.protolog.ProtoLogGroup;
|
||||
import com.android.internal.protolog.common.ProtoLog;
|
||||
import com.android.internal.util.FrameworkStatsLog;
|
||||
import com.android.server.LocalServices;
|
||||
@@ -1056,6 +1068,133 @@ class ActivityClientController extends IActivityClientController.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private @FullscreenRequestHandler.RequestResult int validateMultiwindowFullscreenRequestLocked(
|
||||
Task topFocusedRootTask, int fullscreenRequest, ActivityRecord requesterActivity) {
|
||||
// If the mode is not by default freeform, the freeform will be a user-driven event.
|
||||
if (topFocusedRootTask.getParent().getWindowingMode() != WINDOWING_MODE_FREEFORM) {
|
||||
return RESULT_FAILED_NOT_DEFAULT_FREEFORM;
|
||||
}
|
||||
// If this is not coming from the currently top-most activity, reject the request.
|
||||
if (requesterActivity != topFocusedRootTask.getTopMostActivity()) {
|
||||
return RESULT_FAILED_NOT_TOP_FOCUSED;
|
||||
}
|
||||
if (fullscreenRequest == FULLSCREEN_MODE_REQUEST_ENTER) {
|
||||
if (topFocusedRootTask.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
|
||||
return RESULT_FAILED_NOT_IN_FREEFORM;
|
||||
}
|
||||
} else {
|
||||
if (topFocusedRootTask.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
|
||||
return RESULT_FAILED_NOT_IN_FULLSCREEN_WITH_HISTORY;
|
||||
}
|
||||
if (topFocusedRootTask.mMultiWindowRestoreWindowingMode == INVALID_WINDOWING_MODE) {
|
||||
return RESULT_FAILED_NOT_IN_FULLSCREEN_WITH_HISTORY;
|
||||
}
|
||||
}
|
||||
return RESULT_APPROVED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestMultiwindowFullscreen(IBinder callingActivity, int fullscreenRequest,
|
||||
IRemoteCallback callback) {
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mGlobalLock) {
|
||||
requestMultiwindowFullscreenLocked(callingActivity, fullscreenRequest, callback);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
|
||||
private void requestMultiwindowFullscreenLocked(IBinder callingActivity, int fullscreenRequest,
|
||||
IRemoteCallback callback) {
|
||||
final ActivityRecord r = ActivityRecord.forTokenLocked(callingActivity);
|
||||
if (r == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the shell transition is not enabled, just execute and done.
|
||||
final TransitionController controller = r.mTransitionController;
|
||||
if (!controller.isShellTransitionsEnabled()) {
|
||||
final @FullscreenRequestHandler.RequestResult int validateResult;
|
||||
final Task topFocusedRootTask;
|
||||
topFocusedRootTask = mService.getTopDisplayFocusedRootTask();
|
||||
validateResult = validateMultiwindowFullscreenRequestLocked(topFocusedRootTask,
|
||||
fullscreenRequest, r);
|
||||
reportMultiwindowFullscreenRequestValidatingResult(callback, validateResult);
|
||||
if (validateResult == RESULT_APPROVED) {
|
||||
executeMultiWindowFullscreenRequest(fullscreenRequest, topFocusedRootTask);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Initiate the transition.
|
||||
final Transition transition = new Transition(TRANSIT_CHANGE, 0 /* flags */, controller,
|
||||
mService.mWindowManager.mSyncEngine);
|
||||
if (mService.mWindowManager.mSyncEngine.hasActiveSync()) {
|
||||
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
|
||||
"Creating Pending Multiwindow Fullscreen Request: %s", transition);
|
||||
mService.mWindowManager.mSyncEngine.queueSyncSet(
|
||||
() -> r.mTransitionController.moveToCollecting(transition),
|
||||
() -> {
|
||||
executeFullscreenRequestTransition(fullscreenRequest, callback, r,
|
||||
transition, true /* queued */);
|
||||
});
|
||||
} else {
|
||||
executeFullscreenRequestTransition(fullscreenRequest, callback, r, transition,
|
||||
false /* queued */);
|
||||
}
|
||||
}
|
||||
|
||||
private void executeFullscreenRequestTransition(int fullscreenRequest, IRemoteCallback callback,
|
||||
ActivityRecord r, Transition transition, boolean queued) {
|
||||
final @FullscreenRequestHandler.RequestResult int validateResult;
|
||||
final Task topFocusedRootTask;
|
||||
topFocusedRootTask = mService.getTopDisplayFocusedRootTask();
|
||||
validateResult = validateMultiwindowFullscreenRequestLocked(topFocusedRootTask,
|
||||
fullscreenRequest, r);
|
||||
reportMultiwindowFullscreenRequestValidatingResult(callback, validateResult);
|
||||
if (validateResult != RESULT_APPROVED) {
|
||||
if (queued) {
|
||||
transition.abort();
|
||||
}
|
||||
return;
|
||||
}
|
||||
r.mTransitionController.requestStartTransition(transition, topFocusedRootTask,
|
||||
null /* remoteTransition */, null /* displayChange */);
|
||||
executeMultiWindowFullscreenRequest(fullscreenRequest, topFocusedRootTask);
|
||||
transition.setReady(topFocusedRootTask, true);
|
||||
}
|
||||
|
||||
private static void reportMultiwindowFullscreenRequestValidatingResult(IRemoteCallback callback,
|
||||
@FullscreenRequestHandler.RequestResult int result) {
|
||||
if (callback == null) {
|
||||
return;
|
||||
}
|
||||
Bundle res = new Bundle();
|
||||
res.putInt(REMOTE_CALLBACK_RESULT_KEY, result);
|
||||
try {
|
||||
callback.sendResult(res);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "client throws an exception back to the server, ignore it");
|
||||
}
|
||||
}
|
||||
|
||||
private static void executeMultiWindowFullscreenRequest(int fullscreenRequest, Task requester) {
|
||||
final int targetWindowingMode;
|
||||
if (fullscreenRequest == FULLSCREEN_MODE_REQUEST_ENTER) {
|
||||
requester.mMultiWindowRestoreWindowingMode =
|
||||
requester.getRequestedOverrideWindowingMode();
|
||||
targetWindowingMode = WINDOWING_MODE_FULLSCREEN;
|
||||
} else {
|
||||
targetWindowingMode = requester.mMultiWindowRestoreWindowingMode;
|
||||
requester.mMultiWindowRestoreWindowingMode = INVALID_WINDOWING_MODE;
|
||||
}
|
||||
requester.setWindowingMode(targetWindowingMode);
|
||||
if (targetWindowingMode == WINDOWING_MODE_FULLSCREEN) {
|
||||
requester.setBounds(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startLockTaskModeByToken(IBinder token) {
|
||||
synchronized (mGlobalLock) {
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.server.wm;
|
||||
|
||||
import static android.app.ActivityManager.isStartResultSuccessful;
|
||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
import static android.app.ActivityTaskManager.INVALID_WINDOWING_MODE;
|
||||
import static android.app.ActivityTaskManager.RESIZE_MODE_FORCED;
|
||||
import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION;
|
||||
import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
|
||||
@@ -443,6 +444,8 @@ class Task extends TaskFragment {
|
||||
@Surface.Rotation
|
||||
private int mRotation;
|
||||
|
||||
int mMultiWindowRestoreWindowingMode = INVALID_WINDOWING_MODE;
|
||||
|
||||
/**
|
||||
* Last requested orientation reported to DisplayContent. This is different from {@link
|
||||
* #mOrientation} in the sense that this takes activities' requested orientation into
|
||||
|
||||
Reference in New Issue
Block a user