Merge "Remove legacy calls to StatusBarWindowView for layouts" into sc-v2-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
4948c6a116
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user