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
This commit is contained in:
Evan Laird
2021-06-09 17:05:11 -04:00
parent d1b6cd4a9e
commit 24b99ef4e7
11 changed files with 287 additions and 84 deletions

View File

@@ -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<PrivacyDotViewController> mPrivacyDotViewControllerLazy;
@Inject Provider<EdgeBackGestureHandler> mEdgeBackGestureHandlerProvider;
@Inject Lazy<UiEventLogger> mUiEventLogger;
@Inject Lazy<StatusBarContentInsetsProvider> mContentInsetsProviderLazy;
@Inject Lazy<InternetDialogFactory> mInternetDialogFactory;
@Inject Lazy<FeatureFlags> 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);
}

View File

@@ -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<View>
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<Rect> {
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)")
}
}
}

View File

@@ -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<Optional<StatusBar>> 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<String> mBlockedIcons = new ArrayList<>();
@@ -122,23 +122,24 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
StatusBarLocationPublisher locationPublisher,
NotificationIconAreaController notificationIconAreaController,
FeatureFlags featureFlags,
Lazy<Optional<StatusBar>> statusBarOptionalLazy
StatusBarIconController statusBarIconController,
KeyguardStateController keyguardStateController,
NetworkController networkController,
StatusBarStateController statusBarStateController,
Lazy<Optional<StatusBar>> 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);
}

View File

@@ -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

View File

@@ -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<Integer, Integer> cornerCutoutMargins) {
@@ -370,15 +368,18 @@ public class PhoneStatusBarView extends PanelBar {
lp.height = bounds.height();
}
private void updateSafeInsets(Pair<Integer, Integer> 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<Integer, Integer> 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) {

View File

@@ -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();

View File

@@ -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,

View File

@@ -30,6 +30,9 @@ public interface ConfigurationController extends CallbackController<Configuratio
/** Alert controller of a change in between light and dark themes. */
void notifyThemeChanged();
/** Query the current configuration's layout direction */
boolean isLayoutRtl();
interface ConfigurationListener {
default void onConfigChanged(Configuration newConfig) {}
default void onDensityOrFontScaleChanged() {}
@@ -38,5 +41,6 @@ public interface ConfigurationController extends CallbackController<Configuratio
default void onUiModeChanged() {}
default void onThemeChanged() {}
default void onLocaleListChanged() {}
default void onLayoutDirectionChanged(boolean isLayoutRtl) {}
}
}

View File

@@ -38,11 +38,15 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.R;
import com.android.systemui.SysuiBaseFragmentTest;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.NetworkController;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
@@ -54,21 +58,28 @@ import java.util.Optional;
@SmallTest
public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
private StatusBar mStatusBar;
private NotificationIconAreaController mMockNotificationAreaController;
private View mNotificationAreaInner;
private StatusBarStateController mStatusBarStateController;
private OngoingCallController mOngoingCallController;
private SystemStatusAnimationScheduler mAnimationScheduler;
private StatusBarLocationPublisher mLocationPublisher;
// Set in instantiate()
private StatusBarIconController mStatusBarIconController;
private NetworkController mNetworkController;
private StatusBarStateController mStatusBarStateController;
private KeyguardStateController mKeyguardStateController;
private final StatusBar mStatusBar = mock(StatusBar.class);
private final CommandQueue mCommandQueue = mock(CommandQueue.class);
public CollapsedStatusBarFragmentTest() {
super(CollapsedStatusBarFragment.class);
}
@Before
public void setup() {
mStatusBar = mock(StatusBar.class);
mStatusBarStateController = mDependency
.injectMockDependency(StatusBarStateController.class);
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
@@ -204,6 +215,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
mFragment.getView().findViewById(R.id.ongoing_call_chip).getVisibility());
}
@Ignore("b/192618546")
@Test
public void testOnDozingChanged() throws Exception {
mFragments.dispatchResume();
@@ -227,6 +239,10 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
mOngoingCallController = mock(OngoingCallController.class);
mAnimationScheduler = mock(SystemStatusAnimationScheduler.class);
mLocationPublisher = mock(StatusBarLocationPublisher.class);
mStatusBarIconController = mock(StatusBarIconController.class);
mNetworkController = mock(NetworkController.class);
mStatusBarStateController = mock(StatusBarStateController.class);
mKeyguardStateController = mock(KeyguardStateController.class);
setUpNotificationIconAreaController();
return new CollapsedStatusBarFragment(
mOngoingCallController,
@@ -234,9 +250,15 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
mLocationPublisher,
mMockNotificationAreaController,
mock(FeatureFlags.class),
() -> Optional.of(mStatusBar));
mStatusBarIconController,
mKeyguardStateController,
mNetworkController,
mStatusBarStateController,
() -> Optional.of(mStatusBar),
mCommandQueue);
}
private void setUpNotificationIconAreaController() {
mMockNotificationAreaController = mock(NotificationIconAreaController.class);

View File

@@ -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,

View File

@@ -33,4 +33,9 @@ public class FakeConfigurationController
@Override
public void notifyThemeChanged() {
}
@Override
public boolean isLayoutRtl() {
return false;
}
}