diff options
| author | Wale Ogunwale <ogunwale@google.com> | 2017-11-14 01:01:29 +0000 |
|---|---|---|
| committer | Wale Ogunwale <ogunwale@google.com> | 2017-11-14 01:03:50 +0000 |
| commit | 828ff7e3ef032f3c3b149be9961fa39a979d2fd2 (patch) | |
| tree | 4cca378419a88c94fe6379b28e65d43c2d6a3c12 /core/java/android | |
| parent | 7bb06e012a33c94c68b173bc8f276f78e0d60764 (diff) | |
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
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/Instrumentation.java | 44 | ||||
| -rw-r--r-- | core/java/android/view/DisplayFrames.java | 189 | ||||
| -rw-r--r-- | core/java/android/view/WindowManagerPolicy.java | 62 |
3 files changed, 242 insertions, 53 deletions
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index e260967f92d0..d49e11f47fea 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -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; } } diff --git a/core/java/android/view/DisplayFrames.java b/core/java/android/view/DisplayFrames.java new file mode 100644 index 000000000000..e6861d83d2fd --- /dev/null +++ b/core/java/android/view/DisplayFrames.java @@ -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(); + } +} diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index ebe3633de402..534335bf4743 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -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; @@ -722,12 +721,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. * * @param attrs The window's LayoutParams. @@ -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; @@ -1653,11 +1628,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. * |
