Loading packages/SystemUI/src/com/android/systemui/Dependency.java +3 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,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; Loading Loading @@ -358,6 +359,7 @@ public class Dependency { @Inject Lazy<EdgeBackGestureHandler.Factory> mEdgeBackGestureHandlerFactoryLazy; @Inject Lazy<UiEventLogger> mUiEventLogger; @Inject Lazy<FeatureFlags> mFeatureFlagsLazy; @Inject Lazy<StatusBarContentInsetsProvider> mContentInsetsProviderLazy; @Inject public Dependency() { Loading Loading @@ -572,6 +574,7 @@ public class Dependency { mEdgeBackGestureHandlerFactoryLazy::get); mProviders.put(UiEventLogger.class, mUiEventLogger::get); mProviders.put(FeatureFlags.class, mFeatureFlagsLazy::get); mProviders.put(StatusBarContentInsetsProvider.class, mContentInsetsProviderLazy::get); Dependency.setInstance(this); } Loading packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt +185 −46 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -58,7 +67,8 @@ 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 ) { private var sbHeightPortrait = 0 Loading @@ -84,18 +94,27 @@ 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(object : StatusBarContentInsetsChangedListener { override fun onStatusBarContentInsetsChanged() { dlog("onStatusBarContentInsetsChanged: ") setNewLayoutRects() } }) 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) { Loading Loading @@ -123,16 +142,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) { Loading Loading @@ -222,15 +244,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 Loading Loading @@ -282,6 +366,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 Loading @@ -303,15 +398,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 ) } } Loading @@ -324,19 +436,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()) Loading Loading @@ -377,6 +476,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 Loading @@ -387,23 +491,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) { Loading Loading @@ -441,6 +537,30 @@ class PrivacyDotViewController @Inject constructor( } return -1 } // 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) { Loading @@ -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 { Loading @@ -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 ) { Loading @@ -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)") } } } packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java +20 −19 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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<>(); Loading @@ -122,7 +122,12 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue StatusBarLocationPublisher locationPublisher, NotificationIconAreaController notificationIconAreaController, FeatureFlags featureFlags, Lazy<Optional<StatusBar>> statusBarOptionalLazy Lazy<Optional<StatusBar>> statusBarOptionalLazy, StatusBarIconController statusBarIconController, KeyguardStateController keyguardStateController, NetworkController networkController, StatusBarStateController statusBarStateController, CommandQueue commandQueue ) { mOngoingCallController = ongoingCallController; mAnimationScheduler = animationScheduler; Loading @@ -130,15 +135,11 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue mNotificationIconAreaController = notificationIconAreaController; mFeatureFlags = featureFlags; 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); mStatusBarIconController = statusBarIconController; mKeyguardStateController = keyguardStateController; mNetworkController = networkController; mStatusBarStateController = statusBarStateController; mCommandQueue = commandQueue; } @Override Loading @@ -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); Loading Loading @@ -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); } Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt +14 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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() { Loading Loading @@ -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() Loading @@ -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 Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +14 −13 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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(); } Loading Loading @@ -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) { Loading Loading @@ -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) { Loading Loading
packages/SystemUI/src/com/android/systemui/Dependency.java +3 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,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; Loading Loading @@ -358,6 +359,7 @@ public class Dependency { @Inject Lazy<EdgeBackGestureHandler.Factory> mEdgeBackGestureHandlerFactoryLazy; @Inject Lazy<UiEventLogger> mUiEventLogger; @Inject Lazy<FeatureFlags> mFeatureFlagsLazy; @Inject Lazy<StatusBarContentInsetsProvider> mContentInsetsProviderLazy; @Inject public Dependency() { Loading Loading @@ -572,6 +574,7 @@ public class Dependency { mEdgeBackGestureHandlerFactoryLazy::get); mProviders.put(UiEventLogger.class, mUiEventLogger::get); mProviders.put(FeatureFlags.class, mFeatureFlagsLazy::get); mProviders.put(StatusBarContentInsetsProvider.class, mContentInsetsProviderLazy::get); Dependency.setInstance(this); } Loading
packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt +185 −46 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -58,7 +67,8 @@ 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 ) { private var sbHeightPortrait = 0 Loading @@ -84,18 +94,27 @@ 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(object : StatusBarContentInsetsChangedListener { override fun onStatusBarContentInsetsChanged() { dlog("onStatusBarContentInsetsChanged: ") setNewLayoutRects() } }) 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) { Loading Loading @@ -123,16 +142,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) { Loading Loading @@ -222,15 +244,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 Loading Loading @@ -282,6 +366,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 Loading @@ -303,15 +398,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 ) } } Loading @@ -324,19 +436,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()) Loading Loading @@ -377,6 +476,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 Loading @@ -387,23 +491,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) { Loading Loading @@ -441,6 +537,30 @@ class PrivacyDotViewController @Inject constructor( } return -1 } // 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) { Loading @@ -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 { Loading @@ -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 ) { Loading @@ -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)") } } }
packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java +20 −19 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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<>(); Loading @@ -122,7 +122,12 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue StatusBarLocationPublisher locationPublisher, NotificationIconAreaController notificationIconAreaController, FeatureFlags featureFlags, Lazy<Optional<StatusBar>> statusBarOptionalLazy Lazy<Optional<StatusBar>> statusBarOptionalLazy, StatusBarIconController statusBarIconController, KeyguardStateController keyguardStateController, NetworkController networkController, StatusBarStateController statusBarStateController, CommandQueue commandQueue ) { mOngoingCallController = ongoingCallController; mAnimationScheduler = animationScheduler; Loading @@ -130,15 +135,11 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue mNotificationIconAreaController = notificationIconAreaController; mFeatureFlags = featureFlags; 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); mStatusBarIconController = statusBarIconController; mKeyguardStateController = keyguardStateController; mNetworkController = networkController; mStatusBarStateController = statusBarStateController; mCommandQueue = commandQueue; } @Override Loading @@ -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); Loading Loading @@ -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); } Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt +14 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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() { Loading Loading @@ -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() Loading @@ -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 Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +14 −13 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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(); } Loading Loading @@ -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) { Loading Loading @@ -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) { Loading