Loading core/java/android/provider/Settings.java +10 −0 Original line number Diff line number Diff line Loading @@ -10163,6 +10163,16 @@ public final class Settings { */ public static final String POLICY_CONTROL = "policy_control"; /** * {@link android.view.DisplayCutout DisplayCutout} emulation mode. * * @hide */ public static final String EMULATE_DISPLAY_CUTOUT = "emulate_display_cutout"; /** @hide */ public static final int EMULATE_DISPLAY_CUTOUT_OFF = 0; /** @hide */ public static final int EMULATE_DISPLAY_CUTOUT_ON = 1; /** * Defines global zen mode. ZEN_MODE_OFF, ZEN_MODE_IMPORTANT_INTERRUPTIONS, * or ZEN_MODE_NO_INTERRUPTIONS. Loading core/java/android/view/WindowManager.java +29 −0 Original line number Diff line number Diff line Loading @@ -1268,6 +1268,35 @@ public interface WindowManager extends ViewManager { }, formatToHexString = true) public int flags; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef( flag = true, value = { LayoutParams.FLAG2_LAYOUT_IN_DISPLAY_CUTOUT_AREA, }) @interface Flags2 {} /** * Window flag: allow placing the window within the area that overlaps with the * display cutout. * * <p> * The window must correctly position its contents to take the display cutout into account. * * @see DisplayCutout * @hide for now */ public static final long FLAG2_LAYOUT_IN_DISPLAY_CUTOUT_AREA = 0x00000001; /** * Various behavioral options/flags. Default is none. * * @see #FLAG2_LAYOUT_IN_DISPLAY_CUTOUT_AREA * @hide for now */ @Flags2 public long flags2; /** * If the window has requested hardware acceleration, but this is not * allowed in the process it is in, then still render it as if it is Loading core/tests/coretests/src/android/provider/SettingsBackupTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,7 @@ public class SettingsBackupTest { Settings.Global.DROPBOX_RESERVE_PERCENT, Settings.Global.DROPBOX_TAG_PREFIX, Settings.Global.EMERGENCY_AFFORDANCE_NEEDED, Settings.Global.EMULATE_DISPLAY_CUTOUT, Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED, Settings.Global.ENABLE_CACHE_QUOTA_CALCULATION, Settings.Global.ENABLE_CELLULAR_ON_BOOT, Loading packages/SystemUI/res/values/config.xml +1 −0 Original line number Diff line number Diff line Loading @@ -337,6 +337,7 @@ <item>com.android.systemui.LatencyTester</item> <item>com.android.systemui.globalactions.GlobalActionsComponent</item> <item>com.android.systemui.RoundedCorners</item> <item>com.android.systemui.EmulatedDisplayCutout</item> </string-array> <!-- SystemUI vender service, used in config_systemUIServiceComponents. --> Loading packages/SystemUI/src/com/android/systemui/EmulatedDisplayCutout.java 0 → 100644 +140 −0 Original line number Diff line number Diff line /* * 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 com.android.systemui; import android.content.Context; import android.database.ContentObserver; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PixelFormat; import android.graphics.Point; import android.os.Handler; import android.os.Looper; import android.os.UserHandle; import android.provider.Settings; import android.view.DisplayCutout; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.WindowInsets; import android.view.WindowManager; import java.util.ArrayList; /** * Emulates a display cutout by drawing its shape in an overlay as supplied by * {@link DisplayCutout}. */ public class EmulatedDisplayCutout extends SystemUI { private View mOverlay; private boolean mAttached; private WindowManager mWindowManager; @Override public void start() { mWindowManager = mContext.getSystemService(WindowManager.class); mContext.getContentResolver().registerContentObserver( Settings.Global.getUriFor(Settings.Global.EMULATE_DISPLAY_CUTOUT), false, mObserver, UserHandle.USER_ALL); mObserver.onChange(false); } private void setAttached(boolean attached) { if (attached && !mAttached) { if (mOverlay == null) { mOverlay = new CutoutView(mContext); mOverlay.setLayoutParams(getLayoutParams()); } mWindowManager.addView(mOverlay, mOverlay.getLayoutParams()); mAttached = true; } else if (!attached && mAttached) { mWindowManager.removeView(mOverlay); mAttached = false; } } private WindowManager.LayoutParams getLayoutParams() { final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH | WindowManager.LayoutParams.FLAG_SLIPPERY | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR, PixelFormat.TRANSLUCENT); lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS | WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY; lp.setTitle("EmulatedDisplayCutout"); lp.gravity = Gravity.TOP; return lp; } private ContentObserver mObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { @Override public void onChange(boolean selfChange) { boolean emulateCutout = Settings.Global.getInt( mContext.getContentResolver(), Settings.Global.EMULATE_DISPLAY_CUTOUT, Settings.Global.EMULATE_DISPLAY_CUTOUT_OFF) != Settings.Global.EMULATE_DISPLAY_CUTOUT_OFF; setAttached(emulateCutout); } }; private static class CutoutView extends View { private Paint mPaint = new Paint(); private Path mPath = new Path(); private ArrayList<Point> mBoundingPolygon = new ArrayList<>(); CutoutView(Context context) { super(context); } @Override public WindowInsets onApplyWindowInsets(WindowInsets insets) { insets.getDisplayCutout().getBoundingPolygon(mBoundingPolygon); invalidate(); return insets.consumeCutout(); } @Override protected void onDraw(Canvas canvas) { if (!mBoundingPolygon.isEmpty()) { mPaint.setColor(Color.DKGRAY); mPaint.setStyle(Paint.Style.FILL); mPath.reset(); for (int i = 0; i < mBoundingPolygon.size(); i++) { Point point = mBoundingPolygon.get(i); if (i == 0) { mPath.moveTo(point.x, point.y); } else { mPath.lineTo(point.x, point.y); } } mPath.close(); canvas.drawPath(mPath, mPaint); } } } } Loading
core/java/android/provider/Settings.java +10 −0 Original line number Diff line number Diff line Loading @@ -10163,6 +10163,16 @@ public final class Settings { */ public static final String POLICY_CONTROL = "policy_control"; /** * {@link android.view.DisplayCutout DisplayCutout} emulation mode. * * @hide */ public static final String EMULATE_DISPLAY_CUTOUT = "emulate_display_cutout"; /** @hide */ public static final int EMULATE_DISPLAY_CUTOUT_OFF = 0; /** @hide */ public static final int EMULATE_DISPLAY_CUTOUT_ON = 1; /** * Defines global zen mode. ZEN_MODE_OFF, ZEN_MODE_IMPORTANT_INTERRUPTIONS, * or ZEN_MODE_NO_INTERRUPTIONS. Loading
core/java/android/view/WindowManager.java +29 −0 Original line number Diff line number Diff line Loading @@ -1268,6 +1268,35 @@ public interface WindowManager extends ViewManager { }, formatToHexString = true) public int flags; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef( flag = true, value = { LayoutParams.FLAG2_LAYOUT_IN_DISPLAY_CUTOUT_AREA, }) @interface Flags2 {} /** * Window flag: allow placing the window within the area that overlaps with the * display cutout. * * <p> * The window must correctly position its contents to take the display cutout into account. * * @see DisplayCutout * @hide for now */ public static final long FLAG2_LAYOUT_IN_DISPLAY_CUTOUT_AREA = 0x00000001; /** * Various behavioral options/flags. Default is none. * * @see #FLAG2_LAYOUT_IN_DISPLAY_CUTOUT_AREA * @hide for now */ @Flags2 public long flags2; /** * If the window has requested hardware acceleration, but this is not * allowed in the process it is in, then still render it as if it is Loading
core/tests/coretests/src/android/provider/SettingsBackupTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,7 @@ public class SettingsBackupTest { Settings.Global.DROPBOX_RESERVE_PERCENT, Settings.Global.DROPBOX_TAG_PREFIX, Settings.Global.EMERGENCY_AFFORDANCE_NEEDED, Settings.Global.EMULATE_DISPLAY_CUTOUT, Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED, Settings.Global.ENABLE_CACHE_QUOTA_CALCULATION, Settings.Global.ENABLE_CELLULAR_ON_BOOT, Loading
packages/SystemUI/res/values/config.xml +1 −0 Original line number Diff line number Diff line Loading @@ -337,6 +337,7 @@ <item>com.android.systemui.LatencyTester</item> <item>com.android.systemui.globalactions.GlobalActionsComponent</item> <item>com.android.systemui.RoundedCorners</item> <item>com.android.systemui.EmulatedDisplayCutout</item> </string-array> <!-- SystemUI vender service, used in config_systemUIServiceComponents. --> Loading
packages/SystemUI/src/com/android/systemui/EmulatedDisplayCutout.java 0 → 100644 +140 −0 Original line number Diff line number Diff line /* * 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 com.android.systemui; import android.content.Context; import android.database.ContentObserver; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PixelFormat; import android.graphics.Point; import android.os.Handler; import android.os.Looper; import android.os.UserHandle; import android.provider.Settings; import android.view.DisplayCutout; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.WindowInsets; import android.view.WindowManager; import java.util.ArrayList; /** * Emulates a display cutout by drawing its shape in an overlay as supplied by * {@link DisplayCutout}. */ public class EmulatedDisplayCutout extends SystemUI { private View mOverlay; private boolean mAttached; private WindowManager mWindowManager; @Override public void start() { mWindowManager = mContext.getSystemService(WindowManager.class); mContext.getContentResolver().registerContentObserver( Settings.Global.getUriFor(Settings.Global.EMULATE_DISPLAY_CUTOUT), false, mObserver, UserHandle.USER_ALL); mObserver.onChange(false); } private void setAttached(boolean attached) { if (attached && !mAttached) { if (mOverlay == null) { mOverlay = new CutoutView(mContext); mOverlay.setLayoutParams(getLayoutParams()); } mWindowManager.addView(mOverlay, mOverlay.getLayoutParams()); mAttached = true; } else if (!attached && mAttached) { mWindowManager.removeView(mOverlay); mAttached = false; } } private WindowManager.LayoutParams getLayoutParams() { final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH | WindowManager.LayoutParams.FLAG_SLIPPERY | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR, PixelFormat.TRANSLUCENT); lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS | WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY; lp.setTitle("EmulatedDisplayCutout"); lp.gravity = Gravity.TOP; return lp; } private ContentObserver mObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { @Override public void onChange(boolean selfChange) { boolean emulateCutout = Settings.Global.getInt( mContext.getContentResolver(), Settings.Global.EMULATE_DISPLAY_CUTOUT, Settings.Global.EMULATE_DISPLAY_CUTOUT_OFF) != Settings.Global.EMULATE_DISPLAY_CUTOUT_OFF; setAttached(emulateCutout); } }; private static class CutoutView extends View { private Paint mPaint = new Paint(); private Path mPath = new Path(); private ArrayList<Point> mBoundingPolygon = new ArrayList<>(); CutoutView(Context context) { super(context); } @Override public WindowInsets onApplyWindowInsets(WindowInsets insets) { insets.getDisplayCutout().getBoundingPolygon(mBoundingPolygon); invalidate(); return insets.consumeCutout(); } @Override protected void onDraw(Canvas canvas) { if (!mBoundingPolygon.isEmpty()) { mPaint.setColor(Color.DKGRAY); mPaint.setStyle(Paint.Style.FILL); mPath.reset(); for (int i = 0; i < mBoundingPolygon.size(); i++) { Point point = mBoundingPolygon.get(i); if (i == 0) { mPath.moveTo(point.x, point.y); } else { mPath.lineTo(point.x, point.y); } } mPath.close(); canvas.drawPath(mPath, mPaint); } } } }