Remove legacy calls to StatusBarWindowView for layouts

QuickStatusBarHeader, KeyguardStatusBarView, and PhoneStatusBarView all
had a few calls to some methods in StatusBarWindowView that would try to
calculate the insets necessary draw content in the status bar area that
avoids cutouts. This CL removes those methods and moves that
functionality into StatusBarContentInsetsProvider so that everything can
benefit from the caching it provides and hopefully this simplifies
things.

Test: atest SystemUITests; manual
Bug: 203223072
Change-Id: I6235394a3c71a360b5cc1fb9f511a52aef8c8f17
Merged-In: I6235394a3c71a360b5cc1fb9f511a52aef8c8f17
This commit is contained in:
Evan Laird
2021-10-14 17:41:39 -04:00
parent aaf2ae3c4c
commit 95132a00c4
11 changed files with 188 additions and 181 deletions

View File

@@ -39,11 +39,11 @@ import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.battery.BatteryMeterView;
import com.android.systemui.qs.QSDetail.Callback;
import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider;
import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
import com.android.systemui.statusbar.phone.StatusIconContainer;
import com.android.systemui.statusbar.policy.Clock;
import com.android.systemui.statusbar.policy.VariableDateView;
import com.android.systemui.statusbar.window.StatusBarWindowView;
import java.util.List;
@@ -86,6 +86,7 @@ public class QuickStatusBarHeader extends FrameLayout {
private TintedIconManager mTintedIconManager;
private QSExpansionPathInterpolator mQSExpansionPathInterpolator;
private StatusBarContentInsetsProvider mInsetsProvider;
private int mRoundedCornerPadding = 0;
private int mWaterfallTopInset;
@@ -161,10 +162,12 @@ public class QuickStatusBarHeader extends FrameLayout {
void onAttach(TintedIconManager iconManager,
QSExpansionPathInterpolator qsExpansionPathInterpolator,
List<String> rssiIgnoredSlots,
boolean useCombinedQSHeader) {
boolean useCombinedQSHeader,
StatusBarContentInsetsProvider insetsProvider) {
mUseCombinedQSHeader = useCombinedQSHeader;
mTintedIconManager = iconManager;
mRssiIgnoredSlots = rssiIgnoredSlots;
mInsetsProvider = insetsProvider;
int fillColor = Utils.getColorAttrDefaultColor(getContext(),
android.R.attr.textColorPrimary);
@@ -436,22 +439,20 @@ public class QuickStatusBarHeader extends FrameLayout {
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
// Handle padding of the views
DisplayCutout cutout = insets.getDisplayCutout();
Pair<Integer, Integer> cornerCutoutPadding = StatusBarWindowView.cornerCutoutMargins(
cutout, getDisplay());
Pair<Integer, Integer> padding =
StatusBarWindowView.paddingNeededForCutoutAndRoundedCorner(
cutout, cornerCutoutPadding, -1);
mDatePrivacyView.setPadding(padding.first, 0, padding.second, 0);
mStatusIconsView.setPadding(padding.first, 0, padding.second, 0);
Pair<Integer, Integer> sbInsets = mInsetsProvider
.getStatusBarContentInsetsForCurrentRotation();
boolean hasCornerCutout = mInsetsProvider.currentRotationHasCornerCutout();
mDatePrivacyView.setPadding(sbInsets.first, 0, sbInsets.second, 0);
mStatusIconsView.setPadding(sbInsets.first, 0, sbInsets.second, 0);
LinearLayout.LayoutParams datePrivacySeparatorLayoutParams =
(LinearLayout.LayoutParams) mDatePrivacySeparator.getLayoutParams();
LinearLayout.LayoutParams mClockIconsSeparatorLayoutParams =
(LinearLayout.LayoutParams) mClockIconsSeparator.getLayoutParams();
boolean cornerCutout = cornerCutoutPadding != null
&& (cornerCutoutPadding.first == 0 || cornerCutoutPadding.second == 0);
if (cutout != null) {
Rect topCutout = cutout.getBoundingRectTop();
if (topCutout.isEmpty() || cornerCutout) {
if (topCutout.isEmpty() || hasCornerCutout) {
datePrivacySeparatorLayoutParams.width = 0;
mDatePrivacySeparator.setVisibility(View.GONE);
mClockIconsSeparatorLayoutParams.width = 0;
@@ -469,8 +470,8 @@ public class QuickStatusBarHeader extends FrameLayout {
}
mDatePrivacySeparator.setLayoutParams(datePrivacySeparatorLayoutParams);
mClockIconsSeparator.setLayoutParams(mClockIconsSeparatorLayoutParams);
mCutOutPaddingLeft = padding.first;
mCutOutPaddingRight = padding.second;
mCutOutPaddingLeft = sbInsets.first;
mCutOutPaddingRight = sbInsets.second;
mWaterfallTopInset = cutout == null ? 0 : cutout.getWaterfallInsets().top;
updateBatteryMode();

View File

@@ -39,6 +39,7 @@ import com.android.systemui.privacy.PrivacyItemController;
import com.android.systemui.privacy.logging.PrivacyLogger;
import com.android.systemui.qs.carrier.QSCarrierGroupController;
import com.android.systemui.qs.dagger.QSScope;
import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusIconContainer;
import com.android.systemui.statusbar.policy.Clock;
@@ -73,6 +74,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
private final QSExpansionPathInterpolator mQSExpansionPathInterpolator;
private final BatteryMeterViewController mBatteryMeterViewController;
private final FeatureFlags mFeatureFlags;
private final StatusBarContentInsetsProvider mInsetsProvider;
private final VariableDateViewController mVariableDateViewControllerDateView;
private final VariableDateViewController mVariableDateViewControllerClockDateView;
@@ -142,7 +144,8 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
QSExpansionPathInterpolator qsExpansionPathInterpolator,
BatteryMeterViewController batteryMeterViewController,
FeatureFlags featureFlags,
VariableDateViewController.Factory variableDateViewControllerFactory) {
VariableDateViewController.Factory variableDateViewControllerFactory,
StatusBarContentInsetsProvider statusBarContentInsetsProvider) {
super(view);
mPrivacyItemController = privacyItemController;
mActivityStarter = activityStarter;
@@ -155,6 +158,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
mQSExpansionPathInterpolator = qsExpansionPathInterpolator;
mBatteryMeterViewController = batteryMeterViewController;
mFeatureFlags = featureFlags;
mInsetsProvider = statusBarContentInsetsProvider;
mQSCarrierGroupController = qsCarrierGroupControllerBuilder
.setQSCarrierGroup(mView.findViewById(R.id.carrier_group))
@@ -226,7 +230,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
}
mView.onAttach(mIconManager, mQSExpansionPathInterpolator, rssiIgnoredSlots,
mFeatureFlags.useCombinedQSHeaders());
mFeatureFlags.useCombinedQSHeaders(), mInsetsProvider);
mDemoModeController.addCallback(mDemoModeReceiver);

View File

@@ -393,11 +393,11 @@ class PrivacyDotViewController @Inject constructor(
animationScheduler.addCallback(systemStatusAnimationCallback)
}
val left = contentInsetsProvider.getStatusBarContentInsetsForRotation(ROTATION_SEASCAPE)
val top = contentInsetsProvider.getStatusBarContentInsetsForRotation(ROTATION_NONE)
val right = contentInsetsProvider.getStatusBarContentInsetsForRotation(ROTATION_LANDSCAPE)
val left = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_SEASCAPE)
val top = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_NONE)
val right = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_LANDSCAPE)
val bottom = contentInsetsProvider
.getStatusBarContentInsetsForRotation(ROTATION_UPSIDE_DOWN)
.getStatusBarContentAreaForRotation(ROTATION_UPSIDE_DOWN)
val paddingTop = contentInsetsProvider.getStatusBarPaddingTop()
synchronized(lock) {
@@ -528,11 +528,11 @@ class PrivacyDotViewController @Inject constructor(
// Returns [left, top, right, bottom] aka [seascape, none, landscape, upside-down]
private fun getLayoutRects(): List<Rect> {
val left = contentInsetsProvider.getStatusBarContentInsetsForRotation(ROTATION_SEASCAPE)
val top = contentInsetsProvider.getStatusBarContentInsetsForRotation(ROTATION_NONE)
val right = contentInsetsProvider.getStatusBarContentInsetsForRotation(ROTATION_LANDSCAPE)
val left = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_SEASCAPE)
val top = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_NONE)
val right = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_LANDSCAPE)
val bottom = contentInsetsProvider
.getStatusBarContentInsetsForRotation(ROTATION_UPSIDE_DOWN)
.getStatusBarContentAreaForRotation(ROTATION_UPSIDE_DOWN)
return listOf(left, top, right, bottom)
}

View File

@@ -47,7 +47,6 @@ import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.battery.BatteryMeterView;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.statusbar.window.StatusBarWindowView;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -239,35 +238,32 @@ public class KeyguardStatusBarView extends RelativeLayout {
}
}
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
/** Should only be called from {@link KeyguardStatusBarViewController}. */
WindowInsets updateWindowInsets(
WindowInsets insets,
StatusBarContentInsetsProvider insetsProvider) {
mLayoutState = LAYOUT_NONE;
if (updateLayoutConsideringCutout()) {
if (updateLayoutConsideringCutout(insetsProvider)) {
requestLayout();
}
return super.onApplyWindowInsets(insets);
}
private boolean updateLayoutConsideringCutout() {
private boolean updateLayoutConsideringCutout(StatusBarContentInsetsProvider insetsProvider) {
mDisplayCutout = getRootWindowInsets().getDisplayCutout();
updateKeyguardStatusBarHeight();
Pair<Integer, Integer> cornerCutoutMargins =
StatusBarWindowView.cornerCutoutMargins(mDisplayCutout, getDisplay());
updatePadding(cornerCutoutMargins);
if (mDisplayCutout == null || cornerCutoutMargins != null) {
updatePadding(insetsProvider);
if (mDisplayCutout == null || insetsProvider.currentRotationHasCornerCutout()) {
return updateLayoutParamsNoCutout();
} else {
return updateLayoutParamsForCutout();
}
}
private void updatePadding(Pair<Integer, Integer> cornerCutoutMargins) {
private void updatePadding(StatusBarContentInsetsProvider insetsProvider) {
final int waterfallTop =
mDisplayCutout == null ? 0 : mDisplayCutout.getWaterfallInsets().top;
mPadding =
StatusBarWindowView.paddingNeededForCutoutAndRoundedCorner(
mDisplayCutout, cornerCutoutMargins, mRoundedCornerPadding);
mPadding = insetsProvider.getStatusBarContentInsetsForCurrentRotation();
// consider privacy dot space
final int minLeft = (isLayoutRtl() && mIsPrivacyDotEnabled)

View File

@@ -91,6 +91,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final BiometricUnlockController mBiometricUnlockController;
private final SysuiStatusBarStateController mStatusBarStateController;
private final StatusBarContentInsetsProvider mInsetsProvider;
private final ConfigurationController.ConfigurationListener mConfigurationListener =
new ConfigurationController.ConfigurationListener() {
@@ -228,7 +229,9 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
KeyguardBypassController bypassController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
BiometricUnlockController biometricUnlockController,
SysuiStatusBarStateController statusBarStateController) {
SysuiStatusBarStateController statusBarStateController,
StatusBarContentInsetsProvider statusBarContentInsetsProvider
) {
super(view);
mCarrierTextController = carrierTextController;
mConfigurationController = configurationController;
@@ -244,6 +247,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mBiometricUnlockController = biometricUnlockController;
mStatusBarStateController = statusBarStateController;
mInsetsProvider = statusBarContentInsetsProvider;
mFirstBypassAttempt = mKeyguardBypassController.getBypassEnabled();
mKeyguardStateController.addCallback(
@@ -287,6 +291,9 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
mTintedIconManager.setBlockList(mBlockedIcons);
mStatusBarIconController.addIconGroup(mTintedIconManager);
}
mView.setOnApplyWindowInsetsListener(
(view, windowInsets) -> mView.updateWindowInsets(windowInsets, mInsetsProvider));
onThemeChanged();
}

View File

@@ -16,18 +16,15 @@
package com.android.systemui.statusbar.phone;
import static com.android.systemui.ScreenDecorations.DisplayCutoutView.boundsFromDirection;
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
import android.view.DisplayCutout;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@@ -41,7 +38,6 @@ import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.statusbar.window.StatusBarWindowView;
import com.android.systemui.util.leak.RotationUtils;
import java.util.Objects;
@@ -219,17 +215,18 @@ public class PhoneStatusBarView extends FrameLayout {
private void updateLayoutForCutout() {
updateStatusBarHeight();
updateCutoutLocation(StatusBarWindowView.cornerCutoutMargins(mDisplayCutout, getDisplay()));
updateCutoutLocation();
updateSafeInsets();
}
private void updateCutoutLocation(Pair<Integer, Integer> cornerCutoutMargins) {
private void updateCutoutLocation() {
// Not all layouts have a cutout (e.g., Car)
if (mCutoutSpace == null) {
return;
}
if (mDisplayCutout == null || mDisplayCutout.isEmpty() || cornerCutoutMargins != null) {
boolean hasCornerCutout = mContentInsetsProvider.currentRotationHasCornerCutout();
if (mDisplayCutout == null || mDisplayCutout.isEmpty() || hasCornerCutout) {
mCenterIconSpace.setVisibility(View.VISIBLE);
mCutoutSpace.setVisibility(View.GONE);
return;
@@ -239,8 +236,7 @@ public class PhoneStatusBarView extends FrameLayout {
mCutoutSpace.setVisibility(View.VISIBLE);
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mCutoutSpace.getLayoutParams();
Rect bounds = new Rect();
boundsFromDirection(mDisplayCutout, Gravity.TOP, bounds);
Rect bounds = mDisplayCutout.getBoundingRectTop();
bounds.left = bounds.left + mCutoutSideNudge;
bounds.right = bounds.right - mCutoutSideNudge;
@@ -249,16 +245,13 @@ public class PhoneStatusBarView extends FrameLayout {
}
private void updateSafeInsets() {
Rect contentRect = mContentInsetsProvider
.getStatusBarContentInsetsForRotation(RotationUtils.getExactRotation(getContext()));
Point size = new Point();
getDisplay().getRealSize(size);
Pair<Integer, Integer> insets = mContentInsetsProvider
.getStatusBarContentInsetsForCurrentRotation();
setPadding(
contentRect.left,
insets.first,
getPaddingTop(),
size.x - contentRect.right,
insets.second,
getPaddingBottom());
}

View File

@@ -18,13 +18,14 @@ package com.android.systemui.statusbar.phone
import android.content.Context
import android.content.res.Resources
import android.graphics.Point
import android.graphics.Rect
import android.util.LruCache
import android.util.Pair
import android.view.DisplayCutout
import android.view.View.LAYOUT_DIRECTION_RTL
import android.view.WindowMetrics
import androidx.annotation.VisibleForTesting
import com.android.internal.policy.SystemBarUtils
import com.android.systemui.Dumpable
import com.android.systemui.R
@@ -32,16 +33,18 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.policy.CallbackController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.leak.RotationUtils
import com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE
import com.android.systemui.util.leak.RotationUtils.ROTATION_NONE
import com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE
import com.android.systemui.util.leak.RotationUtils.ROTATION_UPSIDE_DOWN
import com.android.systemui.util.leak.RotationUtils.Rotation
import com.android.systemui.util.leak.RotationUtils.getExactRotation
import com.android.systemui.util.leak.RotationUtils.getResourcesForRotation
import java.io.FileDescriptor
import java.io.PrintWriter
import java.lang.Math.max
import javax.inject.Inject
/**
@@ -111,49 +114,119 @@ class StatusBarContentInsetsProvider @Inject constructor(
}
}
/**
* Some views may need to care about whether or not the current top display cutout is located
* in the corner rather than somewhere in the center. In the case of a corner cutout, the
* status bar area is contiguous.
*/
fun currentRotationHasCornerCutout(): Boolean {
val cutout = context.display.cutout ?: return false
val topBounds = cutout.boundingRectTop
val point = Point()
context.display.getRealSize(point)
return topBounds.left <= 0 || topBounds.right >= point.y
}
/**
* Calculates the maximum bounding rectangle for the privacy chip animation + ongoing privacy
* dot in the coordinates relative to the given rotation.
*
* @param rotation the rotation for which the bounds are required. This is an absolute value
* (i.e., ROTATION_NONE will always return the same bounds regardless of the context
* from which this method is called)
*/
fun getBoundingRectForPrivacyChipForRotation(@Rotation rotation: Int): Rect {
var insets = insetsCache[getCacheKey(rotation = rotation)]
val rotatedResources = getResourcesForRotation(rotation, context)
if (insets == null) {
insets = getStatusBarContentInsetsForRotation(rotation, rotatedResources)
insets = getStatusBarContentAreaForRotation(rotation)
}
val rotatedResources = getResourcesForRotation(rotation, context)
val dotWidth = rotatedResources.getDimensionPixelSize(R.dimen.ongoing_appops_dot_diameter)
val chipWidth = rotatedResources.getDimensionPixelSize(
R.dimen.ongoing_appops_chip_max_width)
val isRtl = context.resources.configuration.layoutDirection == LAYOUT_DIRECTION_RTL
val isRtl = configurationController.isLayoutRtl
return getPrivacyChipBoundingRectForInsets(insets, dotWidth, chipWidth, isRtl)
}
/**
* Calculates the necessary left and right locations for the status bar contents invariant of
* the current device rotation, in the target rotation's coordinates
* Calculate the distance from the left and right edges of the screen to the status bar
* content area. This differs from the content area rects in that these values can be used
* directly as padding.
*
* @param rotation the target rotation for which to calculate insets
*/
@JvmOverloads
fun getStatusBarContentInsetsForRotation(
@Rotation rotation: Int,
rotatedResources: Resources = getResourcesForRotation(rotation, context)
): Rect {
val key = getCacheKey(rotation = rotation)
return insetsCache[key] ?: getCalculatedInsetsForRotation(rotation, rotatedResources)
.also {
insetsCache.put(key, it)
}
fun getStatusBarContentInsetsForRotation(@Rotation rotation: Int): Pair<Int, Int> {
val key = getCacheKey(rotation)
val point = Point()
context.display.getRealSize(point)
// Target rotation can be a different orientation than the current device rotation
point.orientToRotZero(getExactRotation(context))
val width = point.logicalWidth(rotation)
val area = insetsCache[key] ?: getAndSetCalculatedAreaForRotation(
rotation, getResourcesForRotation(rotation, context), key)
return Pair(area.left, width - area.right)
}
private fun getCalculatedInsetsForRotation(
/**
* Calculate the left and right insets for the status bar content in the device's current
* rotation
* @see getStatusBarContentAreaForRotation
*/
fun getStatusBarContentInsetsForCurrentRotation(): Pair<Int, Int> {
return getStatusBarContentInsetsForRotation(getExactRotation(context))
}
/**
* Calculates the area of the status bar contents invariant of the current device rotation,
* in the target rotation's coordinates
*
* @param rotation the rotation for which the bounds are required. This is an absolute value
* (i.e., ROTATION_NONE will always return the same bounds regardless of the context
* from which this method is called)
*/
@JvmOverloads
fun getStatusBarContentAreaForRotation(
@Rotation rotation: Int
): Rect {
val key = getCacheKey(rotation)
return insetsCache[key] ?: getAndSetCalculatedAreaForRotation(
rotation, getResourcesForRotation(rotation, context), key)
}
/**
* Get the status bar content area for the given rotation, in absolute bounds
*/
fun getStatusBarContentAreaForCurrentRotation(): Rect {
val rotation = getExactRotation(context)
return getStatusBarContentAreaForRotation(rotation)
}
private fun getAndSetCalculatedAreaForRotation(
@Rotation targetRotation: Int,
rotatedResources: Resources,
key: CacheKey
): Rect {
return getCalculatedAreaForRotation(targetRotation, rotatedResources)
.also {
insetsCache.put(key, it)
}
}
private fun getCalculatedAreaForRotation(
@Rotation targetRotation: Int,
rotatedResources: Resources
): Rect {
val dc = context.display.cutout
val currentRotation = RotationUtils.getExactRotation(context)
val currentRotation = getExactRotation(context)
val isRtl = rotatedResources.configuration.layoutDirection == LAYOUT_DIRECTION_RTL
val roundedCornerPadding = rotatedResources
.getDimensionPixelSize(R.dimen.rounded_corner_content_padding)
val minDotPadding = if (isPrivacyDotEnabled)
@@ -165,7 +238,7 @@ class StatusBarContentInsetsProvider @Inject constructor(
val minLeft: Int
val minRight: Int
if (isRtl) {
if (configurationController.isLayoutRtl) {
minLeft = max(minDotPadding, roundedCornerPadding)
minRight = roundedCornerPadding
} else {
@@ -181,7 +254,7 @@ class StatusBarContentInsetsProvider @Inject constructor(
SystemBarUtils.getStatusBarHeightForRotation(context, targetRotation),
minLeft,
minRight,
isRtl,
configurationController.isLayoutRtl,
dotWidth)
}
@@ -252,7 +325,7 @@ fun getPrivacyChipBoundingRectForInsets(
* @param currentRotation current device rotation
* @param targetRotation rotation for which to calculate the status bar content rect
* @param displayCutout [DisplayCutout] for the current display. possibly null
* @param windowMetrics [WindowMetrics] for the current window
* @param maxBounds the display bounds in our current rotation
* @param statusBarHeight height of the status bar for the target rotation
* @param minLeft the minimum padding to enforce on the left
* @param minRight the minimum padding to enforce on the right
@@ -464,3 +537,22 @@ private fun Rect.logicalWidth(@Rotation rot: Int): Int {
private fun Int.isHorizontal(): Boolean {
return this == ROTATION_LANDSCAPE || this == ROTATION_SEASCAPE
}
private fun Point.orientToRotZero(@Rotation rot: Int) {
when (rot) {
ROTATION_NONE, ROTATION_UPSIDE_DOWN -> return
else -> {
// swap width and height to zero-orient bounds
val yTmp = y
y = x
x = yTmp
}
}
}
private fun Point.logicalWidth(@Rotation rot: Int): Int {
return when (rot) {
ROTATION_NONE, ROTATION_UPSIDE_DOWN -> x
else -> y
}
}

View File

@@ -21,26 +21,15 @@ import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_UP;
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.MotionEvent;
import android.view.View;
import android.view.WindowInsets;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import com.android.systemui.util.leak.RotationUtils;
/**
* Status bar view.
*/
@@ -111,86 +100,4 @@ public class StatusBarWindowView extends FrameLayout {
}
}
}
/**
* Compute the padding needed for status bar related views, e.g., PhoneStatusBar,
* QuickStatusBarHeader and KeyguardStatusBarView).
*
* @param cutout
* @param cornerCutoutPadding
* @param roundedCornerContentPadding
* @return
*/
@NonNull
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;
}
}

View File

@@ -34,6 +34,7 @@ import com.android.systemui.privacy.PrivacyItemController
import com.android.systemui.privacy.logging.PrivacyLogger
import com.android.systemui.qs.carrier.QSCarrierGroup
import com.android.systemui.qs.carrier.QSCarrierGroupController
import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
import com.android.systemui.statusbar.phone.StatusBarIconController
import com.android.systemui.statusbar.phone.StatusIconContainer
import com.android.systemui.statusbar.policy.Clock
@@ -106,6 +107,8 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() {
private lateinit var context: Context
@Mock
private lateinit var featureFlags: FeatureFlags
@Mock
private lateinit var insetsProvider: StatusBarContentInsetsProvider
private val qsExpansionPathInterpolator = QSExpansionPathInterpolator()
@@ -149,7 +152,8 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() {
qsExpansionPathInterpolator,
batteryMeterViewController,
featureFlags,
variableDateViewControllerFactory
variableDateViewControllerFactory,
insetsProvider
)
}
@@ -248,7 +252,7 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() {
controller.init()
val captor = argumentCaptor<List<String>>()
verify(view).onAttach(any(), any(), capture(captor), anyBoolean())
verify(view).onAttach(any(), any(), capture(captor), anyBoolean(), any())
assertThat(captor.value).containsExactly(
mContext.getString(com.android.internal.R.string.status_bar_mobile)
@@ -261,7 +265,7 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() {
controller.init()
val captor = argumentCaptor<List<String>>()
verify(view).onAttach(any(), any(), capture(captor), anyBoolean())
verify(view).onAttach(any(), any(), capture(captor), anyBoolean(), any())
assertThat(captor.value).containsExactly(
mContext.getString(com.android.internal.R.string.status_bar_no_calling),

View File

@@ -85,6 +85,8 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
private BiometricUnlockController mBiometricUnlockController;
@Mock
private SysuiStatusBarStateController mStatusBarStateController;
@Mock
private StatusBarContentInsetsProvider mStatusBarContentInsetsProvider;
private TestNotificationPanelViewStateProvider mNotificationPanelViewStateProvider;
private KeyguardStatusBarView mKeyguardStatusBarView;
@@ -118,7 +120,8 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
mKeyguardBypassController,
mKeyguardUpdateMonitor,
mBiometricUnlockController,
mStatusBarStateController
mStatusBarStateController,
mStatusBarContentInsetsProvider
);
}

View File

@@ -467,7 +467,7 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
screenBounds = Rect(0, 0, 1080, 2160),
displayUniqueId = "1"
)
val firstDisplayInsets = provider.getStatusBarContentInsetsForRotation(ROTATION_NONE)
val firstDisplayInsets = provider.getStatusBarContentAreaForRotation(ROTATION_NONE)
givenDisplay(
screenBounds = Rect(0, 0, 800, 600),
displayUniqueId = "2"
@@ -475,7 +475,7 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
configurationController.onConfigurationChanged(configuration)
// WHEN: get insets on the second display
val secondDisplayInsets = provider.getStatusBarContentInsetsForRotation(ROTATION_NONE)
val secondDisplayInsets = provider.getStatusBarContentAreaForRotation(ROTATION_NONE)
// THEN: insets are updated
assertThat(firstDisplayInsets).isNotEqualTo(secondDisplayInsets)
@@ -492,13 +492,13 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
displayUniqueId = "1"
)
val firstDisplayInsetsFirstCall = provider
.getStatusBarContentInsetsForRotation(ROTATION_NONE)
.getStatusBarContentAreaForRotation(ROTATION_NONE)
givenDisplay(
screenBounds = Rect(0, 0, 800, 600),
displayUniqueId = "2"
)
configurationController.onConfigurationChanged(configuration)
provider.getStatusBarContentInsetsForRotation(ROTATION_NONE)
provider.getStatusBarContentAreaForRotation(ROTATION_NONE)
givenDisplay(
screenBounds = Rect(0, 0, 1080, 2160),
displayUniqueId = "1"
@@ -507,7 +507,7 @@ class StatusBarContentInsetsProviderTest : SysuiTestCase() {
// WHEN: get insets on the first display again
val firstDisplayInsetsSecondCall = provider
.getStatusBarContentInsetsForRotation(ROTATION_NONE)
.getStatusBarContentAreaForRotation(ROTATION_NONE)
// THEN: insets for the first and second calls for the first display are the same
assertThat(firstDisplayInsetsFirstCall).isEqualTo(firstDisplayInsetsSecondCall)