blob: 8d32e4db6d214409d587a009759ebf5af992a00b [file] [log] [blame]
Adrian Roos5b518852018-01-23 17:23:38 +01001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11 * KIND, either express or implied. See the License for the specific language governing
12 * permissions and limitations under the License.
13 */
14
15package com.android.systemui;
16
Adrian Roos51072a82018-04-10 15:17:08 -070017import static android.view.Surface.ROTATION_0;
18import static android.view.Surface.ROTATION_180;
19import static android.view.Surface.ROTATION_270;
20import static android.view.Surface.ROTATION_90;
Adrian Roos5b518852018-01-23 17:23:38 +010021import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
22import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
23import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
24
25import static com.android.systemui.tuner.TunablePadding.FLAG_START;
26import static com.android.systemui.tuner.TunablePadding.FLAG_END;
27
Adrian Roos51072a82018-04-10 15:17:08 -070028import android.annotation.Dimension;
Adrian Roos5b518852018-01-23 17:23:38 +010029import android.app.Fragment;
30import android.content.Context;
31import android.content.res.ColorStateList;
32import android.content.res.Configuration;
33import android.graphics.Canvas;
34import android.graphics.Color;
Adrian Roos51072a82018-04-10 15:17:08 -070035import android.graphics.Matrix;
Adrian Roos5b518852018-01-23 17:23:38 +010036import android.graphics.Paint;
37import android.graphics.Path;
38import android.graphics.PixelFormat;
39import android.graphics.Rect;
Adrian Roos6a4fa0e2018-03-05 19:50:16 +010040import android.graphics.Region;
Adrian Roos5b518852018-01-23 17:23:38 +010041import android.hardware.display.DisplayManager;
Adrian Roos56d1a2c2018-03-08 23:22:19 +010042import android.os.SystemProperties;
Adrian Roos5b518852018-01-23 17:23:38 +010043import android.provider.Settings.Secure;
44import android.support.annotation.VisibleForTesting;
45import android.util.DisplayMetrics;
46import android.view.DisplayCutout;
47import android.view.DisplayInfo;
48import android.view.Gravity;
49import android.view.LayoutInflater;
Adrian Roos51072a82018-04-10 15:17:08 -070050import android.view.Surface;
Adrian Roos5b518852018-01-23 17:23:38 +010051import android.view.View;
52import android.view.View.OnLayoutChangeListener;
53import android.view.ViewGroup;
54import android.view.ViewGroup.LayoutParams;
55import android.view.WindowManager;
56import android.widget.FrameLayout;
57import android.widget.ImageView;
58
Evan Lairdb0506ca2018-03-15 10:34:31 -040059import com.android.systemui.RegionInterceptingFrameLayout.RegionInterceptableView;
Adrian Roos5b518852018-01-23 17:23:38 +010060import com.android.systemui.fragments.FragmentHostManager;
61import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
62import com.android.systemui.plugins.qs.QS;
63import com.android.systemui.qs.SecureSetting;
64import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
65import com.android.systemui.statusbar.phone.StatusBar;
66import com.android.systemui.tuner.TunablePadding;
67import com.android.systemui.tuner.TunerService;
68import com.android.systemui.tuner.TunerService.Tunable;
69
70/**
71 * An overlay that draws screen decorations in software (e.g for rounded corners or display cutout)
72 * for antialiasing and emulation purposes.
73 */
74public class ScreenDecorations extends SystemUI implements Tunable {
75 public static final String SIZE = "sysui_rounded_size";
76 public static final String PADDING = "sysui_rounded_content_padding";
Adrian Roos56d1a2c2018-03-08 23:22:19 +010077 private static final boolean DEBUG_SCREENSHOT_ROUNDED_CORNERS =
78 SystemProperties.getBoolean("debug.screenshot_rounded_corners", false);
Adrian Roos5b518852018-01-23 17:23:38 +010079
80 private int mRoundedDefault;
Beverlya5f7a302018-04-25 09:19:05 -040081 private int mRoundedDefaultTop;
82 private int mRoundedDefaultBottom;
Adrian Roos5b518852018-01-23 17:23:38 +010083 private View mOverlay;
84 private View mBottomOverlay;
85 private float mDensity;
86 private WindowManager mWindowManager;
87 private boolean mLandscape;
88
89 @Override
90 public void start() {
91 mWindowManager = mContext.getSystemService(WindowManager.class);
92 mRoundedDefault = mContext.getResources().getDimensionPixelSize(
93 R.dimen.rounded_corner_radius);
Beverlya5f7a302018-04-25 09:19:05 -040094 mRoundedDefaultTop = mContext.getResources().getDimensionPixelSize(
95 R.dimen.rounded_corner_radius_top);
96 mRoundedDefaultBottom = mContext.getResources().getDimensionPixelSize(
97 R.dimen.rounded_corner_radius_bottom);
98 if (hasRoundedCorners() || shouldDrawCutout()) {
Adrian Roos5b518852018-01-23 17:23:38 +010099 setupDecorations();
100 }
Beverlya5f7a302018-04-25 09:19:05 -0400101
Adrian Roos5b518852018-01-23 17:23:38 +0100102 int padding = mContext.getResources().getDimensionPixelSize(
103 R.dimen.rounded_corner_content_padding);
104 if (padding != 0) {
105 setupPadding(padding);
106 }
107 }
108
109 private void setupDecorations() {
110 mOverlay = LayoutInflater.from(mContext)
111 .inflate(R.layout.rounded_corners, null);
112 ((ViewGroup)mOverlay).addView(new DisplayCutoutView(mContext, true,
113 this::updateWindowVisibilities));
114 mBottomOverlay = LayoutInflater.from(mContext)
115 .inflate(R.layout.rounded_corners, null);
116 ((ViewGroup)mBottomOverlay).addView(new DisplayCutoutView(mContext, false,
117 this::updateWindowVisibilities));
118
119 mOverlay.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
120 mOverlay.setAlpha(0);
121
122 mBottomOverlay.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
123 mBottomOverlay.setAlpha(0);
124
125 updateViews();
126
127 mWindowManager.addView(mOverlay, getWindowLayoutParams());
128 mWindowManager.addView(mBottomOverlay, getBottomLayoutParams());
129
130 DisplayMetrics metrics = new DisplayMetrics();
131 mWindowManager.getDefaultDisplay().getMetrics(metrics);
132 mDensity = metrics.density;
133
134 Dependency.get(TunerService.class).addTunable(this, SIZE);
135
136 // Watch color inversion and invert the overlay as needed.
137 SecureSetting setting = new SecureSetting(mContext, Dependency.get(Dependency.MAIN_HANDLER),
138 Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED) {
139 @Override
140 protected void handleValueChanged(int value, boolean observedChange) {
141 int tint = value != 0 ? Color.WHITE : Color.BLACK;
142 ColorStateList tintList = ColorStateList.valueOf(tint);
143 ((ImageView) mOverlay.findViewById(R.id.left)).setImageTintList(tintList);
144 ((ImageView) mOverlay.findViewById(R.id.right)).setImageTintList(tintList);
145 ((ImageView) mBottomOverlay.findViewById(R.id.left)).setImageTintList(tintList);
146 ((ImageView) mBottomOverlay.findViewById(R.id.right)).setImageTintList(tintList);
147 }
148 };
149 setting.setListening(true);
150 setting.onChange(false);
151
152 mOverlay.addOnLayoutChangeListener(new OnLayoutChangeListener() {
153 @Override
154 public void onLayoutChange(View v, int left, int top, int right, int bottom,
155 int oldLeft,
156 int oldTop, int oldRight, int oldBottom) {
157 mOverlay.removeOnLayoutChangeListener(this);
158 mOverlay.animate()
159 .alpha(1)
160 .setDuration(1000)
161 .start();
162 mBottomOverlay.animate()
163 .alpha(1)
164 .setDuration(1000)
165 .start();
166 }
167 });
168 }
169
170 @Override
171 protected void onConfigurationChanged(Configuration newConfig) {
172 boolean newLanscape = newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE;
173 if (newLanscape != mLandscape) {
174 mLandscape = newLanscape;
175
176 if (mOverlay != null) {
177 updateLayoutParams();
178 updateViews();
179 }
180 }
181 if (shouldDrawCutout() && mOverlay == null) {
182 setupDecorations();
183 }
184 }
185
186 private void updateViews() {
187 View topLeft = mOverlay.findViewById(R.id.left);
188 View topRight = mOverlay.findViewById(R.id.right);
189 View bottomLeft = mBottomOverlay.findViewById(R.id.left);
190 View bottomRight = mBottomOverlay.findViewById(R.id.right);
191 if (mLandscape) {
192 // Flip corners
193 View tmp = topRight;
194 topRight = bottomLeft;
195 bottomLeft = tmp;
196 }
197 updateView(topLeft, Gravity.TOP | Gravity.LEFT, 0);
198 updateView(topRight, Gravity.TOP | Gravity.RIGHT, 90);
199 updateView(bottomLeft, Gravity.BOTTOM | Gravity.LEFT, 270);
200 updateView(bottomRight, Gravity.BOTTOM | Gravity.RIGHT, 180);
201
202 updateWindowVisibilities();
203 }
204
205 private void updateView(View v, int gravity, int rotation) {
206 ((FrameLayout.LayoutParams)v.getLayoutParams()).gravity = gravity;
207 v.setRotation(rotation);
208 }
209
210 private void updateWindowVisibilities() {
211 updateWindowVisibility(mOverlay);
212 updateWindowVisibility(mBottomOverlay);
213 }
214
215 private void updateWindowVisibility(View overlay) {
216 boolean visibleForCutout = shouldDrawCutout()
217 && overlay.findViewById(R.id.display_cutout).getVisibility() == View.VISIBLE;
Beverlya5f7a302018-04-25 09:19:05 -0400218 boolean visibleForRoundedCorners = hasRoundedCorners();
Adrian Roos5b518852018-01-23 17:23:38 +0100219 overlay.setVisibility(visibleForCutout || visibleForRoundedCorners
220 ? View.VISIBLE : View.GONE);
221 }
222
Beverlya5f7a302018-04-25 09:19:05 -0400223 private boolean hasRoundedCorners() {
224 return mRoundedDefault > 0 || mRoundedDefaultBottom > 0 || mRoundedDefaultTop > 0;
225 }
226
Adrian Roos5b518852018-01-23 17:23:38 +0100227 private boolean shouldDrawCutout() {
Adrian Roosc41b32b2018-04-12 10:13:48 +0200228 return shouldDrawCutout(mContext);
229 }
230
231 static boolean shouldDrawCutout(Context context) {
232 return context.getResources().getBoolean(
Adrian Roos5b518852018-01-23 17:23:38 +0100233 com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout);
234 }
235
236 private void setupPadding(int padding) {
237 // Add some padding to all the content near the edge of the screen.
238 StatusBar sb = getComponent(StatusBar.class);
239 View statusBar = (sb != null ? sb.getStatusBarWindow() : null);
240 if (statusBar != null) {
241 TunablePadding.addTunablePadding(statusBar.findViewById(R.id.keyguard_header), PADDING,
242 padding, FLAG_END);
243
244 FragmentHostManager fragmentHostManager = FragmentHostManager.get(statusBar);
245 fragmentHostManager.addTagListener(CollapsedStatusBarFragment.TAG,
246 new TunablePaddingTagListener(padding, R.id.status_bar));
247 fragmentHostManager.addTagListener(QS.TAG,
248 new TunablePaddingTagListener(padding, R.id.header));
249 }
250 }
251
252 @VisibleForTesting
253 WindowManager.LayoutParams getWindowLayoutParams() {
254 final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
255 ViewGroup.LayoutParams.MATCH_PARENT,
256 LayoutParams.WRAP_CONTENT,
257 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
Evan Lairdb0506ca2018-03-15 10:34:31 -0400258 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Adrian Roos5b518852018-01-23 17:23:38 +0100259 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
260 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
261 | WindowManager.LayoutParams.FLAG_SLIPPERY
262 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
263 PixelFormat.TRANSLUCENT);
Robert Carr772e8bc2018-03-14 11:51:23 -0700264 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS
265 | WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
266
Adrian Roos56d1a2c2018-03-08 23:22:19 +0100267 if (!DEBUG_SCREENSHOT_ROUNDED_CORNERS) {
268 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
269 }
Robert Carr772e8bc2018-03-14 11:51:23 -0700270
Adrian Roos5b518852018-01-23 17:23:38 +0100271 lp.setTitle("ScreenDecorOverlay");
272 lp.gravity = Gravity.TOP | Gravity.LEFT;
273 lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
274 if (mLandscape) {
275 lp.width = WRAP_CONTENT;
276 lp.height = MATCH_PARENT;
277 }
278 return lp;
279 }
280
281 private WindowManager.LayoutParams getBottomLayoutParams() {
282 WindowManager.LayoutParams lp = getWindowLayoutParams();
283 lp.setTitle("ScreenDecorOverlayBottom");
284 lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
285 return lp;
286 }
287
288 private void updateLayoutParams() {
289 mWindowManager.updateViewLayout(mOverlay, getWindowLayoutParams());
290 mWindowManager.updateViewLayout(mBottomOverlay, getBottomLayoutParams());
291 }
292
293 @Override
294 public void onTuningChanged(String key, String newValue) {
295 if (mOverlay == null) return;
296 if (SIZE.equals(key)) {
297 int size = mRoundedDefault;
Beverlya5f7a302018-04-25 09:19:05 -0400298 int sizeTop = mRoundedDefaultTop;
299 int sizeBottom = mRoundedDefaultBottom;
300 if (newValue != null) {
301 try {
302 size = (int) (Integer.parseInt(newValue) * mDensity);
303 } catch (Exception e) {
304 }
Adrian Roos5b518852018-01-23 17:23:38 +0100305 }
Beverlya5f7a302018-04-25 09:19:05 -0400306
307 if (sizeTop == 0) {
308 sizeTop = size;
309 }
310 if (sizeBottom == 0) {
311 sizeBottom = size;
312 }
313
314 setSize(mOverlay.findViewById(R.id.left), sizeTop);
315 setSize(mOverlay.findViewById(R.id.right), sizeTop);
316 setSize(mBottomOverlay.findViewById(R.id.left), sizeBottom);
317 setSize(mBottomOverlay.findViewById(R.id.right), sizeBottom);
Adrian Roos5b518852018-01-23 17:23:38 +0100318 }
319 }
320
321 private void setSize(View view, int pixelSize) {
322 LayoutParams params = view.getLayoutParams();
323 params.width = pixelSize;
324 params.height = pixelSize;
325 view.setLayoutParams(params);
326 }
327
328 @VisibleForTesting
329 static class TunablePaddingTagListener implements FragmentListener {
330
331 private final int mPadding;
332 private final int mId;
333 private TunablePadding mTunablePadding;
334
335 public TunablePaddingTagListener(int padding, int id) {
336 mPadding = padding;
337 mId = id;
338 }
339
340 @Override
341 public void onFragmentViewCreated(String tag, Fragment fragment) {
342 if (mTunablePadding != null) {
343 mTunablePadding.destroy();
344 }
345 View view = fragment.getView();
346 if (mId != 0) {
347 view = view.findViewById(mId);
348 }
349 mTunablePadding = TunablePadding.addTunablePadding(view, PADDING, mPadding,
350 FLAG_START | FLAG_END);
351 }
352 }
353
Evan Lairdb0506ca2018-03-15 10:34:31 -0400354 public static class DisplayCutoutView extends View implements DisplayManager.DisplayListener,
355 RegionInterceptableView {
Adrian Roos5b518852018-01-23 17:23:38 +0100356
357 private final DisplayInfo mInfo = new DisplayInfo();
358 private final Paint mPaint = new Paint();
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100359 private final Region mBounds = new Region();
Adrian Roos5b518852018-01-23 17:23:38 +0100360 private final Rect mBoundingRect = new Rect();
361 private final Path mBoundingPath = new Path();
362 private final int[] mLocation = new int[2];
363 private final boolean mStart;
364 private final Runnable mVisibilityChangedListener;
365
366 public DisplayCutoutView(Context context, boolean start,
367 Runnable visibilityChangedListener) {
368 super(context);
369 mStart = start;
370 mVisibilityChangedListener = visibilityChangedListener;
371 setId(R.id.display_cutout);
372 }
373
374 @Override
375 protected void onAttachedToWindow() {
376 super.onAttachedToWindow();
377 mContext.getSystemService(DisplayManager.class).registerDisplayListener(this,
378 getHandler());
379 update();
380 }
381
382 @Override
383 protected void onDetachedFromWindow() {
384 super.onDetachedFromWindow();
385 mContext.getSystemService(DisplayManager.class).unregisterDisplayListener(this);
386 }
387
388 @Override
389 protected void onDraw(Canvas canvas) {
390 super.onDraw(canvas);
391 getLocationOnScreen(mLocation);
392 canvas.translate(-mLocation[0], -mLocation[1]);
393 if (!mBoundingPath.isEmpty()) {
394 mPaint.setColor(Color.BLACK);
395 mPaint.setStyle(Paint.Style.FILL);
Adrian Roos51072a82018-04-10 15:17:08 -0700396 mPaint.setAntiAlias(true);
Adrian Roos5b518852018-01-23 17:23:38 +0100397 canvas.drawPath(mBoundingPath, mPaint);
398 }
399 }
400
401 @Override
402 public void onDisplayAdded(int displayId) {
403 }
404
405 @Override
406 public void onDisplayRemoved(int displayId) {
407 }
408
409 @Override
410 public void onDisplayChanged(int displayId) {
411 if (displayId == getDisplay().getDisplayId()) {
412 update();
413 }
414 }
415
416 private void update() {
417 requestLayout();
418 getDisplay().getDisplayInfo(mInfo);
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100419 mBounds.setEmpty();
Adrian Roos5b518852018-01-23 17:23:38 +0100420 mBoundingRect.setEmpty();
421 mBoundingPath.reset();
422 int newVisible;
Adrian Roosc41b32b2018-04-12 10:13:48 +0200423 if (shouldDrawCutout(getContext()) && hasCutout()) {
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100424 mBounds.set(mInfo.displayCutout.getBounds());
425 localBounds(mBoundingRect);
Adrian Roos51072a82018-04-10 15:17:08 -0700426 updateBoundingPath();
Adrian Roos1b028282018-03-14 14:43:03 +0100427 invalidate();
Adrian Roos5b518852018-01-23 17:23:38 +0100428 newVisible = VISIBLE;
429 } else {
430 newVisible = GONE;
431 }
432 if (newVisible != getVisibility()) {
433 setVisibility(newVisible);
434 mVisibilityChangedListener.run();
435 }
436 }
437
Adrian Roos51072a82018-04-10 15:17:08 -0700438 private void updateBoundingPath() {
439 int lw = mInfo.logicalWidth;
440 int lh = mInfo.logicalHeight;
441
442 boolean flipped = mInfo.rotation == ROTATION_90 || mInfo.rotation == ROTATION_270;
443
444 int dw = flipped ? lh : lw;
445 int dh = flipped ? lw : lh;
446
Adrian Roosa99f5d62018-04-16 16:03:04 +0200447 mBoundingPath.set(DisplayCutout.pathFromResources(getResources(), dw, dh));
Adrian Roos51072a82018-04-10 15:17:08 -0700448 Matrix m = new Matrix();
449 transformPhysicalToLogicalCoordinates(mInfo.rotation, dw, dh, m);
450 mBoundingPath.transform(m);
451 }
452
453 private static void transformPhysicalToLogicalCoordinates(@Surface.Rotation int rotation,
454 @Dimension int physicalWidth, @Dimension int physicalHeight, Matrix out) {
455 switch (rotation) {
456 case ROTATION_0:
457 out.reset();
458 break;
459 case ROTATION_90:
460 out.setRotate(270);
461 out.postTranslate(0, physicalWidth);
462 break;
463 case ROTATION_180:
464 out.setRotate(180);
465 out.postTranslate(physicalWidth, physicalHeight);
466 break;
467 case ROTATION_270:
468 out.setRotate(90);
469 out.postTranslate(physicalHeight, 0);
470 break;
471 default:
472 throw new IllegalArgumentException("Unknown rotation: " + rotation);
473 }
474 }
475
Adrian Roos5b518852018-01-23 17:23:38 +0100476 private boolean hasCutout() {
Adrian Roos24264212018-02-19 16:26:15 +0100477 final DisplayCutout displayCutout = mInfo.displayCutout;
478 if (displayCutout == null) {
Adrian Roos5b518852018-01-23 17:23:38 +0100479 return false;
480 }
Adrian Roos5b518852018-01-23 17:23:38 +0100481 if (mStart) {
482 return displayCutout.getSafeInsetLeft() > 0
483 || displayCutout.getSafeInsetTop() > 0;
484 } else {
485 return displayCutout.getSafeInsetRight() > 0
486 || displayCutout.getSafeInsetBottom() > 0;
487 }
488 }
489
490 @Override
491 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100492 if (mBounds.isEmpty()) {
Adrian Roos5b518852018-01-23 17:23:38 +0100493 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
494 return;
495 }
496 setMeasuredDimension(
497 resolveSizeAndState(mBoundingRect.width(), widthMeasureSpec, 0),
498 resolveSizeAndState(mBoundingRect.height(), heightMeasureSpec, 0));
499 }
Adrian Roos6a4fa0e2018-03-05 19:50:16 +0100500
501 public static void boundsFromDirection(DisplayCutout displayCutout, int gravity, Rect out) {
502 Region bounds = displayCutout.getBounds();
503 switch (gravity) {
504 case Gravity.TOP:
505 bounds.op(0, 0, Integer.MAX_VALUE, displayCutout.getSafeInsetTop(),
506 Region.Op.INTERSECT);
507 out.set(bounds.getBounds());
508 break;
509 case Gravity.LEFT:
510 bounds.op(0, 0, displayCutout.getSafeInsetLeft(), Integer.MAX_VALUE,
511 Region.Op.INTERSECT);
512 out.set(bounds.getBounds());
513 break;
514 case Gravity.BOTTOM:
515 bounds.op(0, displayCutout.getSafeInsetTop() + 1, Integer.MAX_VALUE,
516 Integer.MAX_VALUE, Region.Op.INTERSECT);
517 out.set(bounds.getBounds());
518 break;
519 case Gravity.RIGHT:
520 bounds.op(displayCutout.getSafeInsetLeft() + 1, 0, Integer.MAX_VALUE,
521 Integer.MAX_VALUE, Region.Op.INTERSECT);
522 out.set(bounds.getBounds());
523 break;
524 }
525 bounds.recycle();
526 }
527
528 private void localBounds(Rect out) {
529 final DisplayCutout displayCutout = mInfo.displayCutout;
530
531 if (mStart) {
532 if (displayCutout.getSafeInsetLeft() > 0) {
533 boundsFromDirection(displayCutout, Gravity.LEFT, out);
534 } else if (displayCutout.getSafeInsetTop() > 0) {
535 boundsFromDirection(displayCutout, Gravity.TOP, out);
536 }
537 } else {
538 if (displayCutout.getSafeInsetRight() > 0) {
539 boundsFromDirection(displayCutout, Gravity.RIGHT, out);
540 } else if (displayCutout.getSafeInsetBottom() > 0) {
541 boundsFromDirection(displayCutout, Gravity.BOTTOM, out);
542 }
543 }
544 }
Evan Lairdb0506ca2018-03-15 10:34:31 -0400545
546 @Override
547 public boolean shouldInterceptTouch() {
548 return mInfo.displayCutout != null && getVisibility() == VISIBLE;
549 }
550
551 @Override
552 public Region getInterceptRegion() {
553 if (mInfo.displayCutout == null) {
554 return null;
555 }
556
557 return mInfo.displayCutout.getBounds();
558 }
Adrian Roos5b518852018-01-23 17:23:38 +0100559 }
560}