blob: c6f79831e022d472af4261217b67d0c0367162ce [file] [log] [blame]
/*
* Copyright (C) 2019 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.statusbar.phone;
import static android.view.WindowInsets.Type.systemBars;
import static com.android.systemui.ScreenDecorations.DisplayCutoutView.boundsFromDirection;
import android.content.Context;
import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Pair;
import android.view.Display;
import android.view.DisplayCutout;
import android.view.Gravity;
import android.view.View;
import android.view.WindowInsets;
import android.widget.FrameLayout;
import com.android.systemui.util.leak.RotationUtils;
/**
* Status bar view.
*/
public class StatusBarWindowView extends FrameLayout {
public static final String TAG = "PhoneStatusBarWindowView";
public static final boolean DEBUG = StatusBar.DEBUG;
private int mLeftInset = 0;
private int mRightInset = 0;
private int mTopInset = 0;
public StatusBarWindowView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public WindowInsets onApplyWindowInsets(WindowInsets windowInsets) {
final Insets insets = windowInsets.getInsetsIgnoringVisibility(systemBars());
mLeftInset = insets.left;
mRightInset = insets.right;
mTopInset = 0;
DisplayCutout displayCutout = getRootWindowInsets().getDisplayCutout();
if (displayCutout != null) {
mTopInset = displayCutout.getWaterfallInsets().top;
}
applyMargins();
return windowInsets;
}
private void applyMargins() {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child.getLayoutParams() instanceof LayoutParams) {
LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (lp.rightMargin != mRightInset || lp.leftMargin != mLeftInset
|| lp.topMargin != mTopInset) {
lp.rightMargin = mRightInset;
lp.leftMargin = mLeftInset;
lp.topMargin = mTopInset;
child.requestLayout();
}
}
}
}
/**
* Compute the padding needed for status bar related views, e.g., PhoneStatusBar,
* QuickStatusBarHeader and KeyguardStatusBarView).
*
* @param cutout
* @param cornerCutoutPadding
* @param roundedCornerContentPadding
* @return
*/
public static Pair<Integer, Integer> paddingNeededForCutoutAndRoundedCorner(
DisplayCutout cutout, Pair<Integer, Integer> cornerCutoutPadding,
int roundedCornerContentPadding) {
if (cutout == null) {
return new Pair<>(roundedCornerContentPadding, roundedCornerContentPadding);
}
// padding needed for corner cutout.
int leftCornerCutoutPadding = cutout.getSafeInsetLeft();
int rightCornerCutoutPadding = cutout.getSafeInsetRight();
if (cornerCutoutPadding != null) {
leftCornerCutoutPadding = Math.max(leftCornerCutoutPadding, cornerCutoutPadding.first);
rightCornerCutoutPadding = Math.max(rightCornerCutoutPadding,
cornerCutoutPadding.second);
}
return new Pair<>(
Math.max(leftCornerCutoutPadding, roundedCornerContentPadding),
Math.max(rightCornerCutoutPadding, roundedCornerContentPadding));
}
/**
* Compute the corner cutout margins in portrait mode
*/
public static Pair<Integer, Integer> cornerCutoutMargins(DisplayCutout cutout,
Display display) {
return statusBarCornerCutoutMargins(cutout, display, RotationUtils.ROTATION_NONE, 0);
}
/**
* Compute the corner cutout margins in the given orientation (exactRotation)
*/
public static Pair<Integer, Integer> statusBarCornerCutoutMargins(DisplayCutout cutout,
Display display, int exactRotation, int statusBarHeight) {
if (cutout == null) {
return null;
}
Point size = new Point();
display.getRealSize(size);
Rect bounds = new Rect();
switch (exactRotation) {
case RotationUtils.ROTATION_LANDSCAPE:
boundsFromDirection(cutout, Gravity.LEFT, bounds);
break;
case RotationUtils.ROTATION_SEASCAPE:
boundsFromDirection(cutout, Gravity.RIGHT, bounds);
break;
case RotationUtils.ROTATION_NONE:
boundsFromDirection(cutout, Gravity.TOP, bounds);
break;
case RotationUtils.ROTATION_UPSIDE_DOWN:
// we assume the cutout is always on top in portrait mode
return null;
}
if (statusBarHeight >= 0 && bounds.top > statusBarHeight) {
return null;
}
if (bounds.left <= 0) {
return new Pair<>(bounds.right, 0);
}
if (bounds.right >= size.x) {
return new Pair<>(0, size.x - bounds.left);
}
return null;
}
}