Merge "Reinflate silent notif header on config change" into qt-dev
diff --git a/packages/SystemUI/res/layout/status_bar_notification_section_header.xml b/packages/SystemUI/res/layout/status_bar_notification_section_header.xml
index eabc5c5..508619a 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_section_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_section_header.xml
@@ -22,6 +22,7 @@
android:focusable="true"
android:clickable="true"
>
+
<com.android.systemui.statusbar.notification.row.NotificationBackgroundView
android:id="@+id/backgroundNormal"
android:layout_width="match_parent"
@@ -38,28 +39,7 @@
android:gravity="center_vertical"
android:orientation="horizontal"
>
- <TextView
- android:id="@+id/header_label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:layout_marginStart="@dimen/notification_section_header_padding_left"
- android:gravity="start"
- android:textAlignment="gravity"
- android:text="@string/notification_section_header_gentle"
- android:textSize="12sp"
- android:textColor="@color/notification_section_header_label_color"
- android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
- />
- <ImageView
- android:id="@+id/btn_clear_all"
- android:layout_width="@dimen/notification_section_header_height"
- android:layout_height="@dimen/notification_section_header_height"
- android:layout_marginEnd="4dp"
- android:src="@drawable/status_bar_notification_section_header_clear_btn"
- android:contentDescription="@string/accessibility_notification_section_header_gentle_clear_all"
- android:scaleType="center"
- />
+ <include layout="@layout/status_bar_notification_section_header_contents"/>
</LinearLayout>
<com.android.systemui.statusbar.notification.FakeShadowView
diff --git a/packages/SystemUI/res/layout/status_bar_notification_section_header_contents.xml b/packages/SystemUI/res/layout/status_bar_notification_section_header_contents.xml
new file mode 100644
index 0000000..feabd1c
--- /dev/null
+++ b/packages/SystemUI/res/layout/status_bar_notification_section_header_contents.xml
@@ -0,0 +1,41 @@
+<!--
+ ~ Copyright (C) 2019 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
+ -->
+
+<!-- Used by both status_bar_notification_header and SectionHeaderView -->
+<merge xmlns:android="http://schemas.android.com/apk/res/android" >
+ <TextView
+ android:id="@+id/header_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_marginStart="@dimen/notification_section_header_padding_left"
+ android:gravity="start"
+ android:textAlignment="gravity"
+ android:text="@string/notification_section_header_gentle"
+ android:textSize="12sp"
+ android:textColor="@color/notification_section_header_label_color"
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+ />
+ <ImageView
+ android:id="@+id/btn_clear_all"
+ android:layout_width="@dimen/notification_section_header_height"
+ android:layout_height="@dimen/notification_section_header_height"
+ android:layout_marginEnd="4dp"
+ android:src="@drawable/status_bar_notification_section_header_clear_btn"
+ android:contentDescription="@string/accessibility_notification_section_header_gentle_clear_all"
+ android:scaleType="center"
+ />
+</merge>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java
index 5747bb1..170a4d5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java
@@ -19,7 +19,6 @@
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE;
import android.annotation.Nullable;
-import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import android.view.LayoutInflater;
@@ -32,6 +31,8 @@
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
/**
* Manages the boundaries of the two notification sections (high priority and low priority). Also
@@ -43,8 +44,10 @@
private final NotificationStackScrollLayout mParent;
private final ActivityStarter mActivityStarter;
private final StatusBarStateController mStatusBarStateController;
+ private final ConfigurationController mConfigurationController;
private final boolean mUseMultipleSections;
+ private boolean mInitialized = false;
private SectionHeaderView mGentleHeader;
private boolean mGentleHeaderVisible = false;
@Nullable private ExpandableNotificationRow mFirstGentleNotif;
@@ -54,18 +57,29 @@
NotificationStackScrollLayout parent,
ActivityStarter activityStarter,
StatusBarStateController statusBarStateController,
+ ConfigurationController configurationController,
boolean useMultipleSections) {
mParent = parent;
mActivityStarter = activityStarter;
mStatusBarStateController = statusBarStateController;
+ mConfigurationController = configurationController;
mUseMultipleSections = useMultipleSections;
}
+ /** Must be called before use. */
+ void initialize(LayoutInflater layoutInflater) {
+ if (mInitialized) {
+ throw new IllegalStateException("NotificationSectionsManager already initialized");
+ }
+ mInitialized = true;
+ reinflateViews(layoutInflater);
+ mConfigurationController.addCallback(mConfigurationListener);
+ }
+
/**
- * Must be called before use. Should be called again whenever inflation-related things change,
- * such as density or theme changes.
+ * Reinflates the entire notification header, including all decoration views.
*/
- void inflateViews(Context context) {
+ void reinflateViews(LayoutInflater layoutInflater) {
int oldPos = -1;
if (mGentleHeader != null) {
if (mGentleHeader.getTransientContainer() != null) {
@@ -76,7 +90,7 @@
}
}
- mGentleHeader = (SectionHeaderView) LayoutInflater.from(context).inflate(
+ mGentleHeader = (SectionHeaderView) layoutInflater.inflate(
R.layout.status_bar_notification_section_header, mParent, false);
mGentleHeader.setOnHeaderClickListener(this::onGentleHeaderClick);
mGentleHeader.setOnClearAllClickListener(this::onClearGentleNotifsClick);
@@ -244,6 +258,13 @@
return lastChildBeforeGap;
}
+ private final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
+ @Override
+ public void onLocaleListChanged() {
+ mGentleHeader.reinflateContents();
+ }
+ };
+
private void onGentleHeaderClick(View v) {
Intent intent = new Intent(Settings.ACTION_NOTIFICATION_SETTINGS);
mActivityStarter.startActivity(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index c214431..6e9fe67 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -32,7 +32,6 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.WallpaperManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
@@ -515,6 +514,7 @@
NotificationRoundnessManager notificationRoundnessManager,
AmbientPulseManager ambientPulseManager,
DynamicPrivacyController dynamicPrivacyController,
+ ConfigurationController configurationController,
ActivityStarter activityStarter,
StatusBarStateController statusBarStateController) {
super(context, attrs, 0, 0);
@@ -533,8 +533,9 @@
this,
activityStarter,
statusBarStateController,
+ configurationController,
NotificationUtils.useNewInterruptionModel(context));
- mSectionsManager.inflateViews(context);
+ mSectionsManager.initialize(LayoutInflater.from(context));
mSectionsManager.setOnClearGentleNotifsClickListener(v -> {
// Leave the shade open if there will be other notifs left over to clear
final boolean closeShade = !hasActiveClearableNotifications(ROWS_HIGH_PRIORITY);
@@ -648,7 +649,7 @@
inflateFooterView();
inflateEmptyShadeView();
updateFooter();
- mSectionsManager.inflateViews(mContext);
+ mSectionsManager.reinflateViews(LayoutInflater.from(mContext));
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java
index e2f702d..cc1170f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java
@@ -16,11 +16,16 @@
package com.android.systemui.statusbar.notification.stack;
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.annotation.Nullable;
import android.content.Context;
import android.graphics.RectF;
import android.util.AttributeSet;
+import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
@@ -32,9 +37,10 @@
* notification sections. Currently only used for gentle notifications.
*/
public class SectionHeaderView extends ActivatableNotificationView {
- private View mContents;
+ private ViewGroup mContents;
private TextView mLabelView;
private ImageView mClearAllButton;
+ @Nullable private View.OnClickListener mOnClearClickListener = null;
private final RectF mTmpRect = new RectF();
@@ -45,9 +51,16 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mContents = findViewById(R.id.content);
- mLabelView = findViewById(R.id.header_label);
- mClearAllButton = findViewById(R.id.btn_clear_all);
+ mContents = checkNotNull(findViewById(R.id.content));
+ bindContents();
+ }
+
+ private void bindContents() {
+ mLabelView = checkNotNull(findViewById(R.id.header_label));
+ mClearAllButton = checkNotNull(findViewById(R.id.btn_clear_all));
+ if (mOnClearClickListener != null) {
+ mClearAllButton.setOnClickListener(mOnClearClickListener);
+ }
}
@Override
@@ -55,6 +68,21 @@
return mContents;
}
+ /**
+ * Destroys and reinflates the visible contents of the section header. For use on configuration
+ * changes or any other time that layout values might need to be re-evaluated.
+ *
+ * Does not reinflate the base content view itself ({@link #getContentView()} or any of the
+ * decorator views, such as the background view or shadow view.
+ */
+ void reinflateContents() {
+ mContents.removeAllViews();
+ LayoutInflater.from(getContext()).inflate(
+ R.layout.status_bar_notification_section_header_contents,
+ mContents);
+ bindContents();
+ }
+
/** Must be called whenever the UI mode changes (i.e. when we enter night mode). */
void onUiModeChanged() {
updateBackgroundColors();
@@ -88,6 +116,7 @@
/** Fired when the user clicks on the "X" button on the far right of the header. */
void setOnClearAllClickListener(View.OnClickListener listener) {
+ mOnClearClickListener = listener;
mClearAllButton.setOnClickListener(listener);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
index b99958a..73abda9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
@@ -31,6 +31,7 @@
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.AttributeSet;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -41,6 +42,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import org.junit.Before;
import org.junit.Rule;
@@ -60,6 +62,7 @@
@Mock private NotificationStackScrollLayout mNssl;
@Mock private ActivityStarterDelegate mActivityStarterDelegate;
@Mock private StatusBarStateController mStatusBarStateController;
+ @Mock private ConfigurationController mConfigurationController;
private NotificationSectionsManager mSectionsManager;
@@ -70,15 +73,21 @@
mNssl,
mActivityStarterDelegate,
mStatusBarStateController,
+ mConfigurationController,
true);
// Required in order for the header inflation to work properly
when(mNssl.generateLayoutParams(any(AttributeSet.class)))
.thenReturn(new ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
- mSectionsManager.inflateViews(mContext);
+ mSectionsManager.initialize(LayoutInflater.from(mContext));
when(mNssl.indexOfChild(any(View.class))).thenReturn(-1);
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
}
+ @Test(expected = IllegalStateException.class)
+ public void testDuplicateInitializeThrows() {
+ mSectionsManager.initialize(LayoutInflater.from(mContext));
+ }
+
@Test
public void testInsertHeader() {
// GIVEN a stack with HI and LO rows but no section headers
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index d425982..9f49e89 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -75,6 +75,7 @@
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarTest.TestableNotificationEntryManager;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import org.junit.After;
import org.junit.Assert;
@@ -155,6 +156,7 @@
true /* allowLongPress */, mNotificationRoundnessManager,
new AmbientPulseManager(mContext),
mock(DynamicPrivacyController.class),
+ mock(ConfigurationController.class),
mock(ActivityStarterDelegate.class),
mock(StatusBarStateController.class));
mStackScroller = spy(mStackScrollerInternal);