Move status view to keyguard root view
Moves the whole space without breaking it apart (yet). This includes
clocks, smartsapce, notif shelf, and media for split shade mode.
Add a guideline to support split shade in the new constraint layout.
Also, simplify how smartspace views are readded especially following a
config change to make sure they get updated.
Bug: 288242803
Test: atest KeyguardStatusViewControllerTest NotificationPanelViewControllerTest
Change-Id: Ide48b8dcd6d111cec8872bf758e8f78797f7860a
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 15ca9d4..d2cb475 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -212,6 +212,7 @@
<item type="id" name="keyguard_indication_text" />
<item type="id" name="keyguard_indication_text_bottom" />
<item type="id" name="nssl_guideline" />
+ <item type="id" name="split_shade_guideline" />
<item type="id" name="lock_icon" />
<item type="id" name="lock_icon_bg" />
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 4d196aa..a9531cf 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -243,24 +243,8 @@
return;
}
updateAodIcons();
-
mStatusArea = mView.findViewById(R.id.keyguard_status_area);
- if (mSmartspaceController.isEnabled()) {
- View ksv = mView.findViewById(R.id.keyguard_slice_view);
- int viewIndex = mStatusArea.indexOfChild(ksv);
- ksv.setVisibility(View.GONE);
-
- // TODO(b/261757708): add content observer for the Settings toggle and add/remove
- // weather according to the Settings.
- if (mSmartspaceController.isDateWeatherDecoupled()) {
- addDateWeatherView(viewIndex);
- viewIndex += 1;
- }
-
- addSmartspaceView(viewIndex);
- }
-
mSecureSettings.registerContentObserverForUser(
Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK,
false, /* notifyForDescendants */
@@ -274,13 +258,27 @@
mShowWeatherObserver,
UserHandle.USER_ALL
);
-
updateDoubleLineClock();
- setDateWeatherVisibility();
- setWeatherVisibility();
mKeyguardUnlockAnimationController.addKeyguardUnlockAnimationListener(
mKeyguardUnlockAnimationListener);
+
+ if (mSmartspaceController.isEnabled()) {
+ View ksv = mView.findViewById(R.id.keyguard_slice_view);
+ int viewIndex = mStatusArea.indexOfChild(ksv);
+ ksv.setVisibility(View.GONE);
+
+ mSmartspaceController.removeViewsFromParent(mStatusArea);
+ addSmartspaceView();
+ // TODO(b/261757708): add content observer for the Settings toggle and add/remove
+ // weather according to the Settings.
+ if (mSmartspaceController.isDateWeatherDecoupled()) {
+ addDateWeatherView();
+ }
+ }
+
+ setDateWeatherVisibility();
+ setWeatherVisibility();
}
int getNotificationIconAreaHeight() {
@@ -301,29 +299,22 @@
void onLocaleListChanged() {
if (mSmartspaceController.isEnabled()) {
+ mSmartspaceController.removeViewsFromParent(mStatusArea);
+ addSmartspaceView();
if (mSmartspaceController.isDateWeatherDecoupled()) {
mDateWeatherView.removeView(mWeatherView);
- int index = mStatusArea.indexOfChild(mDateWeatherView);
- if (index >= 0) {
- mStatusArea.removeView(mDateWeatherView);
- addDateWeatherView(index);
- }
+ addDateWeatherView();
setDateWeatherVisibility();
setWeatherVisibility();
}
- int index = mStatusArea.indexOfChild(mSmartspaceView);
- if (index >= 0) {
- mStatusArea.removeView(mSmartspaceView);
- addSmartspaceView(index);
- }
}
}
- private void addDateWeatherView(int index) {
+ private void addDateWeatherView() {
mDateWeatherView = (ViewGroup) mSmartspaceController.buildAndConnectDateView(mView);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
MATCH_PARENT, WRAP_CONTENT);
- mStatusArea.addView(mDateWeatherView, index, lp);
+ mStatusArea.addView(mDateWeatherView, 0, lp);
int startPadding = getContext().getResources().getDimensionPixelSize(
R.dimen.below_clock_padding_start);
int endPadding = getContext().getResources().getDimensionPixelSize(
@@ -343,11 +334,11 @@
mWeatherView.setPaddingRelative(0, 0, 4, 0);
}
- private void addSmartspaceView(int index) {
+ private void addSmartspaceView() {
mSmartspaceView = mSmartspaceController.buildAndConnectView(mView);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
MATCH_PARENT, WRAP_CONTENT);
- mStatusArea.addView(mSmartspaceView, index, lp);
+ mStatusArea.addView(mSmartspaceView, 0, lp);
int startPadding = getContext().getResources().getDimensionPixelSize(
R.dimen.below_clock_padding_start);
int endPadding = getContext().getResources().getDimensionPixelSize(
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index 8e92941..73b4c5f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -150,7 +150,8 @@
@Override
public void onInit() {
mKeyguardClockSwitchController.init();
- mDumpManager.registerDumpable(this);
+
+ mDumpManager.registerDumpable(getInstanceName(), this);
if (mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
startCoroutines(EmptyCoroutineContext.INSTANCE);
}
@@ -190,7 +191,7 @@
* Called in notificationPanelViewController to avoid leak
*/
public void onDestroy() {
- mDumpManager.unregisterDumpable(TAG);
+ mDumpManager.unregisterDumpable(getInstanceName());
}
/**
@@ -385,7 +386,7 @@
* Updates the alignment of the KeyguardStatusView and animates the transition if requested.
*/
public void updateAlignment(
- ConstraintLayout notifContainerParent,
+ ConstraintLayout layout,
boolean splitShadeEnabled,
boolean shouldBeCentered,
boolean animate) {
@@ -395,16 +396,23 @@
}
mStatusViewCentered = shouldBeCentered;
- if (notifContainerParent == null) {
+ if (layout == null) {
return;
}
ConstraintSet constraintSet = new ConstraintSet();
- constraintSet.clone(notifContainerParent);
- int statusConstraint = shouldBeCentered ? PARENT_ID : R.id.qs_edge_guideline;
+ constraintSet.clone(layout);
+ int guideline;
+ if (mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
+ guideline = R.id.split_shade_guideline;
+ } else {
+ guideline = R.id.qs_edge_guideline;
+ }
+
+ int statusConstraint = shouldBeCentered ? PARENT_ID : guideline;
constraintSet.connect(R.id.keyguard_status_view, END, statusConstraint, END);
if (!animate) {
- constraintSet.applyTo(notifContainerParent);
+ constraintSet.applyTo(layout);
return;
}
@@ -447,7 +455,7 @@
// old animation rather than setting up the custom animations.
if (clockContainerView == null || clockContainerView.getChildCount() == 0) {
transition.addListener(mKeyguardStatusAlignmentTransitionListener);
- TransitionManager.beginDelayedTransition(notifContainerParent, transition);
+ TransitionManager.beginDelayedTransition(layout, transition);
} else {
View clockView = clockContainerView.getChildAt(0);
@@ -481,14 +489,14 @@
}
set.addListener(mKeyguardStatusAlignmentTransitionListener);
- TransitionManager.beginDelayedTransition(notifContainerParent, set);
+ TransitionManager.beginDelayedTransition(layout, set);
}
} else {
transition.addListener(mKeyguardStatusAlignmentTransitionListener);
- TransitionManager.beginDelayedTransition(notifContainerParent, transition);
+ TransitionManager.beginDelayedTransition(layout, transition);
}
- constraintSet.applyTo(notifContainerParent);
+ constraintSet.applyTo(layout);
}
@Override
@@ -496,6 +504,10 @@
mView.dump(pw, args);
}
+ String getInstanceName() {
+ return TAG + "#" + hashCode();
+ }
+
@VisibleForTesting
static class SplitShadeTransitionAdapter extends Transition {
private static final String PROP_BOUNDS_LEFT = "splitShadeTransitionAdapter:boundsLeft";
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
index 6213265c..dffc19d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
@@ -20,6 +20,8 @@
import android.content.res.Configuration
import android.view.View
import android.view.ViewGroup
+import com.android.keyguard.KeyguardStatusViewController
+import com.android.keyguard.dagger.KeyguardStatusViewComponent
import com.android.systemui.CoreStartable
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
@@ -80,6 +82,7 @@
private val chipbarCoordinator: ChipbarCoordinator,
private val keyguardBlueprintCommandListener: KeyguardBlueprintCommandListener,
private val keyguardBlueprintViewModel: KeyguardBlueprintViewModel,
+ private val keyguardStatusViewComponentFactory: KeyguardStatusViewComponent.Factory,
) : CoreStartable {
private var rootViewHandle: DisposableHandle? = null
@@ -88,6 +91,7 @@
private var rightShortcutHandle: KeyguardQuickAffordanceViewBinder.Binding? = null
private var ambientIndicationAreaHandle: KeyguardAmbientIndicationAreaViewBinder.Binding? = null
private var settingsPopupMenuHandle: DisposableHandle? = null
+ private var keyguardStatusViewController: KeyguardStatusViewController? = null
override fun start() {
bindKeyguardRootView()
@@ -96,6 +100,7 @@
unbindKeyguardBottomArea(notificationPanel)
bindIndicationArea()
bindLockIconView(notificationPanel)
+ bindKeyguardStatusView(notificationPanel)
setupNotificationStackScrollLayout(notificationPanel)
bindLeftShortcut()
bindRightShortcut()
@@ -117,7 +122,7 @@
sharedNotificationContainer.addNotificationStackScrollLayout(nssl)
SharedNotificationContainerBinder.bind(
sharedNotificationContainer,
- sharedNotificationContainerViewModel
+ sharedNotificationContainerViewModel,
)
}
}
@@ -255,4 +260,31 @@
}
}
}
+
+ fun bindKeyguardStatusView(legacyParent: ViewGroup) {
+ // At startup, 2 views with the ID `R.id.keyguard_status_view` will be available.
+ // Disable one of them
+ if (featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
+ legacyParent.findViewById<View>(R.id.keyguard_status_view)?.let {
+ legacyParent.removeView(it)
+ }
+
+ val keyguardStatusView = keyguardRootView.addStatusView()
+ val statusViewComponent = keyguardStatusViewComponentFactory.build(keyguardStatusView)
+ val controller = statusViewComponent.getKeyguardStatusViewController()
+ controller.init()
+ keyguardStatusViewController = controller
+ } else {
+ keyguardRootView.findViewById<View?>(R.id.keyguard_status_view)?.let {
+ keyguardRootView.removeView(it)
+ }
+ }
+ }
+
+ /**
+ * Temporary, to allow NotificationPanelViewController to use the same instance while code is
+ * migrated: b/288242803
+ */
+ fun getKeyguardStatusViewController() = keyguardStatusViewController
+ fun getKeyguardRootView() = keyguardRootView
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
index f1b3441..e35c369 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
@@ -199,13 +199,16 @@
fun setAnimateDozingTransitions(animate: Boolean)
/** Sets the current amount of alpha that should be used for rendering the bottom area. */
- @Deprecated("Deprecated as part of b/278057014")
- fun setBottomAreaAlpha(alpha: Float)
+ @Deprecated("Deprecated as part of b/278057014") fun setBottomAreaAlpha(alpha: Float)
/** Sets the current amount of alpha that should be used for rendering the keyguard. */
fun setKeyguardAlpha(alpha: Float)
- fun setKeyguardVisibility(statusBarState: Int, goingToFullShade: Boolean, occlusionTransitionRunning: Boolean)
+ fun setKeyguardVisibility(
+ statusBarState: Int,
+ goingToFullShade: Boolean,
+ occlusionTransitionRunning: Boolean
+ )
/**
* Sets the relative offset of the lock-screen clock from its natural position on the screen.
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt
index e60901f..a948741 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt
@@ -24,6 +24,7 @@
import android.widget.ImageView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.res.ResourcesCompat
+import com.android.keyguard.KeyguardStatusView
import com.android.keyguard.LockIconView
import com.android.systemui.R
import com.android.systemui.animation.view.LaunchableImageView
@@ -38,6 +39,8 @@
attrs,
) {
+ private var statusView: KeyguardStatusView? = null
+
init {
addIndicationTextArea()
addLockIconView()
@@ -45,6 +48,7 @@
addLeftShortcut()
addRightShortcut()
addSettingsPopupMenu()
+ addStatusView()
}
private fun addIndicationTextArea() {
@@ -119,4 +123,19 @@
}
addView(view)
}
+
+ fun addStatusView(): KeyguardStatusView {
+ // StatusView may need to be rebuilt on config changes. Remove and reinflate
+ statusView?.let { removeView(it) }
+ val view =
+ (LayoutInflater.from(context).inflate(R.layout.keyguard_status_view, this, false)
+ as KeyguardStatusView)
+ .apply {
+ setClipChildren(false)
+ statusView = this
+ }
+
+ addView(view)
+ return view
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt
index 5538fe7..518df07 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt
@@ -25,6 +25,8 @@
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultLockIconSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultSettingsPopupMenuSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultShortcutsSection
+import com.android.systemui.keyguard.ui.view.layout.sections.DefaultStatusViewSection
+import com.android.systemui.keyguard.ui.view.layout.sections.SplitShadeGuidelines
import javax.inject.Inject
/**
@@ -42,6 +44,8 @@
private val defaultShortcutsSection: DefaultShortcutsSection,
private val defaultAmbientIndicationAreaSection: DefaultAmbientIndicationAreaSection,
private val defaultSettingsPopupMenuSection: DefaultSettingsPopupMenuSection,
+ private val defaultStatusViewSection: DefaultStatusViewSection,
+ private val splitShadeGuidelines: SplitShadeGuidelines,
) : KeyguardBlueprint {
override val id: String = DEFAULT
@@ -51,6 +55,8 @@
defaultShortcutsSection.apply(constraintSet)
defaultAmbientIndicationAreaSection.apply(constraintSet)
defaultSettingsPopupMenuSection.apply(constraintSet)
+ defaultStatusViewSection.apply(constraintSet)
+ splitShadeGuidelines.apply(constraintSet)
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt
index 19410e4..54c2796 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt
@@ -27,6 +27,8 @@
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultLockIconSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultSettingsPopupMenuSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultShortcutsSection
+import com.android.systemui.keyguard.ui.view.layout.sections.DefaultStatusViewSection
+import com.android.systemui.keyguard.ui.view.layout.sections.SplitShadeGuidelines
import javax.inject.Inject
/** Vertically aligns the shortcuts with the udfps. */
@@ -41,6 +43,8 @@
private val defaultSettingsPopupMenuSection: DefaultSettingsPopupMenuSection,
private val alignShortcutsToUdfpsSection: AlignShortcutsToUdfpsSection,
private val defaultShortcutsSection: DefaultShortcutsSection,
+ private val defaultStatusViewSection: DefaultStatusViewSection,
+ private val splitShadeGuidelines: SplitShadeGuidelines,
) : KeyguardBlueprint {
override val id: String = SHORTCUTS_BESIDE_UDFPS
@@ -54,6 +58,8 @@
} else {
defaultShortcutsSection.apply(constraintSet)
}
+ defaultStatusViewSection.apply(constraintSet)
+ splitShadeGuidelines.apply(constraintSet)
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt
new file mode 100644
index 0000000..3f319ba
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 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.keyguard.ui.view.layout.sections
+
+import android.content.Context
+import android.view.ViewGroup
+import androidx.constraintlayout.widget.ConstraintSet
+import com.android.systemui.R
+import com.android.systemui.keyguard.data.repository.KeyguardSection
+import javax.inject.Inject
+import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
+import androidx.constraintlayout.widget.ConstraintSet.MATCH_CONSTRAINT
+import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
+import androidx.constraintlayout.widget.ConstraintSet.START
+import androidx.constraintlayout.widget.ConstraintSet.TOP
+import androidx.constraintlayout.widget.ConstraintSet.END
+
+class DefaultStatusViewSection @Inject constructor(private val context: Context) :
+ KeyguardSection {
+ private val statusViewId = R.id.keyguard_status_view
+
+ override fun apply(constraintSet: ConstraintSet) {
+ constraintSet.apply {
+ constrainWidth(statusViewId, MATCH_CONSTRAINT)
+ constrainHeight(statusViewId, WRAP_CONTENT)
+ connect(statusViewId, TOP, PARENT_ID, TOP)
+ connect(statusViewId, START, PARENT_ID, START)
+ connect(statusViewId, END, PARENT_ID, END)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeGuidelines.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeGuidelines.kt
new file mode 100644
index 0000000..668b17f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeGuidelines.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 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.keyguard.ui.view.layout.sections
+
+import android.content.Context
+import android.view.ViewGroup
+import androidx.constraintlayout.widget.ConstraintSet
+import com.android.systemui.R
+import com.android.systemui.keyguard.data.repository.KeyguardSection
+import javax.inject.Inject
+import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
+import androidx.constraintlayout.widget.ConstraintSet.MATCH_CONSTRAINT
+import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
+import androidx.constraintlayout.widget.ConstraintSet.START
+import androidx.constraintlayout.widget.ConstraintSet.TOP
+import androidx.constraintlayout.widget.ConstraintSet.END
+import androidx.constraintlayout.widget.ConstraintSet.VERTICAL
+
+class SplitShadeGuidelines @Inject constructor(private val context: Context) :
+ KeyguardSection {
+
+ override fun apply(constraintSet: ConstraintSet) {
+ constraintSet.apply {
+ // For use on large screens, it will provide a guideline vertically in the center to
+ // enable items to be aligned on the left or right sides
+ create(R.id.split_shade_guideline, VERTICAL)
+ setGuidelinePercent(R.id.split_shade_guideline, 0.5f)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 416f147..35fd98c 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -90,6 +90,8 @@
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
import com.android.app.animation.Interpolators;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
@@ -1053,10 +1055,7 @@
mKeyguardStatusBarViewController.init();
mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent);
- updateViewControllers(
- mView.findViewById(R.id.keyguard_status_view),
- userAvatarContainer,
- keyguardUserSwitcherView);
+ updateViewControllers(userAvatarContainer, keyguardUserSwitcherView);
mNotificationStackScrollLayoutController.setOnHeightChangedListener(
new NsslHeightChangedListener());
@@ -1218,18 +1217,31 @@
mQsController.loadDimens();
}
- private void updateViewControllers(KeyguardStatusView keyguardStatusView,
+ private void updateViewControllers(
FrameLayout userAvatarView,
KeyguardUserSwitcherView keyguardUserSwitcherView) {
+ // Re-associate the KeyguardStatusViewController
if (mKeyguardStatusViewController != null) {
mKeyguardStatusViewController.onDestroy();
}
- // Re-associate the KeyguardStatusViewController
- KeyguardStatusViewComponent statusViewComponent =
+
+ if (mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
+ // Need a shared controller until mKeyguardStatusViewController can be removed from
+ // here, due to important state being set in that controller. Rebind in order to pick
+ // up config changes
+ mKeyguardViewConfigurator.bindKeyguardStatusView(mView);
+ mKeyguardStatusViewController =
+ mKeyguardViewConfigurator.getKeyguardStatusViewController();
+ } else {
+ KeyguardStatusView keyguardStatusView = mView.getRootView().findViewById(
+ R.id.keyguard_status_view);
+ KeyguardStatusViewComponent statusViewComponent =
mKeyguardStatusViewComponentFactory.build(keyguardStatusView);
- mKeyguardStatusViewController = statusViewComponent.getKeyguardStatusViewController();
- mKeyguardStatusViewController.init();
+ mKeyguardStatusViewController = statusViewComponent.getKeyguardStatusViewController();
+ mKeyguardStatusViewController.init();
+ }
mKeyguardStatusViewController.setSplitShadeEnabled(mSplitShadeEnabled);
+
updateClockAppearance();
if (mKeyguardUserSwitcherController != null) {
@@ -1335,15 +1347,22 @@
void reInflateViews() {
debugLog("reInflateViews");
// Re-inflate the status view group.
- KeyguardStatusView keyguardStatusView =
- mNotificationContainerParent.findViewById(R.id.keyguard_status_view);
- int statusIndex = mNotificationContainerParent.indexOfChild(keyguardStatusView);
- mNotificationContainerParent.removeView(keyguardStatusView);
- keyguardStatusView = (KeyguardStatusView) mLayoutInflater.inflate(
- R.layout.keyguard_status_view, mNotificationContainerParent, false);
- mNotificationContainerParent.addView(keyguardStatusView, statusIndex);
- attachSplitShadeMediaPlayerContainer(
- keyguardStatusView.findViewById(R.id.status_view_media_container));
+ if (!mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
+ KeyguardStatusView keyguardStatusView =
+ mNotificationContainerParent.findViewById(R.id.keyguard_status_view);
+ int statusIndex = mNotificationContainerParent.indexOfChild(keyguardStatusView);
+ mNotificationContainerParent.removeView(keyguardStatusView);
+ keyguardStatusView = (KeyguardStatusView) mLayoutInflater.inflate(
+ R.layout.keyguard_status_view, mNotificationContainerParent, false);
+ mNotificationContainerParent.addView(keyguardStatusView, statusIndex);
+
+ attachSplitShadeMediaPlayerContainer(
+ keyguardStatusView.findViewById(R.id.status_view_media_container));
+ } else {
+ attachSplitShadeMediaPlayerContainer(
+ mKeyguardViewConfigurator.getKeyguardRootView()
+ .findViewById(R.id.status_view_media_container));
+ }
// we need to update KeyguardStatusView constraints after reinflating it
updateResources();
@@ -1369,8 +1388,7 @@
R.layout.keyguard_user_switcher /* layoutId */,
showKeyguardUserSwitcher /* enabled */);
- updateViewControllers(mView.findViewById(R.id.keyguard_status_view), userAvatarView,
- keyguardUserSwitcherView);
+ updateViewControllers(userAvatarView, keyguardUserSwitcherView);
if (!mFeatureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) {
// Update keyguard bottom area
@@ -1666,8 +1684,14 @@
private void updateKeyguardStatusViewAlignment(boolean animate) {
boolean shouldBeCentered = shouldKeyguardStatusViewBeCentered();
+ ConstraintLayout layout;
+ if (mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
+ layout = mKeyguardViewConfigurator.getKeyguardRootView();
+ } else {
+ layout = mNotificationContainerParent;
+ }
mKeyguardStatusViewController.updateAlignment(
- mNotificationContainerParent, mSplitShadeEnabled, shouldBeCentered, animate);
+ layout, mSplitShadeEnabled, shouldBeCentered, animate);
mKeyguardUnfoldTransition.ifPresent(t -> t.setStatusViewCentered(shouldBeCentered));
}
@@ -3390,7 +3414,6 @@
ipw.print("mPanelFlingOvershootAmount="); ipw.println(mPanelFlingOvershootAmount);
ipw.print("mLastGesturedOverExpansion="); ipw.println(mLastGesturedOverExpansion);
ipw.print("mIsSpringBackAnimation="); ipw.println(mIsSpringBackAnimation);
- ipw.print("mSplitShadeEnabled="); ipw.println(mSplitShadeEnabled);
ipw.print("mHintDistance="); ipw.println(mHintDistance);
ipw.print("mInitialOffsetOnTouch="); ipw.println(mInitialOffsetOnTouch);
ipw.print("mCollapsedAndHeadsUpOnDown="); ipw.println(mCollapsedAndHeadsUpOnDown);
@@ -3423,7 +3446,6 @@
ipw.print("mGestureWaitForTouchSlop="); ipw.println(mGestureWaitForTouchSlop);
ipw.print("mIgnoreXTouchSlop="); ipw.println(mIgnoreXTouchSlop);
ipw.print("mExpandLatencyTracking="); ipw.println(mExpandLatencyTracking);
- ipw.print("mExpandLatencyTracking="); ipw.println(mExpandLatencyTracking);
ipw.println("gestureExclusionRect:" + calculateGestureExclusionRect());
new DumpsysTableLogger(
TAG,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
index 11b1053..903d485 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -445,6 +445,12 @@
session?.requestSmartspaceUpdate()
}
+ fun removeViewsFromParent(viewGroup: ViewGroup) {
+ smartspaceViews.toList().forEach {
+ viewGroup.removeView(it as View)
+ }
+ }
+
/**
* Disconnects the smartspace view from the smartspace service and cleans up any resources.
*/
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java
index ac04bc4..98d4d22 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java
@@ -23,6 +23,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -157,6 +158,12 @@
when(mSmartspaceController.buildAndConnectDateView(any())).thenReturn(mFakeDateView);
when(mSmartspaceController.buildAndConnectWeatherView(any())).thenReturn(mFakeWeatherView);
when(mSmartspaceController.buildAndConnectView(any())).thenReturn(mFakeSmartspaceView);
+ doAnswer(invocation -> {
+ removeView(mFakeDateView);
+ removeView(mFakeWeatherView);
+ removeView(mFakeSmartspaceView);
+ return null;
+ }).when(mSmartspaceController).removeViewsFromParent(any());
mExecutor = new FakeExecutor(new FakeSystemClock());
mFakeFeatureFlags = new FakeFeatureFlags();
mFakeFeatureFlags.set(FACE_AUTH_REFACTOR, false);
@@ -201,6 +208,13 @@
when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(mStatusArea);
}
+ private void removeView(View v) {
+ ViewGroup group = ((ViewGroup) v.getParent());
+ if (group != null) {
+ group.removeView(v);
+ }
+ }
+
protected void init() {
mController.init();
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
index 20d9ef1..7d23c80 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
@@ -16,6 +16,7 @@
package com.android.keyguard;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -119,8 +120,8 @@
@Test
public void correctlyDump() {
mController.onInit();
- verify(mDumpManager).registerDumpable(mController);
+ verify(mDumpManager).registerDumpable(eq(mController.getInstanceName()), eq(mController));
mController.onDestroy();
- verify(mDumpManager, times(1)).unregisterDumpable(KeyguardStatusViewController.TAG);
+ verify(mDumpManager, times(1)).unregisterDumpable(eq(mController.getInstanceName()));
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt
index 66631dc..addb181 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt
@@ -17,6 +17,8 @@
package com.android.systemui.keyguard.ui.view.layout.blueprints
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
import androidx.constraintlayout.widget.ConstraintSet
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -26,15 +28,17 @@
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultLockIconSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultSettingsPopupMenuSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultShortcutsSection
+import com.android.systemui.keyguard.ui.view.layout.sections.DefaultStatusViewSection
+import com.android.systemui.keyguard.ui.view.layout.sections.SplitShadeGuidelines
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
-@RunWith(JUnit4::class)
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
@SmallTest
class DefaultKeyguardBlueprintTest : SysuiTestCase() {
private lateinit var underTest: DefaultKeyguardBlueprint
@@ -45,6 +49,8 @@
@Mock
private lateinit var defaultAmbientIndicationAreaSection: DefaultAmbientIndicationAreaSection
@Mock private lateinit var defaultSettingsPopupMenuSection: DefaultSettingsPopupMenuSection
+ @Mock private lateinit var defaultStatusViewSection: DefaultStatusViewSection
+ @Mock private lateinit var splitShadeGuidelines: SplitShadeGuidelines
@Before
fun setup() {
@@ -57,6 +63,8 @@
defaultShortcutsSection,
defaultAmbientIndicationAreaSection,
defaultSettingsPopupMenuSection,
+ defaultStatusViewSection,
+ splitShadeGuidelines,
)
}
@@ -69,5 +77,7 @@
verify(defaultShortcutsSection).apply(cs)
verify(defaultAmbientIndicationAreaSection).apply(cs)
verify(defaultSettingsPopupMenuSection).apply(cs)
+ verify(defaultStatusViewSection).apply(cs)
+ verify(splitShadeGuidelines).apply(cs)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSectionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSectionTest.kt
index 1444f8d..379c03c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSectionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSectionTest.kt
@@ -25,6 +25,7 @@
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.AuthController
+import com.android.systemui.keyguard.ui.view.KeyguardRootView
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index c3540cf..981e44b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -424,6 +424,10 @@
when(mView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame);
when(mView.findViewById(R.id.keyguard_status_view))
.thenReturn(mock(KeyguardStatusView.class));
+ View rootView = mock(View.class);
+ when(mView.getRootView()).thenReturn(rootView);
+ when(rootView.findViewById(R.id.keyguard_status_view))
+ .thenReturn(mock(KeyguardStatusView.class));
mNotificationContainerParent = new NotificationsQuickSettingsContainer(getContext(), null);
mNotificationContainerParent.addView(keyguardStatusView);
mNotificationContainerParent.onFinishInflate();
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
index 15ce055..faebcaa 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
@@ -146,7 +146,6 @@
_animateBottomAreaDozingTransitions.tryEmit(animate)
}
-
@Deprecated("Deprecated as part of b/278057014")
override fun setBottomAreaAlpha(alpha: Float) {
_bottomAreaAlpha.value = alpha
@@ -257,8 +256,11 @@
goingToFullShade: Boolean,
occlusionTransitionRunning: Boolean
) {
- _keyguardRootViewVisibility.value = KeyguardRootViewVisibilityState(
- statusBarState, goingToFullShade, occlusionTransitionRunning
- )
+ _keyguardRootViewVisibility.value =
+ KeyguardRootViewVisibilityState(
+ statusBarState,
+ goingToFullShade,
+ occlusionTransitionRunning
+ )
}
}