Merge "Remove legacy calls to StatusBarWindowView for layouts" into sc-v2-dev

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

View File

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

View File

@@ -393,11 +393,11 @@ class PrivacyDotViewController @Inject constructor(
animationScheduler.addCallback(systemStatusAnimationCallback) animationScheduler.addCallback(systemStatusAnimationCallback)
} }
val left = contentInsetsProvider.getStatusBarContentInsetsForRotation(ROTATION_SEASCAPE) val left = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_SEASCAPE)
val top = contentInsetsProvider.getStatusBarContentInsetsForRotation(ROTATION_NONE) val top = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_NONE)
val right = contentInsetsProvider.getStatusBarContentInsetsForRotation(ROTATION_LANDSCAPE) val right = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_LANDSCAPE)
val bottom = contentInsetsProvider val bottom = contentInsetsProvider
.getStatusBarContentInsetsForRotation(ROTATION_UPSIDE_DOWN) .getStatusBarContentAreaForRotation(ROTATION_UPSIDE_DOWN)
val paddingTop = contentInsetsProvider.getStatusBarPaddingTop() val paddingTop = contentInsetsProvider.getStatusBarPaddingTop()
synchronized(lock) { synchronized(lock) {
@@ -528,11 +528,11 @@ class PrivacyDotViewController @Inject constructor(
// Returns [left, top, right, bottom] aka [seascape, none, landscape, upside-down] // Returns [left, top, right, bottom] aka [seascape, none, landscape, upside-down]
private fun getLayoutRects(): List<Rect> { private fun getLayoutRects(): List<Rect> {
val left = contentInsetsProvider.getStatusBarContentInsetsForRotation(ROTATION_SEASCAPE) val left = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_SEASCAPE)
val top = contentInsetsProvider.getStatusBarContentInsetsForRotation(ROTATION_NONE) val top = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_NONE)
val right = contentInsetsProvider.getStatusBarContentInsetsForRotation(ROTATION_LANDSCAPE) val right = contentInsetsProvider.getStatusBarContentAreaForRotation(ROTATION_LANDSCAPE)
val bottom = contentInsetsProvider val bottom = contentInsetsProvider
.getStatusBarContentInsetsForRotation(ROTATION_UPSIDE_DOWN) .getStatusBarContentAreaForRotation(ROTATION_UPSIDE_DOWN)
return listOf(left, top, right, bottom) 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.animation.Interpolators;
import com.android.systemui.battery.BatteryMeterView; import com.android.systemui.battery.BatteryMeterView;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.statusbar.window.StatusBarWindowView;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.PrintWriter; import java.io.PrintWriter;
@@ -239,35 +238,32 @@ public class KeyguardStatusBarView extends RelativeLayout {
} }
} }
@Override /** Should only be called from {@link KeyguardStatusBarViewController}. */
public WindowInsets onApplyWindowInsets(WindowInsets insets) { WindowInsets updateWindowInsets(
WindowInsets insets,
StatusBarContentInsetsProvider insetsProvider) {
mLayoutState = LAYOUT_NONE; mLayoutState = LAYOUT_NONE;
if (updateLayoutConsideringCutout()) { if (updateLayoutConsideringCutout(insetsProvider)) {
requestLayout(); requestLayout();
} }
return super.onApplyWindowInsets(insets); return super.onApplyWindowInsets(insets);
} }
private boolean updateLayoutConsideringCutout() { private boolean updateLayoutConsideringCutout(StatusBarContentInsetsProvider insetsProvider) {
mDisplayCutout = getRootWindowInsets().getDisplayCutout(); mDisplayCutout = getRootWindowInsets().getDisplayCutout();
updateKeyguardStatusBarHeight(); updateKeyguardStatusBarHeight();
updatePadding(insetsProvider);
Pair<Integer, Integer> cornerCutoutMargins = if (mDisplayCutout == null || insetsProvider.currentRotationHasCornerCutout()) {
StatusBarWindowView.cornerCutoutMargins(mDisplayCutout, getDisplay());
updatePadding(cornerCutoutMargins);
if (mDisplayCutout == null || cornerCutoutMargins != null) {
return updateLayoutParamsNoCutout(); return updateLayoutParamsNoCutout();
} else { } else {
return updateLayoutParamsForCutout(); return updateLayoutParamsForCutout();
} }
} }
private void updatePadding(Pair<Integer, Integer> cornerCutoutMargins) { private void updatePadding(StatusBarContentInsetsProvider insetsProvider) {
final int waterfallTop = final int waterfallTop =
mDisplayCutout == null ? 0 : mDisplayCutout.getWaterfallInsets().top; mDisplayCutout == null ? 0 : mDisplayCutout.getWaterfallInsets().top;
mPadding = mPadding = insetsProvider.getStatusBarContentInsetsForCurrentRotation();
StatusBarWindowView.paddingNeededForCutoutAndRoundedCorner(
mDisplayCutout, cornerCutoutMargins, mRoundedCornerPadding);
// consider privacy dot space // consider privacy dot space
final int minLeft = (isLayoutRtl() && mIsPrivacyDotEnabled) final int minLeft = (isLayoutRtl() && mIsPrivacyDotEnabled)

View File

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

View File

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

View File

@@ -18,13 +18,14 @@ package com.android.systemui.statusbar.phone
import android.content.Context import android.content.Context
import android.content.res.Resources import android.content.res.Resources
import android.graphics.Point
import android.graphics.Rect import android.graphics.Rect
import android.util.LruCache import android.util.LruCache
import android.util.Pair import android.util.Pair
import android.view.DisplayCutout import android.view.DisplayCutout
import android.view.View.LAYOUT_DIRECTION_RTL
import android.view.WindowMetrics
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import com.android.internal.policy.SystemBarUtils import com.android.internal.policy.SystemBarUtils
import com.android.systemui.Dumpable import com.android.systemui.Dumpable
import com.android.systemui.R 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.dump.DumpManager
import com.android.systemui.statusbar.policy.CallbackController import com.android.systemui.statusbar.policy.CallbackController
import com.android.systemui.statusbar.policy.ConfigurationController 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_LANDSCAPE
import com.android.systemui.util.leak.RotationUtils.ROTATION_NONE 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_SEASCAPE
import com.android.systemui.util.leak.RotationUtils.ROTATION_UPSIDE_DOWN 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.Rotation
import com.android.systemui.util.leak.RotationUtils.getExactRotation
import com.android.systemui.util.leak.RotationUtils.getResourcesForRotation import com.android.systemui.util.leak.RotationUtils.getResourcesForRotation
import java.io.FileDescriptor import java.io.FileDescriptor
import java.io.PrintWriter import java.io.PrintWriter
import java.lang.Math.max import java.lang.Math.max
import javax.inject.Inject 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 * Calculates the maximum bounding rectangle for the privacy chip animation + ongoing privacy
* dot in the coordinates relative to the given rotation. * 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 { fun getBoundingRectForPrivacyChipForRotation(@Rotation rotation: Int): Rect {
var insets = insetsCache[getCacheKey(rotation = rotation)] var insets = insetsCache[getCacheKey(rotation = rotation)]
val rotatedResources = getResourcesForRotation(rotation, context)
if (insets == null) { 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 dotWidth = rotatedResources.getDimensionPixelSize(R.dimen.ongoing_appops_dot_diameter)
val chipWidth = rotatedResources.getDimensionPixelSize( val chipWidth = rotatedResources.getDimensionPixelSize(
R.dimen.ongoing_appops_chip_max_width) 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) return getPrivacyChipBoundingRectForInsets(insets, dotWidth, chipWidth, isRtl)
} }
/** /**
* Calculates the necessary left and right locations for the status bar contents invariant of * Calculate the distance from the left and right edges of the screen to the status bar
* the current device rotation, in the target rotation's coordinates * 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): Pair<Int, Int> {
fun getStatusBarContentInsetsForRotation( val key = getCacheKey(rotation)
@Rotation rotation: Int,
rotatedResources: Resources = getResourcesForRotation(rotation, context) val point = Point()
): Rect { context.display.getRealSize(point)
val key = getCacheKey(rotation = rotation) // Target rotation can be a different orientation than the current device rotation
return insetsCache[key] ?: getCalculatedInsetsForRotation(rotation, rotatedResources) point.orientToRotZero(getExactRotation(context))
.also { val width = point.logicalWidth(rotation)
insetsCache.put(key, it)
} 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, @Rotation targetRotation: Int,
rotatedResources: Resources rotatedResources: Resources
): Rect { ): Rect {
val dc = context.display.cutout 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 val roundedCornerPadding = rotatedResources
.getDimensionPixelSize(R.dimen.rounded_corner_content_padding) .getDimensionPixelSize(R.dimen.rounded_corner_content_padding)
val minDotPadding = if (isPrivacyDotEnabled) val minDotPadding = if (isPrivacyDotEnabled)
@@ -165,7 +238,7 @@ class StatusBarContentInsetsProvider @Inject constructor(
val minLeft: Int val minLeft: Int
val minRight: Int val minRight: Int
if (isRtl) { if (configurationController.isLayoutRtl) {
minLeft = max(minDotPadding, roundedCornerPadding) minLeft = max(minDotPadding, roundedCornerPadding)
minRight = roundedCornerPadding minRight = roundedCornerPadding
} else { } else {
@@ -181,7 +254,7 @@ class StatusBarContentInsetsProvider @Inject constructor(
SystemBarUtils.getStatusBarHeightForRotation(context, targetRotation), SystemBarUtils.getStatusBarHeightForRotation(context, targetRotation),
minLeft, minLeft,
minRight, minRight,
isRtl, configurationController.isLayoutRtl,
dotWidth) dotWidth)
} }
@@ -252,7 +325,7 @@ fun getPrivacyChipBoundingRectForInsets(
* @param currentRotation current device rotation * @param currentRotation current device rotation
* @param targetRotation rotation for which to calculate the status bar content rect * @param targetRotation rotation for which to calculate the status bar content rect
* @param displayCutout [DisplayCutout] for the current display. possibly null * @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 statusBarHeight height of the status bar for the target rotation
* @param minLeft the minimum padding to enforce on the left * @param minLeft the minimum padding to enforce on the left
* @param minRight the minimum padding to enforce on the right * @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 { private fun Int.isHorizontal(): Boolean {
return this == ROTATION_LANDSCAPE || this == ROTATION_SEASCAPE 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.MotionEvent.ACTION_UP;
import static android.view.WindowInsets.Type.systemBars; import static android.view.WindowInsets.Type.systemBars;
import static com.android.systemui.ScreenDecorations.DisplayCutoutView.boundsFromDirection;
import android.content.Context; import android.content.Context;
import android.graphics.Insets; import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Pair;
import android.view.Display;
import android.view.DisplayCutout; import android.view.DisplayCutout;
import android.view.Gravity;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.WindowInsets; import android.view.WindowInsets;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import com.android.systemui.util.leak.RotationUtils;
/** /**
* Status bar view. * 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.privacy.logging.PrivacyLogger
import com.android.systemui.qs.carrier.QSCarrierGroup import com.android.systemui.qs.carrier.QSCarrierGroup
import com.android.systemui.qs.carrier.QSCarrierGroupController 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.StatusBarIconController
import com.android.systemui.statusbar.phone.StatusIconContainer import com.android.systemui.statusbar.phone.StatusIconContainer
import com.android.systemui.statusbar.policy.Clock import com.android.systemui.statusbar.policy.Clock
@@ -106,6 +107,8 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() {
private lateinit var context: Context private lateinit var context: Context
@Mock @Mock
private lateinit var featureFlags: FeatureFlags private lateinit var featureFlags: FeatureFlags
@Mock
private lateinit var insetsProvider: StatusBarContentInsetsProvider
private val qsExpansionPathInterpolator = QSExpansionPathInterpolator() private val qsExpansionPathInterpolator = QSExpansionPathInterpolator()
@@ -149,7 +152,8 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() {
qsExpansionPathInterpolator, qsExpansionPathInterpolator,
batteryMeterViewController, batteryMeterViewController,
featureFlags, featureFlags,
variableDateViewControllerFactory variableDateViewControllerFactory,
insetsProvider
) )
} }
@@ -248,7 +252,7 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() {
controller.init() controller.init()
val captor = argumentCaptor<List<String>>() 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( assertThat(captor.value).containsExactly(
mContext.getString(com.android.internal.R.string.status_bar_mobile) mContext.getString(com.android.internal.R.string.status_bar_mobile)
@@ -261,7 +265,7 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() {
controller.init() controller.init()
val captor = argumentCaptor<List<String>>() 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( assertThat(captor.value).containsExactly(
mContext.getString(com.android.internal.R.string.status_bar_no_calling), 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; private BiometricUnlockController mBiometricUnlockController;
@Mock @Mock
private SysuiStatusBarStateController mStatusBarStateController; private SysuiStatusBarStateController mStatusBarStateController;
@Mock
private StatusBarContentInsetsProvider mStatusBarContentInsetsProvider;
private TestNotificationPanelViewStateProvider mNotificationPanelViewStateProvider; private TestNotificationPanelViewStateProvider mNotificationPanelViewStateProvider;
private KeyguardStatusBarView mKeyguardStatusBarView; private KeyguardStatusBarView mKeyguardStatusBarView;
@@ -118,7 +120,8 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
mKeyguardBypassController, mKeyguardBypassController,
mKeyguardUpdateMonitor, mKeyguardUpdateMonitor,
mBiometricUnlockController, mBiometricUnlockController,
mStatusBarStateController mStatusBarStateController,
mStatusBarContentInsetsProvider
); );
} }

View File

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