Support insets on secondary displays
Indroduced DisplayFrames object to track frames used to calculate window insets per display vs. at a global level in PhoneWindowManager. Bug: 64148922 Change-Id: I19f166920eba0a4f933a223a77e096bcc8dab0c1 Test: bit FrameworksServicesTests:com.android.server.wm.ScreenDecorWindowTests Test: go/wm-smoke
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package android.app;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
@@ -418,22 +419,51 @@ public class Instrumentation {
|
||||
* different process. In addition, if the given Intent resolves to
|
||||
* multiple activities, instead of displaying a dialog for the user to
|
||||
* select an activity, an exception will be thrown.
|
||||
*
|
||||
*
|
||||
* <p>The function returns as soon as the activity goes idle following the
|
||||
* call to its {@link Activity#onCreate}. Generally this means it has gone
|
||||
* through the full initialization including {@link Activity#onResume} and
|
||||
* drawn and displayed its initial window.
|
||||
*
|
||||
*
|
||||
* @param intent Description of the activity to start.
|
||||
*
|
||||
*
|
||||
* @see Context#startActivity
|
||||
* @see #startActivitySync(Intent, Bundle)
|
||||
*/
|
||||
public Activity startActivitySync(Intent intent) {
|
||||
return startActivitySync(intent, null /* options */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a new activity and wait for it to begin running before returning.
|
||||
* In addition to being synchronous, this method as some semantic
|
||||
* differences from the standard {@link Context#startActivity} call: the
|
||||
* activity component is resolved before talking with the activity manager
|
||||
* (its class name is specified in the Intent that this method ultimately
|
||||
* starts), and it does not allow you to start activities that run in a
|
||||
* different process. In addition, if the given Intent resolves to
|
||||
* multiple activities, instead of displaying a dialog for the user to
|
||||
* select an activity, an exception will be thrown.
|
||||
*
|
||||
* <p>The function returns as soon as the activity goes idle following the
|
||||
* call to its {@link Activity#onCreate}. Generally this means it has gone
|
||||
* through the full initialization including {@link Activity#onResume} and
|
||||
* drawn and displayed its initial window.
|
||||
*
|
||||
* @param intent Description of the activity to start.
|
||||
* @param options Additional options for how the Activity should be started.
|
||||
* May be null if there are no options. See {@link android.app.ActivityOptions}
|
||||
* for how to build the Bundle supplied here; there are no supported definitions
|
||||
* for building it manually.
|
||||
*
|
||||
* @see Context#startActivity(Intent, Bundle)
|
||||
*/
|
||||
public Activity startActivitySync(Intent intent, @Nullable Bundle options) {
|
||||
validateNotAppThread();
|
||||
|
||||
synchronized (mSync) {
|
||||
intent = new Intent(intent);
|
||||
|
||||
|
||||
ActivityInfo ai = intent.resolveActivityInfo(
|
||||
getTargetContext().getPackageManager(), 0);
|
||||
if (ai == null) {
|
||||
@@ -447,7 +477,7 @@ public class Instrumentation {
|
||||
+ myProc + " resolved to different process "
|
||||
+ ai.processName + ": " + intent);
|
||||
}
|
||||
|
||||
|
||||
intent.setComponent(new ComponentName(
|
||||
ai.applicationInfo.packageName, ai.name));
|
||||
final ActivityWaiter aw = new ActivityWaiter(intent);
|
||||
@@ -457,7 +487,7 @@ public class Instrumentation {
|
||||
}
|
||||
mWaitingActivities.add(aw);
|
||||
|
||||
getTargetContext().startActivity(intent);
|
||||
getTargetContext().startActivity(intent, options);
|
||||
|
||||
do {
|
||||
try {
|
||||
@@ -465,7 +495,7 @@ public class Instrumentation {
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
} while (mWaitingActivities.contains(aw));
|
||||
|
||||
|
||||
return aw.activity;
|
||||
}
|
||||
}
|
||||
|
||||
189
core/java/android/view/DisplayFrames.java
Normal file
189
core/java/android/view/DisplayFrames.java
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package android.view;
|
||||
|
||||
import static android.view.Surface.ROTATION_180;
|
||||
import static android.view.Surface.ROTATION_270;
|
||||
import static android.view.Surface.ROTATION_90;
|
||||
import static com.android.server.wm.proto.DisplayFramesProto.STABLE_BOUNDS;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Container class for all the display frames that affect how we do window layout on a display.
|
||||
* @hide
|
||||
*/
|
||||
public class DisplayFrames {
|
||||
public final int mDisplayId;
|
||||
|
||||
/**
|
||||
* The current size of the screen; really; extends into the overscan area of the screen and
|
||||
* doesn't account for any system elements like the status bar.
|
||||
*/
|
||||
public final Rect mOverscan = new Rect();
|
||||
|
||||
/**
|
||||
* The current visible size of the screen; really; (ir)regardless of whether the status bar can
|
||||
* be hidden but not extending into the overscan area.
|
||||
*/
|
||||
public final Rect mUnrestricted = new Rect();
|
||||
|
||||
/** Like mOverscan*, but allowed to move into the overscan region where appropriate. */
|
||||
public final Rect mRestrictedOverscan = new Rect();
|
||||
|
||||
/**
|
||||
* The current size of the screen; these may be different than (0,0)-(dw,dh) if the status bar
|
||||
* can't be hidden; in that case it effectively carves out that area of the display from all
|
||||
* other windows.
|
||||
*/
|
||||
public final Rect mRestricted = new Rect();
|
||||
|
||||
/**
|
||||
* During layout, the current screen borders accounting for any currently visible system UI
|
||||
* elements.
|
||||
*/
|
||||
public final Rect mSystem = new Rect();
|
||||
|
||||
/** For applications requesting stable content insets, these are them. */
|
||||
public final Rect mStable = new Rect();
|
||||
|
||||
/**
|
||||
* For applications requesting stable content insets but have also set the fullscreen window
|
||||
* flag, these are the stable dimensions without the status bar.
|
||||
*/
|
||||
public final Rect mStableFullscreen = new Rect();
|
||||
|
||||
/**
|
||||
* During layout, the current screen borders with all outer decoration (status bar, input method
|
||||
* dock) accounted for.
|
||||
*/
|
||||
public final Rect mCurrent = new Rect();
|
||||
|
||||
/**
|
||||
* During layout, the frame in which content should be displayed to the user, accounting for all
|
||||
* screen decoration except for any space they deem as available for other content. This is
|
||||
* usually the same as mCurrent*, but may be larger if the screen decor has supplied content
|
||||
* insets.
|
||||
*/
|
||||
public final Rect mContent = new Rect();
|
||||
|
||||
/**
|
||||
* During layout, the frame in which voice content should be displayed to the user, accounting
|
||||
* for all screen decoration except for any space they deem as available for other content.
|
||||
*/
|
||||
public final Rect mVoiceContent = new Rect();
|
||||
|
||||
/** During layout, the current screen borders along which input method windows are placed. */
|
||||
public final Rect mDock = new Rect();
|
||||
|
||||
private final Rect mDisplayInfoOverscan = new Rect();
|
||||
private final Rect mRotatedDisplayInfoOverscan = new Rect();
|
||||
public int mDisplayWidth;
|
||||
public int mDisplayHeight;
|
||||
|
||||
public int mRotation;
|
||||
|
||||
public DisplayFrames(int displayId, DisplayInfo info) {
|
||||
mDisplayId = displayId;
|
||||
onDisplayInfoUpdated(info);
|
||||
}
|
||||
|
||||
public void onDisplayInfoUpdated(DisplayInfo info) {
|
||||
mDisplayWidth = info.logicalWidth;
|
||||
mDisplayHeight = info.logicalHeight;
|
||||
mRotation = info.rotation;
|
||||
mDisplayInfoOverscan.set(
|
||||
info.overscanLeft, info.overscanTop, info.overscanRight, info.overscanBottom);
|
||||
}
|
||||
|
||||
public void onBeginLayout() {
|
||||
switch (mRotation) {
|
||||
case ROTATION_90:
|
||||
mRotatedDisplayInfoOverscan.left = mDisplayInfoOverscan.top;
|
||||
mRotatedDisplayInfoOverscan.top = mDisplayInfoOverscan.right;
|
||||
mRotatedDisplayInfoOverscan.right = mDisplayInfoOverscan.bottom;
|
||||
mRotatedDisplayInfoOverscan.bottom = mDisplayInfoOverscan.left;
|
||||
break;
|
||||
case ROTATION_180:
|
||||
mRotatedDisplayInfoOverscan.left = mDisplayInfoOverscan.right;
|
||||
mRotatedDisplayInfoOverscan.top = mDisplayInfoOverscan.bottom;
|
||||
mRotatedDisplayInfoOverscan.right = mDisplayInfoOverscan.left;
|
||||
mRotatedDisplayInfoOverscan.bottom = mDisplayInfoOverscan.top;
|
||||
break;
|
||||
case ROTATION_270:
|
||||
mRotatedDisplayInfoOverscan.left = mDisplayInfoOverscan.bottom;
|
||||
mRotatedDisplayInfoOverscan.top = mDisplayInfoOverscan.left;
|
||||
mRotatedDisplayInfoOverscan.right = mDisplayInfoOverscan.top;
|
||||
mRotatedDisplayInfoOverscan.bottom = mDisplayInfoOverscan.right;
|
||||
break;
|
||||
default:
|
||||
mRotatedDisplayInfoOverscan.set(mDisplayInfoOverscan);
|
||||
break;
|
||||
}
|
||||
|
||||
mRestrictedOverscan.set(0, 0, mDisplayWidth, mDisplayHeight);
|
||||
mOverscan.set(mRestrictedOverscan);
|
||||
mSystem.set(mRestrictedOverscan);
|
||||
mUnrestricted.set(mRotatedDisplayInfoOverscan);
|
||||
mUnrestricted.right = mDisplayWidth - mUnrestricted.right;
|
||||
mUnrestricted.bottom = mDisplayHeight - mUnrestricted.bottom;
|
||||
mRestricted.set(mUnrestricted);
|
||||
mDock.set(mUnrestricted);
|
||||
mContent.set(mUnrestricted);
|
||||
mVoiceContent.set(mUnrestricted);
|
||||
mStable.set(mUnrestricted);
|
||||
mStableFullscreen.set(mUnrestricted);
|
||||
mCurrent.set(mUnrestricted);
|
||||
|
||||
}
|
||||
|
||||
public int getInputMethodWindowVisibleHeight() {
|
||||
return mDock.bottom - mCurrent.bottom;
|
||||
}
|
||||
|
||||
public void writeToProto(ProtoOutputStream proto, long fieldId) {
|
||||
final long token = proto.start(fieldId);
|
||||
mStable.writeToProto(proto, STABLE_BOUNDS);
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
public void dump(String prefix, PrintWriter pw) {
|
||||
pw.println(prefix + "DisplayFrames w=" + mDisplayWidth + " h=" + mDisplayHeight
|
||||
+ " r=" + mRotation);
|
||||
final String myPrefix = prefix + " ";
|
||||
dumpFrame(mStable, "mStable", myPrefix, pw);
|
||||
dumpFrame(mStableFullscreen, "mStableFullscreen", myPrefix, pw);
|
||||
dumpFrame(mDock, "mDock", myPrefix, pw);
|
||||
dumpFrame(mCurrent, "mCurrent", myPrefix, pw);
|
||||
dumpFrame(mSystem, "mSystem", myPrefix, pw);
|
||||
dumpFrame(mContent, "mContent", myPrefix, pw);
|
||||
dumpFrame(mVoiceContent, "mVoiceContent", myPrefix, pw);
|
||||
dumpFrame(mOverscan, "mOverscan", myPrefix, pw);
|
||||
dumpFrame(mRestrictedOverscan, "mRestrictedOverscan", myPrefix, pw);
|
||||
dumpFrame(mRestricted, "mRestricted", myPrefix, pw);
|
||||
dumpFrame(mUnrestricted, "mUnrestricted", myPrefix, pw);
|
||||
dumpFrame(mDisplayInfoOverscan, "mDisplayInfoOverscan", myPrefix, pw);
|
||||
dumpFrame(mRotatedDisplayInfoOverscan, "mRotatedDisplayInfoOverscan", myPrefix, pw);
|
||||
}
|
||||
|
||||
private void dumpFrame(Rect frame, String name, String prefix, PrintWriter pw) {
|
||||
pw.print(prefix + name + "="); frame.printShortString(pw); pw.println();
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,6 @@ import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SystemApi;
|
||||
import android.app.ActivityManager.StackId;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.CompatibilityInfo;
|
||||
@@ -721,12 +720,6 @@ public interface WindowManagerPolicy {
|
||||
*/
|
||||
public void setInitialDisplaySize(Display display, int width, int height, int density);
|
||||
|
||||
/**
|
||||
* Called by window manager to set the overscan region that should be used for the
|
||||
* given display.
|
||||
*/
|
||||
public void setDisplayOverscan(Display display, int left, int top, int right, int bottom);
|
||||
|
||||
/**
|
||||
* Check permissions when adding a window.
|
||||
*
|
||||
@@ -1173,14 +1166,10 @@ public interface WindowManagerPolicy {
|
||||
/**
|
||||
* Called when layout of the windows is about to start.
|
||||
*
|
||||
* @param displayId Id of the display we are doing layout on.
|
||||
* @param displayWidth The current full width of the screen.
|
||||
* @param displayHeight The current full height of the screen.
|
||||
* @param displayRotation The current rotation being applied to the base window.
|
||||
* @param displayFrames frames of the display we are doing layout on.
|
||||
* @param uiMode The current uiMode in configuration.
|
||||
*/
|
||||
public void beginLayoutLw(int displayId, int displayWidth, int displayHeight,
|
||||
int displayRotation, int uiMode);
|
||||
default void beginLayoutLw(DisplayFrames displayFrames, int uiMode) {}
|
||||
|
||||
/**
|
||||
* Returns the bottom-most layer of the system decor, above which no policy decor should
|
||||
@@ -1189,37 +1178,28 @@ public interface WindowManagerPolicy {
|
||||
public int getSystemDecorLayerLw();
|
||||
|
||||
/**
|
||||
* Return the rectangle of the screen that is available for applications to run in.
|
||||
* This will be called immediately after {@link #beginLayoutLw}.
|
||||
*
|
||||
* @param r The rectangle to be filled with the boundaries available to applications.
|
||||
*/
|
||||
public void getContentRectLw(Rect r);
|
||||
|
||||
/**
|
||||
* Called for each window attached to the window manager as layout is
|
||||
* proceeding. The implementation of this function must take care of
|
||||
* setting the window's frame, either here or in finishLayout().
|
||||
* Called for each window attached to the window manager as layout is proceeding. The
|
||||
* implementation of this function must take care of setting the window's frame, either here or
|
||||
* in finishLayout().
|
||||
*
|
||||
* @param win The window being positioned.
|
||||
* @param attached For sub-windows, the window it is attached to; this
|
||||
* window will already have had layoutWindow() called on it
|
||||
* so you can use its Rect. Otherwise null.
|
||||
* @param displayFrames The display frames.
|
||||
*/
|
||||
public void layoutWindowLw(WindowState win, WindowState attached);
|
||||
default void layoutWindowLw(
|
||||
WindowState win, WindowState attached, DisplayFrames displayFrames) {}
|
||||
|
||||
|
||||
/**
|
||||
* Return the insets for the areas covered by system windows. These values
|
||||
* are computed on the most recent layout, so they are not guaranteed to
|
||||
* be correct.
|
||||
* Return the insets for the areas covered by system windows. These values are computed on the
|
||||
* most recent layout, so they are not guaranteed to be correct.
|
||||
*
|
||||
* @param attrs The LayoutParams of the window.
|
||||
* @param taskBounds The bounds of the task this window is on or {@code null} if no task is
|
||||
* associated with the window.
|
||||
* @param displayRotation Rotation of the display.
|
||||
* @param displayWidth The width of the display.
|
||||
* @param displayHeight The height of the display.
|
||||
* @param displayFrames display frames.
|
||||
* @param outContentInsets The areas covered by system windows, expressed as positive insets.
|
||||
* @param outStableInsets The areas covered by stable system windows irrespective of their
|
||||
* current visibility. Expressed as positive insets.
|
||||
@@ -1227,16 +1207,11 @@ public interface WindowManagerPolicy {
|
||||
* @return Whether to always consume the navigation bar.
|
||||
* See {@link #isNavBarForcedShownLw(WindowState)}.
|
||||
*/
|
||||
public boolean getInsetHintLw(WindowManager.LayoutParams attrs, Rect taskBounds,
|
||||
int displayRotation, int displayWidth, int displayHeight, Rect outContentInsets,
|
||||
Rect outStableInsets, Rect outOutsets);
|
||||
|
||||
/**
|
||||
* Called when layout of the windows is finished. After this function has
|
||||
* returned, all windows given to layoutWindow() <em>must</em> have had a
|
||||
* frame assigned.
|
||||
*/
|
||||
public void finishLayoutLw();
|
||||
default boolean getInsetHintLw(WindowManager.LayoutParams attrs, Rect taskBounds,
|
||||
DisplayFrames displayFrames, Rect outContentInsets, Rect outStableInsets,
|
||||
Rect outOutsets) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Layout state may have changed (so another layout will be performed) */
|
||||
static final int FINISH_LAYOUT_REDO_LAYOUT = 0x0001;
|
||||
@@ -1652,11 +1627,6 @@ public interface WindowManagerPolicy {
|
||||
*/
|
||||
public void showGlobalActions();
|
||||
|
||||
/**
|
||||
* @return The current height of the input method window.
|
||||
*/
|
||||
public int getInputMethodWindowVisibleHeightLw();
|
||||
|
||||
/**
|
||||
* Called when the current user changes. Guaranteed to be called before the broadcast
|
||||
* of the new user id is made to all listeners.
|
||||
|
||||
Reference in New Issue
Block a user