From 24b99ef4e71aebbc037d1bc944f80c5585353218 Mon Sep 17 00:00:00 2001 From: Evan Laird Date: Wed, 9 Jun 2021 17:05:11 -0400 Subject: [PATCH] Hook up the sysui backend for status bar content rects StatusBarContentInsetsProvider provides the sysui backend for the windowmanager api to communicate the location of the privacy indicators to apps. This CL hooks up that backend to the dot view controller and the PhoneStatusBarView, which provides us with a stronger guarantee that things are working and codifies the places where status bar content layout can be changed. Also in this CL is a better dot positioning algorithm that will ensure there is no flickering when the dot needs to rotate. Test: manual Bug 187973222 Change-Id: I3dba7719ac4c4d178c9ec5265865961dbd0450f9 --- .../src/com/android/systemui/Dependency.java | 3 + .../events/PrivacyDotViewController.kt | 233 ++++++++++++++---- .../phone/CollapsedStatusBarFragment.java | 39 +-- .../phone/ConfigurationControllerImpl.kt | 14 ++ .../statusbar/phone/PhoneStatusBarView.java | 27 +- .../systemui/statusbar/phone/StatusBar.java | 11 +- .../phone/dagger/StatusBarPhoneModule.java | 3 + .../policy/ConfigurationController.java | 4 + .../phone/CollapsedStatusBarFragmentTest.java | 30 ++- .../statusbar/phone/StatusBarTest.java | 2 + .../leaks/FakeConfigurationController.java | 5 + 11 files changed, 287 insertions(+), 84 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index 45f8d826ea334..7ebcfb073e512 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -99,6 +99,7 @@ import com.android.systemui.statusbar.phone.LockscreenGestureLogger; import com.android.systemui.statusbar.phone.ManagedProfileController; import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper; import com.android.systemui.statusbar.phone.ShadeController; +import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.phone.StatusBarWindowController; import com.android.systemui.statusbar.policy.AccessibilityController; @@ -371,6 +372,7 @@ public class Dependency { @Inject Lazy mPrivacyDotViewControllerLazy; @Inject Provider mEdgeBackGestureHandlerProvider; @Inject Lazy mUiEventLogger; + @Inject Lazy mContentInsetsProviderLazy; @Inject Lazy mInternetDialogFactory; @Inject Lazy mFeatureFlagsLazy; @@ -587,6 +589,7 @@ public class Dependency { mProviders.put(EDGE_BACK_GESTURE_HANDLER_PROVIDER, () -> mEdgeBackGestureHandlerProvider); mProviders.put(UiEventLogger.class, mUiEventLogger::get); mProviders.put(FeatureFlags.class, mFeatureFlagsLazy::get); + mProviders.put(StatusBarContentInsetsProvider.class, mContentInsetsProviderLazy::get); Dependency.setInstance(this); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt index 5f10e557faede..19a00d231ea2a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt @@ -18,6 +18,8 @@ package com.android.systemui.statusbar.events import android.animation.Animator import android.annotation.UiThread +import android.graphics.Point +import android.graphics.Rect import android.util.Log import android.view.Gravity import android.view.View @@ -31,9 +33,16 @@ import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.StatusBarState.SHADE import com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED -import com.android.systemui.statusbar.phone.StatusBarLocationPublisher -import com.android.systemui.statusbar.phone.StatusBarMarginUpdatedListener +import com.android.systemui.statusbar.phone.StatusBarContentInsetsChangedListener +import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider +import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.concurrency.DelayableExecutor +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 java.lang.IllegalStateException import java.util.concurrent.Executor @@ -58,9 +67,10 @@ import javax.inject.Inject class PrivacyDotViewController @Inject constructor( @Main private val mainExecutor: Executor, private val stateController: StatusBarStateController, - private val locationPublisher: StatusBarLocationPublisher, + private val configurationController: ConfigurationController, + private val contentInsetsProvider: StatusBarContentInsetsProvider, private val animationScheduler: SystemStatusAnimationScheduler -) { +) : StatusBarContentInsetsChangedListener { private var sbHeightPortrait = 0 private var sbHeightLandscape = 0 @@ -84,18 +94,22 @@ class PrivacyDotViewController @Inject constructor( // Privacy dots are created in ScreenDecoration's UiThread, which is not the main thread private var uiExecutor: DelayableExecutor? = null - private val marginListener: StatusBarMarginUpdatedListener = - object : StatusBarMarginUpdatedListener { - override fun onStatusBarMarginUpdated(marginLeft: Int, marginRight: Int) { - setStatusBarMargins(marginLeft, marginRight) - } - } - private val views: Sequence get() = if (!this::tl.isInitialized) sequenceOf() else sequenceOf(tl, tr, br, bl) init { - locationPublisher.addCallback(marginListener) + contentInsetsProvider.addCallback(this) + configurationController.addCallback(object : ConfigurationController.ConfigurationListener { + override fun onLayoutDirectionChanged(isRtl: Boolean) { + synchronized(this) { + val corner = selectDesignatedCorner(nextViewState.rotation, isRtl) + nextViewState = nextViewState.copy( + layoutRtl = isRtl, + designatedCorner = corner + ) + } + } + }) stateController.addCallback(object : StatusBarStateController.StateListener { override fun onExpandedChanged(isExpanded: Boolean) { @@ -123,16 +137,19 @@ class PrivacyDotViewController @Inject constructor( fun setNewRotation(rot: Int) { dlog("updateRotation: $rot") + val isRtl: Boolean synchronized(lock) { if (rot == nextViewState.rotation) { return } + + isRtl = nextViewState.layoutRtl } // If we rotated, hide all dotes until the next state resolves setCornerVisibilities(View.INVISIBLE) - val newCorner = selectDesignatedCorner(rot) + val newCorner = selectDesignatedCorner(rot, isRtl) val index = newCorner.cornerIndex() val h = when (rot) { @@ -222,15 +239,77 @@ class PrivacyDotViewController @Inject constructor( } } + @UiThread + private fun setCornerSizes(state: ViewState) { + // StatusBarContentInsetsProvider can tell us the location of the privacy indicator dot + // in every rotation. The only thing we need to check is rtl + val rtl = state.layoutRtl + val size = Point() + tl.context.display.getRealSize(size) + val currentRotation = RotationUtils.getExactRotation(tl.context) + + val displayWidth: Int + val displayHeight: Int + if (currentRotation == ROTATION_LANDSCAPE || currentRotation == ROTATION_SEASCAPE) { + displayWidth = size.y + displayHeight = size.x + } else { + displayWidth = size.x + displayHeight = size.y + } + + var rot = activeRotationForCorner(tl, rtl) + var contentInsets = state.contentRectForRotation(rot) + (tl.layoutParams as FrameLayout.LayoutParams).apply { + height = contentInsets.height() + if (rtl) { + width = contentInsets.left + } else { + width = displayHeight - contentInsets.right + } + } + + rot = activeRotationForCorner(tr, rtl) + contentInsets = state.contentRectForRotation(rot) + (tr.layoutParams as FrameLayout.LayoutParams).apply { + height = contentInsets.height() + if (rtl) { + width = contentInsets.left + } else { + width = displayWidth - contentInsets.right + } + } + + rot = activeRotationForCorner(br, rtl) + contentInsets = state.contentRectForRotation(rot) + (br.layoutParams as FrameLayout.LayoutParams).apply { + height = contentInsets.height() + if (rtl) { + width = contentInsets.left + } else { + width = displayHeight - contentInsets.right + } + } + + rot = activeRotationForCorner(bl, rtl) + contentInsets = state.contentRectForRotation(rot) + (bl.layoutParams as FrameLayout.LayoutParams).apply { + height = contentInsets.height() + if (rtl) { + width = contentInsets.left + } else { + width = displayWidth - contentInsets.right + } + } + } + // Designated view will be the one at statusbar's view.END @UiThread - private fun selectDesignatedCorner(r: Int): View? { + private fun selectDesignatedCorner(r: Int, isRtl: Boolean): View? { if (!this::tl.isInitialized) { return null } - val isRtl = tl.isLayoutRtl - return when (r) { 0 -> if (isRtl) tl else tr 1 -> if (isRtl) tr else br @@ -282,6 +361,17 @@ class PrivacyDotViewController @Inject constructor( return modded } + @Rotation + private fun activeRotationForCorner(corner: View, rtl: Boolean): Int { + // Each corner will only be visible in a single rotation, based on rtl + return when (corner) { + tr -> if (rtl) ROTATION_LANDSCAPE else ROTATION_NONE + tl -> if (rtl) ROTATION_NONE else ROTATION_SEASCAPE + br -> if (rtl) ROTATION_UPSIDE_DOWN else ROTATION_LANDSCAPE + else /* bl */ -> if (rtl) ROTATION_SEASCAPE else ROTATION_UPSIDE_DOWN + } + } + private fun widthForCorner(corner: Int, left: Int, right: Int): Int { return when (corner) { TOP_LEFT, BOTTOM_LEFT -> left @@ -303,15 +393,32 @@ class PrivacyDotViewController @Inject constructor( bl = bottomLeft br = bottomRight - val dc = selectDesignatedCorner(0) + val rtl = configurationController.isLayoutRtl + val dc = selectDesignatedCorner(0, rtl) + val index = dc.cornerIndex() mainExecutor.execute { animationScheduler.addCallback(systemStatusAnimationCallback) } + val left = contentInsetsProvider.getStatusBarContentInsetsForRotation(ROTATION_SEASCAPE) + val top = contentInsetsProvider.getStatusBarContentInsetsForRotation(ROTATION_NONE) + val right = contentInsetsProvider.getStatusBarContentInsetsForRotation(ROTATION_LANDSCAPE) + val bottom = contentInsetsProvider + .getStatusBarContentInsetsForRotation(ROTATION_UPSIDE_DOWN) + synchronized(lock) { - nextViewState = nextViewState.copy(designatedCorner = dc, cornerIndex = index) + nextViewState = nextViewState.copy( + viewInitialized = true, + designatedCorner = dc, + cornerIndex = index, + seascapeRect = left, + portraitRect = top, + landscapeRect = right, + upsideDownRect = bottom, + layoutRtl = rtl + ) } } @@ -324,19 +431,6 @@ class PrivacyDotViewController @Inject constructor( sbHeightLandscape = landscape } - /** - * The dot view containers will fill the margin in order to position the dots correctly - * - * @param left the space between the status bar contents and the left side of the screen - * @param right space between the status bar contents and the right side of the screen - */ - private fun setStatusBarMargins(left: Int, right: Int) { - dlog("setStatusBarMargins l=$left r=$right") - synchronized(lock) { - nextViewState = nextViewState.copy(marginLeft = left, marginRight = right) - } - } - private fun updateStatusBarState() { synchronized(lock) { nextViewState = nextViewState.copy(shadeExpanded = isShadeInQs()) @@ -377,6 +471,11 @@ class PrivacyDotViewController @Inject constructor( @UiThread private fun resolveState(state: ViewState) { dlog("resolveState $state") + if (!state.viewInitialized) { + dlog("resolveState: view is not initialized. skipping") + return + } + if (state == currentViewState) { dlog("resolveState: skipping") return @@ -387,23 +486,15 @@ class PrivacyDotViewController @Inject constructor( updateRotations(state.rotation) } - if (state.height != currentViewState.height) { - updateHeights(state.rotation) - } - - if (state.marginLeft != currentViewState.marginLeft || - state.marginRight != currentViewState.marginRight) { - updateCornerSizes(state.marginLeft, state.marginRight, state.rotation) + if (state.needsLayout(currentViewState)) { + setCornerSizes(state) + views.forEach { it.requestLayout() } } if (state.designatedCorner != currentViewState.designatedCorner) { updateDesignatedCorner(state.designatedCorner, state.shouldShowDot()) } - if (state.needsLayout(currentViewState)) { - views.forEach { it.requestLayout() } - } - val shouldShow = state.shouldShowDot() if (shouldShow != currentViewState.shouldShowDot()) { if (shouldShow && state.designatedCorner != null) { @@ -441,6 +532,35 @@ class PrivacyDotViewController @Inject constructor( } return -1 } + + override fun onStatusBarContentInsetsChanged() { + Log.d(TAG, "onStatusBarContentInsetsChanged: ") + setNewLayoutRects() + } + + // Returns [left, top, right, bottom] aka [seascape, none, landscape, upside-down] + private fun getLayoutRects(): List { + val left = contentInsetsProvider.getStatusBarContentInsetsForRotation(ROTATION_SEASCAPE) + val top = contentInsetsProvider.getStatusBarContentInsetsForRotation(ROTATION_NONE) + val right = contentInsetsProvider.getStatusBarContentInsetsForRotation(ROTATION_LANDSCAPE) + val bottom = contentInsetsProvider + .getStatusBarContentInsetsForRotation(ROTATION_UPSIDE_DOWN) + + return listOf(left, top, right, bottom) + } + + private fun setNewLayoutRects() { + val rects = getLayoutRects() + + synchronized(lock) { + nextViewState = nextViewState.copy( + seascapeRect = rects[0], + portraitRect = rects[1], + landscapeRect = rects[2], + upsideDownRect = rects[3] + ) + } + } } private fun dlog(s: String) { @@ -461,7 +581,7 @@ const val BOTTOM_RIGHT = 2 const val BOTTOM_LEFT = 3 private const val DURATION = 160L private const val TAG = "PrivacyDotViewController" -private const val DEBUG = true +private const val DEBUG = false private const val DEBUG_VERBOSE = false private fun Int.toGravity(): Int { @@ -485,14 +605,20 @@ private fun Int.innerGravity(): Int { } private data class ViewState( + val viewInitialized: Boolean = false, + val systemPrivacyEventIsActive: Boolean = false, val shadeExpanded: Boolean = false, val qsExpanded: Boolean = false, + val portraitRect: Rect? = null, + val landscapeRect: Rect? = null, + val upsideDownRect: Rect? = null, + val seascapeRect: Rect? = null, + val layoutRtl: Boolean = false, + val rotation: Int = 0, val height: Int = 0, - val marginLeft: Int = 0, - val marginRight: Int = 0, val cornerIndex: Int = -1, val designatedCorner: View? = null ) { @@ -502,7 +628,20 @@ private data class ViewState( fun needsLayout(other: ViewState): Boolean { return rotation != other.rotation || - marginRight != other.marginRight || - height != other.height + layoutRtl != other.layoutRtl || + portraitRect != other.portraitRect || + landscapeRect != other.landscapeRect || + upsideDownRect != other.upsideDownRect || + seascapeRect != other.seascapeRect + } + + fun contentRectForRotation(@Rotation rot: Int): Rect { + return when (rot) { + ROTATION_NONE -> portraitRect!! + ROTATION_LANDSCAPE -> landscapeRect!! + ROTATION_UPSIDE_DOWN -> upsideDownRect!! + ROTATION_SEASCAPE -> seascapeRect!! + else -> throw IllegalArgumentException("not a rotation ($rot)") + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java index a68dab9f046bf..14b39fec378ff 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java @@ -37,7 +37,6 @@ import android.view.ViewGroup; import android.view.ViewStub; import android.widget.LinearLayout; -import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.animation.Interpolators; import com.android.systemui.plugins.statusbar.StatusBarStateController; @@ -79,9 +78,9 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue public static final int FADE_IN_DURATION = 320; public static final int FADE_IN_DELAY = 50; private PhoneStatusBarView mStatusBar; - private StatusBarStateController mStatusBarStateController; - private KeyguardStateController mKeyguardStateController; - private NetworkController mNetworkController; + private final StatusBarStateController mStatusBarStateController; + private final KeyguardStateController mKeyguardStateController; + private final NetworkController mNetworkController; private LinearLayout mSystemIconArea; private View mClockView; private View mOngoingCallChip; @@ -92,12 +91,13 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue private Lazy> mStatusBarOptionalLazy; private DarkIconManager mDarkIconManager; private View mOperatorNameFrame; - private CommandQueue mCommandQueue; - private OngoingCallController mOngoingCallController; + private final CommandQueue mCommandQueue; + private final OngoingCallController mOngoingCallController; private final SystemStatusAnimationScheduler mAnimationScheduler; private final StatusBarLocationPublisher mLocationPublisher; - private NotificationIconAreaController mNotificationIconAreaController; private final FeatureFlags mFeatureFlags; + private final NotificationIconAreaController mNotificationIconAreaController; + private final StatusBarIconController mStatusBarIconController; private List mBlockedIcons = new ArrayList<>(); @@ -122,23 +122,24 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue StatusBarLocationPublisher locationPublisher, NotificationIconAreaController notificationIconAreaController, FeatureFlags featureFlags, - Lazy> statusBarOptionalLazy + StatusBarIconController statusBarIconController, + KeyguardStateController keyguardStateController, + NetworkController networkController, + StatusBarStateController statusBarStateController, + Lazy> statusBarOptionalLazy, + CommandQueue commandQueue ) { mOngoingCallController = ongoingCallController; mAnimationScheduler = animationScheduler; mLocationPublisher = locationPublisher; mNotificationIconAreaController = notificationIconAreaController; mFeatureFlags = featureFlags; + mStatusBarIconController = statusBarIconController; + mKeyguardStateController = keyguardStateController; + mNetworkController = networkController; + mStatusBarStateController = statusBarStateController; mStatusBarOptionalLazy = statusBarOptionalLazy; - } - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mKeyguardStateController = Dependency.get(KeyguardStateController.class); - mNetworkController = Dependency.get(NetworkController.class); - mStatusBarStateController = Dependency.get(StatusBarStateController.class); - mCommandQueue = Dependency.get(CommandQueue.class); + mCommandQueue = commandQueue; } @Override @@ -164,7 +165,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue mBlockedIcons.add(getString(com.android.internal.R.string.status_bar_alarm_clock)); mBlockedIcons.add(getString(com.android.internal.R.string.status_bar_call_strength)); mDarkIconManager.setBlockList(mBlockedIcons); - Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager); + mStatusBarIconController.addIconGroup(mDarkIconManager); mSystemIconArea = mStatusBar.findViewById(R.id.system_icon_area); mClockView = mStatusBar.findViewById(R.id.clock); mOngoingCallChip = mStatusBar.findViewById(R.id.ongoing_call_chip); @@ -203,7 +204,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue @Override public void onDestroyView() { super.onDestroyView(); - Dependency.get(StatusBarIconController.class).removeIconGroup(mDarkIconManager); + mStatusBarIconController.removeIconGroup(mDarkIconManager); if (mNetworkController.hasEmergencyCryptKeeperText()) { mNetworkController.removeCallback(mSignalCallback); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt index b148eeba2cf55..07618da4451a4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt @@ -18,6 +18,7 @@ import android.content.Context import android.content.pm.ActivityInfo import android.content.res.Configuration import android.os.LocaleList +import android.view.View.LAYOUT_DIRECTION_RTL import com.android.systemui.statusbar.policy.ConfigurationController import java.util.ArrayList @@ -33,6 +34,7 @@ class ConfigurationControllerImpl(context: Context) : ConfigurationController { private var uiMode: Int = 0 private var localeList: LocaleList? = null private val context: Context + private var layoutDirection: Int init { val currentConfig = context.resources.configuration @@ -44,6 +46,7 @@ class ConfigurationControllerImpl(context: Context) : ConfigurationController { Configuration.UI_MODE_TYPE_CAR uiMode = currentConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK localeList = currentConfig.locales + layoutDirection = currentConfig.layoutDirection } override fun notifyThemeChanged() { @@ -101,6 +104,13 @@ class ConfigurationControllerImpl(context: Context) : ConfigurationController { } } + if (layoutDirection != newConfig.layoutDirection) { + layoutDirection = newConfig.layoutDirection + listeners.filterForEach({ this.listeners.contains(it) }) { + it.onLayoutDirectionChanged(layoutDirection == LAYOUT_DIRECTION_RTL) + } + } + if (lastConfig.updateFrom(newConfig) and ActivityInfo.CONFIG_ASSETS_PATHS != 0) { listeners.filterForEach({ this.listeners.contains(it) }) { it.onOverlayChanged() @@ -116,6 +126,10 @@ class ConfigurationControllerImpl(context: Context) : ConfigurationController { override fun removeCallback(listener: ConfigurationController.ConfigurationListener) { listeners.remove(listener) } + + override fun isLayoutRtl(): Boolean { + return layoutDirection == LAYOUT_DIRECTION_RTL + } } // This could be done with a Collection.filter and Collection.forEach, but Collection.filter diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 31a432e2c451f..c300b11b9a34b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -23,6 +23,7 @@ import static java.lang.Float.isNaN; 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.EventLog; @@ -52,6 +53,7 @@ public class PhoneStatusBarView extends PanelBar { private static final boolean DEBUG = StatusBar.DEBUG; private static final boolean DEBUG_GESTURES = false; private final CommandQueue mCommandQueue; + private final StatusBarContentInsetsProvider mContentInsetsProvider; StatusBar mBar; @@ -85,11 +87,10 @@ public class PhoneStatusBarView extends PanelBar { private int mCutoutSideNudge = 0; private boolean mHeadsUpVisible; - private int mRoundedCornerPadding = 0; - public PhoneStatusBarView(Context context, AttributeSet attrs) { super(context, attrs); mCommandQueue = Dependency.get(CommandQueue.class); + mContentInsetsProvider = Dependency.get(StatusBarContentInsetsProvider.class); } public void setBar(StatusBar bar) { @@ -305,8 +306,6 @@ public class PhoneStatusBarView extends PanelBar { public void updateResources() { mCutoutSideNudge = getResources().getDimensionPixelSize( R.dimen.display_cutout_margin_consumption); - mRoundedCornerPadding = getResources().getDimensionPixelSize( - R.dimen.rounded_corner_content_padding); updateStatusBarHeight(); } @@ -341,8 +340,7 @@ public class PhoneStatusBarView extends PanelBar { private void updateLayoutForCutout() { updateStatusBarHeight(); updateCutoutLocation(StatusBarWindowView.cornerCutoutMargins(mDisplayCutout, getDisplay())); - updateSafeInsets(StatusBarWindowView.statusBarCornerCutoutMargins(mDisplayCutout, - getDisplay(), mRotationOrientation, mStatusBarHeight)); + updateSafeInsets(); } private void updateCutoutLocation(Pair cornerCutoutMargins) { @@ -370,15 +368,18 @@ public class PhoneStatusBarView extends PanelBar { lp.height = bounds.height(); } - private void updateSafeInsets(Pair cornerCutoutMargins) { - // Depending on our rotation, we may have to work around a cutout in the middle of the view, - // or letterboxing from the right or left sides. + private void updateSafeInsets() { + Rect contentRect = mContentInsetsProvider + .getStatusBarContentInsetsForRotation(RotationUtils.getExactRotation(getContext())); - Pair padding = - StatusBarWindowView.paddingNeededForCutoutAndRoundedCorner( - mDisplayCutout, cornerCutoutMargins, mRoundedCornerPadding); + Point size = new Point(); + getDisplay().getRealSize(size); - setPadding(padding.first, getPaddingTop(), padding.second, getPaddingBottom()); + setPadding( + contentRect.left, + getPaddingTop(), + size.x - contentRect.right, + getPaddingBottom()); } public void setHeadsUpVisible(boolean headsUpVisible) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index f78a003d02959..2c2d91c777b3e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -442,6 +442,7 @@ public class StatusBar extends SystemUI implements DemoMode, private final OngoingCallController mOngoingCallController; private final SystemStatusAnimationScheduler mAnimationScheduler; private final StatusBarLocationPublisher mStatusBarLocationPublisher; + private final StatusBarIconController mStatusBarIconController; // expanded notifications // the sliding/resizing panel within the notification window @@ -804,6 +805,7 @@ public class StatusBar extends SystemUI implements DemoMode, OngoingCallController ongoingCallController, SystemStatusAnimationScheduler animationScheduler, StatusBarLocationPublisher locationPublisher, + StatusBarIconController statusBarIconController, LockscreenShadeTransitionController lockscreenShadeTransitionController, FeatureFlags featureFlags, KeyguardUnlockAnimationController keyguardUnlockAnimationController, @@ -890,6 +892,7 @@ public class StatusBar extends SystemUI implements DemoMode, mOngoingCallController = ongoingCallController; mAnimationScheduler = animationScheduler; mStatusBarLocationPublisher = locationPublisher; + mStatusBarIconController = statusBarIconController; mFeatureFlags = featureFlags; mKeyguardUnlockAnimationController = keyguardUnlockAnimationController; mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController; @@ -1193,7 +1196,13 @@ public class StatusBar extends SystemUI implements DemoMode, mStatusBarLocationPublisher, mNotificationIconAreaController, mFeatureFlags, - () -> Optional.of(this)), + mStatusBarIconController, + mKeyguardStateController, + mNetworkController, + mStatusBarStateController, + () -> Optional.of(this), + mCommandQueue + ), CollapsedStatusBarFragment.TAG) .commit(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java index 716d1dbc64628..b6e8bd8bf7c17 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java @@ -89,6 +89,7 @@ import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy; import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; +import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.phone.StatusBarLocationPublisher; import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter; @@ -216,6 +217,7 @@ public interface StatusBarPhoneModule { OngoingCallController ongoingCallController, SystemStatusAnimationScheduler animationScheduler, StatusBarLocationPublisher locationPublisher, + StatusBarIconController statusBarIconController, LockscreenShadeTransitionController transitionController, FeatureFlags featureFlags, KeyguardUnlockAnimationController keyguardUnlockAnimationController, @@ -305,6 +307,7 @@ public interface StatusBarPhoneModule { ongoingCallController, animationScheduler, locationPublisher, + statusBarIconController, transitionController, featureFlags, keyguardUnlockAnimationController, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java index c2bd87c6276f5..3a05ec78a8b0b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java @@ -30,6 +30,9 @@ public interface ConfigurationController extends CallbackController Optional.of(mStatusBar)); + mStatusBarIconController, + mKeyguardStateController, + mNetworkController, + mStatusBarStateController, + () -> Optional.of(mStatusBar), + mCommandQueue); } + private void setUpNotificationIconAreaController() { mMockNotificationAreaController = mock(NotificationIconAreaController.class); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java index c504fd8c78010..7dc7a66ec14b7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java @@ -269,6 +269,7 @@ public class StatusBarTest extends SysuiTestCase { @Mock private OngoingCallController mOngoingCallController; @Mock private SystemStatusAnimationScheduler mAnimationScheduler; @Mock private StatusBarLocationPublisher mLocationPublisher; + @Mock private StatusBarIconController mIconController; @Mock private LockscreenShadeTransitionController mLockscreenTransitionController; @Mock private FeatureFlags mFeatureFlags; @Mock private IWallpaperManager mWallpaperManager; @@ -442,6 +443,7 @@ public class StatusBarTest extends SysuiTestCase { mOngoingCallController, mAnimationScheduler, mLocationPublisher, + mIconController, mLockscreenTransitionController, mFeatureFlags, mKeyguardUnlockAnimationController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeConfigurationController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeConfigurationController.java index f5ccac39ed203..516eb6e6dffd7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeConfigurationController.java +++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeConfigurationController.java @@ -33,4 +33,9 @@ public class FakeConfigurationController @Override public void notifyThemeChanged() { } + + @Override + public boolean isLayoutRtl() { + return false; + } }