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 5ab71bc62fe60..b3f7ca6f26305 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt @@ -29,6 +29,8 @@ import com.android.systemui.animation.Interpolators import com.android.systemui.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.statusbar.phone.StatusBarLocationPublisher +import com.android.systemui.statusbar.phone.StatusBarMarginUpdatedListener import java.lang.IllegalStateException import java.util.concurrent.Executor @@ -51,8 +53,9 @@ import javax.inject.Inject @SysUISingleton class PrivacyDotViewController @Inject constructor( - @Main val mainExecutor: Executor, - val animationScheduler: SystemStatusAnimationScheduler + @Main private val mainExecutor: Executor, + private val locationPublisher: StatusBarLocationPublisher, + private val animationScheduler: SystemStatusAnimationScheduler ) { private var rotation = 0 private var leftSize = 0 @@ -80,12 +83,21 @@ class PrivacyDotViewController @Inject constructor( private val views: Sequence get() = if (!this::tl.isInitialized) sequenceOf() else sequenceOf(tl, tr, br, bl) + init { + locationPublisher.addCallback(object : StatusBarMarginUpdatedListener { + override fun onStatusBarMarginUpdated(marginLeft: Int, marginRight: Int) { + setStatusBarMargins(marginLeft, marginRight) + } + }) + } + fun setUiExecutor(e: Executor) { uiExecutor = e } @UiThread fun updateRotation(rot: Int) { + dlog("updateRotation: ") if (rot == rotation) { return } @@ -248,7 +260,7 @@ class PrivacyDotViewController @Inject constructor( * @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 */ - fun setStatusBarMargins(left: Int, right: Int) { + private fun setStatusBarMargins(left: Int, right: Int) { leftSize = left rightSize = right @@ -262,6 +274,7 @@ class PrivacyDotViewController @Inject constructor( } private fun doUpdates(rot: Boolean, height: Boolean, width: Boolean) { + dlog("doUpdates: ") var newDesignatedCorner: View? = null if (rot) { @@ -324,12 +337,19 @@ class PrivacyDotViewController @Inject constructor( } } +private fun dlog(s: String) { + if (DEBUG) { + Log.d(TAG, s) + } +} + const val TOP_LEFT = 0 const val TOP_RIGHT = 1 const val BOTTOM_RIGHT = 2 const val BOTTOM_LEFT = 3 private const val DURATION = 160L private const val TAG = "PrivacyDotViewController" +private const val DEBUG = false private fun Int.toGravity(): Int { return when (this) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt index 620963060b496..b861c1db9b8b9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt @@ -27,6 +27,7 @@ import android.widget.FrameLayout import com.android.systemui.R import com.android.systemui.statusbar.SuperStatusBarViewFactory +import com.android.systemui.statusbar.phone.StatusBarLocationPublisher import com.android.systemui.statusbar.phone.StatusBarWindowController import com.android.systemui.statusbar.phone.StatusBarWindowView @@ -39,7 +40,8 @@ import javax.inject.Inject class SystemEventChipAnimationController @Inject constructor( private val context: Context, private val statusBarViewFactory: SuperStatusBarViewFactory, - private val statusBarWindowController: StatusBarWindowController + private val statusBarWindowController: StatusBarWindowController, + private val locationPublisher: StatusBarLocationPublisher ) : SystemStatusChipAnimationCallback { var showPersistentDot = false set(value) { @@ -64,13 +66,15 @@ class SystemEventChipAnimationController @Inject constructor( if (state == ANIMATING_IN) { currentAnimatedView = viewCreator(context) - animationWindowView.addView(currentAnimatedView, layoutParamsDefault) + animationWindowView.addView(currentAnimatedView, layoutParamsDefault()) // We are animating IN; chip comes in from View.END currentAnimatedView?.apply { - translationX = width.toFloat() + val translation = width.toFloat() + translationX = if (isLayoutRtl) -translation else translation alpha = 0f visibility = View.VISIBLE + setPadding(locationPublisher.marginLeft, 0, locationPublisher.marginRight, 0) } } else { // We are animating away @@ -109,7 +113,7 @@ class SystemEventChipAnimationController @Inject constructor( val w = width val translation = (1 - amt) * w - translationX = translation + translationX = if (isLayoutRtl) -translation else translation } } @@ -131,7 +135,13 @@ class SystemEventChipAnimationController @Inject constructor( statusBarWindowView.addView(animationWindowView, lp) } - private val layoutParamsDefault = FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).also { - it.gravity = Gravity.END or Gravity.CENTER_VERTICAL + private fun start() = if (animationWindowView.isLayoutRtl) right() else left() + private fun right() = locationPublisher.marginRight + private fun left() = locationPublisher.marginLeft + + private fun layoutParamsDefault(): FrameLayout.LayoutParams = + FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).also { + it.gravity = Gravity.END or Gravity.CENTER_VERTICAL + it.marginStart = start() } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt index 1e071312065b4..40049373610cb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt @@ -127,7 +127,6 @@ class SystemStatusAnimationScheduler @Inject constructor( } private fun isTooEarly(): Boolean { - Log.d(TAG, "time=> ${systemClock.uptimeMillis() - Process.getStartUptimeMillis()}") return systemClock.uptimeMillis() - Process.getStartUptimeMillis() < MIN_UPTIME } @@ -339,4 +338,4 @@ private const val ENTRANCE_ANIM_LENGTH = 500L private const val CHIP_ANIM_LENGTH = 500L private const val MIN_UPTIME: Long = 5 * 1000 -private const val DEBUG = false \ No newline at end of file +private const val DEBUG = false 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 76657ad5ab070..16bed6f3f38d6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java @@ -43,7 +43,6 @@ import com.android.systemui.animation.Interpolators; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.statusbar.events.PrivacyDotViewController; import com.android.systemui.statusbar.events.SystemStatusAnimationCallback; import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler; import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager; @@ -92,7 +91,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue private CommandQueue mCommandQueue; private OngoingCallController mOngoingCallController; private final SystemStatusAnimationScheduler mAnimationScheduler; - private final PrivacyDotViewController mDotViewController; + private final StatusBarLocationPublisher mLocationPublisher; private NotificationIconAreaController mNotificationIconAreaController; private List mBlockedIcons = new ArrayList<>(); @@ -120,12 +119,12 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue public CollapsedStatusBarFragment( OngoingCallController ongoingCallController, SystemStatusAnimationScheduler animationScheduler, - PrivacyDotViewController dotViewController, + StatusBarLocationPublisher locationPublisher, NotificationIconAreaController notificationIconAreaController ) { mOngoingCallController = ongoingCallController; mAnimationScheduler = animationScheduler; - mDotViewController = dotViewController; + mLocationPublisher = locationPublisher; mNotificationIconAreaController = notificationIconAreaController; } @@ -540,7 +539,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue int leftMargin = left - mStatusBar.getLeft(); int rightMargin = mStatusBar.getRight() - right; - mDotViewController.setStatusBarMargins(leftMargin, rightMargin); + mLocationPublisher.updateStatusBarMargin(leftMargin, rightMargin); } // Listen for view end changes of PhoneStatusBarView and publish that to the privacy dot 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 aaef739af8c44..8363fd68ba937 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -209,7 +209,6 @@ import com.android.systemui.statusbar.SuperStatusBarViewFactory; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.charging.WiredChargingRippleController; -import com.android.systemui.statusbar.events.PrivacyDotViewController; import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler; import com.android.systemui.statusbar.notification.DynamicPrivacyController; import com.android.systemui.statusbar.notification.NotificationActivityStarter; @@ -429,7 +428,7 @@ public class StatusBar extends SystemUI implements DemoMode, private NotificationsController mNotificationsController; private final OngoingCallController mOngoingCallController; private final SystemStatusAnimationScheduler mAnimationScheduler; - private final PrivacyDotViewController mDotViewController; + private final StatusBarLocationPublisher mStatusBarLocationPublisher; // expanded notifications // the sliding/resizing panel within the notification window @@ -799,7 +798,7 @@ public class StatusBar extends SystemUI implements DemoMode, WiredChargingRippleController chargingRippleAnimationController, OngoingCallController ongoingCallController, SystemStatusAnimationScheduler animationScheduler, - PrivacyDotViewController dotViewController, + StatusBarLocationPublisher locationPublisher, FeatureFlags featureFlags, KeyguardUnlockAnimationController keyguardUnlockAnimationController) { super(context); @@ -882,7 +881,7 @@ public class StatusBar extends SystemUI implements DemoMode, mChargingRippleAnimationController = chargingRippleAnimationController; mOngoingCallController = ongoingCallController; mAnimationScheduler = animationScheduler; - mDotViewController = dotViewController; + mStatusBarLocationPublisher = locationPublisher; mFeatureFlags = featureFlags; mExpansionChangedListeners = new ArrayList<>(); @@ -1175,7 +1174,7 @@ public class StatusBar extends SystemUI implements DemoMode, new CollapsedStatusBarFragment( mOngoingCallController, mAnimationScheduler, - mDotViewController, + mStatusBarLocationPublisher, mNotificationIconAreaController), CollapsedStatusBarFragment.TAG) .commit(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLocationPublisher.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLocationPublisher.kt new file mode 100644 index 0000000000000..4e5ecfe3f6237 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLocationPublisher.kt @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.phone + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.statusbar.policy.CallbackController +import java.lang.ref.WeakReference +import javax.inject.Inject + +/** + * Publishes updates to the status bar's margins. + * + * While the status bar view consumes the entire width of the device, the status bar + * contents are laid out with margins for rounded corners, padding from the absolute + * edges, and potentially display cutouts in the corner. + */ +@SysUISingleton +class StatusBarLocationPublisher @Inject constructor() +: CallbackController { + private val listeners = mutableSetOf>() + + var marginLeft: Int = 0 + private set + var marginRight: Int = 0 + private set + + override fun addCallback(listener: StatusBarMarginUpdatedListener) { + listeners.add(WeakReference(listener)) + } + + override fun removeCallback(listener: StatusBarMarginUpdatedListener) { + var toRemove: WeakReference? = null + for (l in listeners) { + if (l.get() == listener) { + toRemove = l + } + } + + if (toRemove != null) { + listeners.remove(toRemove) + } + } + + fun updateStatusBarMargin(left: Int, right: Int) { + marginLeft = left + marginRight = right + + notifyListeners() + } + + private fun notifyListeners() { + var listenerList: List> + synchronized(this) { + listenerList = listeners.toList() + } + + listenerList.forEach { wrapper -> + if (wrapper.get() == null) { + listeners.remove(wrapper) + } + + wrapper.get()?.onStatusBarMarginUpdated(marginLeft, marginRight) + } + } +} + +interface StatusBarMarginUpdatedListener { + fun onStatusBarMarginUpdated(marginLeft: Int, marginRight: Int) +} \ No newline at end of file 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 66e1c2e1b5719..ae11a74748cd3 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 @@ -62,7 +62,6 @@ import com.android.systemui.statusbar.SuperStatusBarViewFactory; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.charging.WiredChargingRippleController; -import com.android.systemui.statusbar.events.PrivacyDotViewController; import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler; import com.android.systemui.statusbar.notification.DynamicPrivacyController; import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator; @@ -91,6 +90,7 @@ 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; import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager; import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; @@ -212,7 +212,7 @@ public interface StatusBarPhoneModule { WiredChargingRippleController chargingRippleAnimationController, OngoingCallController ongoingCallController, SystemStatusAnimationScheduler animationScheduler, - PrivacyDotViewController dotViewController, + StatusBarLocationPublisher locationPublisher, FeatureFlags featureFlags, KeyguardUnlockAnimationController keyguardUnlockAnimationController) { return new StatusBar( @@ -298,7 +298,7 @@ public interface StatusBarPhoneModule { chargingRippleAnimationController, ongoingCallController, animationScheduler, - dotViewController, + locationPublisher, featureFlags, keyguardUnlockAnimationController); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java index a01e0b1c3e3a1..f485b465e4865 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java @@ -38,7 +38,6 @@ 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.events.PrivacyDotViewController; import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler; import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; @@ -57,7 +56,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { private StatusBarStateController mStatusBarStateController; private OngoingCallController mOngoingCallController; private SystemStatusAnimationScheduler mAnimationScheduler; - private PrivacyDotViewController mDotViewController; + private StatusBarLocationPublisher mLocationPublisher; public CollapsedStatusBarFragmentTest() { super(CollapsedStatusBarFragment.class); @@ -224,12 +223,12 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { protected Fragment instantiate(Context context, String className, Bundle arguments) { mOngoingCallController = mock(OngoingCallController.class); mAnimationScheduler = mock(SystemStatusAnimationScheduler.class); - mDotViewController = mock(PrivacyDotViewController.class); + mLocationPublisher = mock(StatusBarLocationPublisher.class); setUpNotificationIconAreaController(); return new CollapsedStatusBarFragment( mOngoingCallController, mAnimationScheduler, - mDotViewController, + mLocationPublisher, mMockNotificationAreaController); } 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 545e2e08ec07e..b2487e8e2444d 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 @@ -115,7 +115,6 @@ import com.android.systemui.statusbar.StatusBarStateControllerImpl; import com.android.systemui.statusbar.SuperStatusBarViewFactory; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.charging.WiredChargingRippleController; -import com.android.systemui.statusbar.events.PrivacyDotViewController; import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler; import com.android.systemui.statusbar.notification.DynamicPrivacyController; import com.android.systemui.statusbar.notification.NotificationEntryListener; @@ -267,7 +266,7 @@ public class StatusBarTest extends SysuiTestCase { @Mock private WiredChargingRippleController mWiredChargingRippleController; @Mock private OngoingCallController mOngoingCallController; @Mock private SystemStatusAnimationScheduler mAnimationScheduler; - @Mock private PrivacyDotViewController mDotViewController; + @Mock private StatusBarLocationPublisher mLocationPublisher; @Mock private FeatureFlags mFeatureFlags; @Mock private IWallpaperManager mWallpaperManager; @Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController; @@ -437,7 +436,7 @@ public class StatusBarTest extends SysuiTestCase { mWiredChargingRippleController, mOngoingCallController, mAnimationScheduler, - mDotViewController, + mLocationPublisher, mFeatureFlags, mKeyguardUnlockAnimationController); when(mKeyguardViewMediator.registerStatusBar(any(StatusBar.class), any(ViewGroup.class),