diff --git a/packages/SettingsLib/BannerMessagePreference/Android.bp b/packages/SettingsLib/BannerMessagePreference/Android.bp
index 82e837bcd3acc..c6a95625a4148 100644
--- a/packages/SettingsLib/BannerMessagePreference/Android.bp
+++ b/packages/SettingsLib/BannerMessagePreference/Android.bp
@@ -14,9 +14,10 @@ android_library {
resource_dirs: ["res"],
static_libs: [
- "androidx.preference_preference",
+ "androidx.preference_preference",
+ "SettingsLibSettingsTheme",
],
sdk_version: "system_current",
- min_sdk_version: "21",
+ min_sdk_version: "28",
}
diff --git a/packages/SettingsLib/BannerMessagePreference/AndroidManifest.xml b/packages/SettingsLib/BannerMessagePreference/AndroidManifest.xml
index 56b886f7efb12..dd51ea38a1fef 100644
--- a/packages/SettingsLib/BannerMessagePreference/AndroidManifest.xml
+++ b/packages/SettingsLib/BannerMessagePreference/AndroidManifest.xml
@@ -18,6 +18,6 @@
-
+
diff --git a/packages/SettingsLib/BannerMessagePreference/lint-baseline.xml b/packages/SettingsLib/BannerMessagePreference/lint-baseline.xml
deleted file mode 100644
index ba02a1fae9e0d..0000000000000
--- a/packages/SettingsLib/BannerMessagePreference/lint-baseline.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/SettingsLib/BannerMessagePreference/res/drawable-v31/settingslib_card_background.xml b/packages/SettingsLib/BannerMessagePreference/res/drawable-v31/settingslib_card_background.xml
new file mode 100644
index 0000000000000..072eb5873ce52
--- /dev/null
+++ b/packages/SettingsLib/BannerMessagePreference/res/drawable-v31/settingslib_card_background.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/SettingsLib/BannerMessagePreference/res/drawable-v31/settingslib_ic_cross.xml b/packages/SettingsLib/BannerMessagePreference/res/drawable-v31/settingslib_ic_cross.xml
new file mode 100644
index 0000000000000..d926cc6e5a586
--- /dev/null
+++ b/packages/SettingsLib/BannerMessagePreference/res/drawable-v31/settingslib_ic_cross.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
diff --git a/packages/SettingsLib/BannerMessagePreference/res/layout-v31/settingslib_banner_message.xml b/packages/SettingsLib/BannerMessagePreference/res/layout-v31/settingslib_banner_message.xml
new file mode 100644
index 0000000000000..904b78c7f1656
--- /dev/null
+++ b/packages/SettingsLib/BannerMessagePreference/res/layout-v31/settingslib_banner_message.xml
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/SettingsLib/BannerMessagePreference/res/layout/banner_message.xml b/packages/SettingsLib/BannerMessagePreference/res/layout/settingslib_banner_message.xml
similarity index 81%
rename from packages/SettingsLib/BannerMessagePreference/res/layout/banner_message.xml
rename to packages/SettingsLib/BannerMessagePreference/res/layout/settingslib_banner_message.xml
index 977e19687960c..80cb1d5f244a7 100644
--- a/packages/SettingsLib/BannerMessagePreference/res/layout/banner_message.xml
+++ b/packages/SettingsLib/BannerMessagePreference/res/layout/settingslib_banner_message.xml
@@ -30,8 +30,10 @@
android:orientation="horizontal">
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/SettingsLib/BannerMessagePreference/res/values-night/colors.xml b/packages/SettingsLib/BannerMessagePreference/res/values-night/colors.xml
new file mode 100644
index 0000000000000..50141a8b63bdd
--- /dev/null
+++ b/packages/SettingsLib/BannerMessagePreference/res/values-night/colors.xml
@@ -0,0 +1,25 @@
+
+
+
+
+ #3B2D2C
+ #333121
+ #2B3328
+ #F28B82
+ #FDD663
+ #81C995
+
diff --git a/packages/SettingsLib/BannerMessagePreference/res/values-v31/styles.xml b/packages/SettingsLib/BannerMessagePreference/res/values-v31/styles.xml
new file mode 100644
index 0000000000000..a39e77969c40d
--- /dev/null
+++ b/packages/SettingsLib/BannerMessagePreference/res/values-v31/styles.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/SettingsLib/BannerMessagePreference/res/values/attrs.xml b/packages/SettingsLib/BannerMessagePreference/res/values/attrs.xml
new file mode 100644
index 0000000000000..96634a51de56e
--- /dev/null
+++ b/packages/SettingsLib/BannerMessagePreference/res/values/attrs.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/SettingsLib/BannerMessagePreference/res/values/colors.xml b/packages/SettingsLib/BannerMessagePreference/res/values/colors.xml
new file mode 100644
index 0000000000000..53d72d1eeff79
--- /dev/null
+++ b/packages/SettingsLib/BannerMessagePreference/res/values/colors.xml
@@ -0,0 +1,25 @@
+
+
+
+
+ #FFDAD5
+ #F0E3A8
+ #CFEBC0
+ #BB3322
+ #895900
+ #1D7233
+
diff --git a/packages/SettingsLib/BannerMessagePreference/res/values/strings.xml b/packages/SettingsLib/BannerMessagePreference/res/values/strings.xml
new file mode 100644
index 0000000000000..a1af38a2bd38c
--- /dev/null
+++ b/packages/SettingsLib/BannerMessagePreference/res/values/strings.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+ Dismiss
+
+
+
diff --git a/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java b/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java
index 5352552d7c66a..5bedd7a188905 100644
--- a/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java
+++ b/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java
@@ -17,13 +17,25 @@
package com.android.settingslib.widget;
import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.ImageView;
import android.widget.TextView;
+import androidx.annotation.ColorInt;
+import androidx.annotation.ColorRes;
+import androidx.annotation.RequiresApi;
import androidx.annotation.StringRes;
+import androidx.core.os.BuildCompat;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
@@ -33,55 +45,151 @@ import androidx.preference.PreferenceViewHolder;
*/
public class BannerMessagePreference extends Preference {
+ public enum AttentionLevel {
+ HIGH(0, R.color.banner_background_attention_high, R.color.banner_accent_attention_high),
+ MEDIUM(1,
+ R.color.banner_background_attention_medium,
+ R.color.banner_accent_attention_medium),
+ LOW(2, R.color.banner_background_attention_low, R.color.banner_accent_attention_low);
+
+ // Corresponds to the enum valye of R.attr.attentionLevel
+ private final int mAttrValue;
+ @ColorRes private final int mBackgroundColorResId;
+ @ColorRes private final int mAccentColorResId;
+
+ AttentionLevel(int attrValue, @ColorRes int backgroundColorResId,
+ @ColorRes int accentColorResId) {
+ mAttrValue = attrValue;
+ mBackgroundColorResId = backgroundColorResId;
+ mAccentColorResId = accentColorResId;
+ }
+
+ static AttentionLevel fromAttr(int attrValue) {
+ for (AttentionLevel level : values()) {
+ if (level.mAttrValue == attrValue) {
+ return level;
+ }
+ }
+ throw new IllegalArgumentException();
+ }
+
+ @ColorRes int getAccentColorResId() {
+ return mAccentColorResId;
+ }
+
+ @ColorRes int getBackgroundColorResId() {
+ return mBackgroundColorResId;
+ }
+ }
+
private static final String TAG = "BannerPreference";
- private BannerMessagePreference.ButtonInfo mPositiveButtonInfo;
- private BannerMessagePreference.ButtonInfo mNegativeButtonInfo;
+ private static final boolean IS_AT_LEAST_S = BuildCompat.isAtLeastS();
+
+ private final BannerMessagePreference.ButtonInfo mPositiveButtonInfo =
+ new BannerMessagePreference.ButtonInfo();
+ private final BannerMessagePreference.ButtonInfo mNegativeButtonInfo =
+ new BannerMessagePreference.ButtonInfo();
+ private final BannerMessagePreference.DismissButtonInfo mDismissButtonInfo =
+ new BannerMessagePreference.DismissButtonInfo();
+
+ // Default attention level is High.
+ private AttentionLevel mAttentionLevel = AttentionLevel.HIGH;
+ private String mSubtitle;
public BannerMessagePreference(Context context) {
super(context);
- init();
+ init(context, null /* attrs */);
}
public BannerMessagePreference(Context context, AttributeSet attrs) {
super(context, attrs);
- init();
+ init(context, attrs);
}
public BannerMessagePreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- init();
+ init(context, attrs);
}
public BannerMessagePreference(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- init();
+ init(context, attrs);
+ }
+
+ private void init(Context context, AttributeSet attrs) {
+ setSelectable(false);
+ setLayoutResource(R.layout.settingslib_banner_message);
+
+ if (IS_AT_LEAST_S) {
+ if (attrs != null) {
+ // Get attention level and subtitle from layout XML
+ TypedArray a =
+ context.obtainStyledAttributes(attrs, R.styleable.BannerMessagePreference);
+ int mAttentionLevelValue =
+ a.getInt(R.styleable.BannerMessagePreference_attentionLevel, 0);
+ mAttentionLevel = AttentionLevel.fromAttr(mAttentionLevelValue);
+ mSubtitle = a.getString(R.styleable.BannerMessagePreference_subtitle);
+ a.recycle();
+ }
+ }
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
- holder.setDividerAllowedAbove(true);
- holder.setDividerAllowedBelow(true);
+ final Context context = getContext();
+
+ final TextView titleView = (TextView) holder.findViewById(R.id.banner_title);
+ CharSequence title = getTitle();
+ titleView.setText(title);
+ titleView.setVisibility(title == null ? View.GONE : View.VISIBLE);
+
+ final TextView summaryView = (TextView) holder.findViewById(R.id.banner_summary);
+ summaryView.setText(getSummary());
mPositiveButtonInfo.mButton = (Button) holder.findViewById(R.id.banner_positive_btn);
mNegativeButtonInfo.mButton = (Button) holder.findViewById(R.id.banner_negative_btn);
+ if (IS_AT_LEAST_S) {
+ final Resources.Theme theme = context.getTheme();
+ @ColorInt final int accentColor =
+ context.getResources().getColor(mAttentionLevel.getAccentColorResId(), theme);
+ @ColorInt final int backgroundColor =
+ context.getResources().getColor(
+ mAttentionLevel.getBackgroundColorResId(), theme);
+
+ holder.setDividerAllowedAbove(false);
+ holder.setDividerAllowedBelow(false);
+ holder.itemView.getBackground().setTint(backgroundColor);
+
+ mPositiveButtonInfo.mColor = accentColor;
+ mNegativeButtonInfo.mColor = accentColor;
+
+ mDismissButtonInfo.mButton = (ImageButton) holder.findViewById(R.id.banner_dismiss_btn);
+ mDismissButtonInfo.setUpButton();
+
+ final TextView subtitleView = (TextView) holder.findViewById(R.id.banner_subtitle);
+ subtitleView.setText(mSubtitle);
+ subtitleView.setVisibility(mSubtitle == null ? View.GONE : View.VISIBLE);
+
+ final ImageView iconView = (ImageView) holder.findViewById(R.id.banner_icon);
+ if (iconView != null) {
+ Drawable icon = getIcon();
+ iconView.setImageDrawable(
+ icon == null
+ ? getContext().getDrawable(R.drawable.ic_warning)
+ : icon);
+ iconView.setColorFilter(
+ new PorterDuffColorFilter(accentColor, PorterDuff.Mode.SRC_IN));
+ }
+ } else {
+ holder.setDividerAllowedAbove(true);
+ holder.setDividerAllowedBelow(true);
+ }
+
mPositiveButtonInfo.setUpButton();
mNegativeButtonInfo.setUpButton();
-
- final TextView titleView = (TextView) holder.findViewById(R.id.banner_title);
- final TextView summaryView = (TextView) holder.findViewById(R.id.banner_summary);
-
- titleView.setText(getTitle());
- summaryView.setText(getSummary());
- }
-
- private void init() {
- mPositiveButtonInfo = new BannerMessagePreference.ButtonInfo();
- mNegativeButtonInfo = new BannerMessagePreference.ButtonInfo();
- setSelectable(false);
- setLayoutResource(R.layout.banner_message);
}
/**
@@ -106,6 +214,18 @@ public class BannerMessagePreference extends Preference {
return this;
}
+ /**
+ * Set the visibility state of dismiss button.
+ */
+ @RequiresApi(Build.VERSION_CODES.S)
+ public BannerMessagePreference setDismissButtonVisible(boolean isVisible) {
+ if (isVisible != mDismissButtonInfo.mIsVisible) {
+ mDismissButtonInfo.mIsVisible = isVisible;
+ notifyChanged();
+ }
+ return this;
+ }
+
/**
* Register a callback to be invoked when positive button is clicked.
*/
@@ -130,13 +250,32 @@ public class BannerMessagePreference extends Preference {
return this;
}
+ /**
+ * Register a callback to be invoked when the dismiss button is clicked.
+ */
+ @RequiresApi(Build.VERSION_CODES.S)
+ public BannerMessagePreference setDismissButtonOnClickListener(
+ View.OnClickListener listener) {
+ if (listener != mDismissButtonInfo.mListener) {
+ mDismissButtonInfo.mListener = listener;
+ notifyChanged();
+ }
+ return this;
+ }
+
/**
* Sets the text to be displayed in positive button.
*/
public BannerMessagePreference setPositiveButtonText(@StringRes int textResId) {
- final String newText = getContext().getString(textResId);
- if (!TextUtils.equals(newText, mPositiveButtonInfo.mText)) {
- mPositiveButtonInfo.mText = newText;
+ return setPositiveButtonText(getContext().getString(textResId));
+ }
+
+ /**
+ * Sets the text to be displayed in positive button.
+ */
+ public BannerMessagePreference setPositiveButtonText(String positiveButtonText) {
+ if (!TextUtils.equals(positiveButtonText, mPositiveButtonInfo.mText)) {
+ mPositiveButtonInfo.mText = positiveButtonText;
notifyChanged();
}
return this;
@@ -146,9 +285,51 @@ public class BannerMessagePreference extends Preference {
* Sets the text to be displayed in negative button.
*/
public BannerMessagePreference setNegativeButtonText(@StringRes int textResId) {
- final String newText = getContext().getString(textResId);
- if (!TextUtils.equals(newText, mNegativeButtonInfo.mText)) {
- mNegativeButtonInfo.mText = newText;
+ return setNegativeButtonText(getContext().getString(textResId));
+ }
+
+ /**
+ * Sets the text to be displayed in negative button.
+ */
+ public BannerMessagePreference setNegativeButtonText(String negativeButtonText) {
+ if (!TextUtils.equals(negativeButtonText, mNegativeButtonInfo.mText)) {
+ mNegativeButtonInfo.mText = negativeButtonText;
+ notifyChanged();
+ }
+ return this;
+ }
+
+ /**
+ * Sets the subtitle.
+ */
+ @RequiresApi(Build.VERSION_CODES.S)
+ public BannerMessagePreference setSubtitle(@StringRes int textResId) {
+ return setSubtitle(getContext().getString(textResId));
+ }
+
+ /**
+ * Sets the subtitle.
+ */
+ @RequiresApi(Build.VERSION_CODES.S)
+ public BannerMessagePreference setSubtitle(String subtitle) {
+ if (!TextUtils.equals(subtitle, mSubtitle)) {
+ mSubtitle = subtitle;
+ notifyChanged();
+ }
+ return this;
+ }
+
+ /**
+ * Sets the attention level. This will update the color theme of the preference.
+ */
+ @RequiresApi(Build.VERSION_CODES.S)
+ public BannerMessagePreference setAttentionLevel(AttentionLevel attentionLevel) {
+ if (attentionLevel == mAttentionLevel) {
+ return this;
+ }
+
+ if (attentionLevel != null) {
+ mAttentionLevel = attentionLevel;
notifyChanged();
}
return this;
@@ -159,11 +340,16 @@ public class BannerMessagePreference extends Preference {
private CharSequence mText;
private View.OnClickListener mListener;
private boolean mIsVisible = true;
+ @ColorInt private int mColor;
void setUpButton() {
mButton.setText(mText);
mButton.setOnClickListener(mListener);
+ if (IS_AT_LEAST_S) {
+ mButton.setTextColor(mColor);
+ }
+
if (shouldBeVisible()) {
mButton.setVisibility(View.VISIBLE);
} else {
@@ -179,4 +365,26 @@ public class BannerMessagePreference extends Preference {
return mIsVisible && (!TextUtils.isEmpty(mText));
}
}
+
+ static class DismissButtonInfo {
+ private ImageButton mButton;
+ private View.OnClickListener mListener;
+ private boolean mIsVisible = true;
+
+ void setUpButton() {
+ mButton.setOnClickListener(mListener);
+ if (shouldBeVisible()) {
+ mButton.setVisibility(View.VISIBLE);
+ } else {
+ mButton.setVisibility(View.GONE);
+ }
+ }
+
+ /**
+ * By default, dismiss button is visible if it has a click listener.
+ */
+ private boolean shouldBeVisible() {
+ return mIsVisible && (mListener != null);
+ }
+ }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java
index 8ab02983bfc25..6670ed307816c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java
@@ -18,18 +18,35 @@ package com.android.settingslib.widget;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
import android.content.Context;
+import android.graphics.ColorFilter;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.ImageView;
import android.widget.TextView;
+import androidx.annotation.ColorRes;
import androidx.preference.PreferenceViewHolder;
+import androidx.preference.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.Shadows;
+import org.robolectric.shadows.ShadowDrawable;
+import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
public class BannerMessagePreferenceTest {
@@ -39,16 +56,22 @@ public class BannerMessagePreferenceTest {
private BannerMessagePreference mBannerPreference;
private PreferenceViewHolder mHolder;
+ private boolean mClickListenerCalled = false;
+ private final View.OnClickListener mClickListener = v -> mClickListenerCalled = true;
+
+ private static final int TEST_STRING_RES_ID =
+ R.string.accessibility_banner_message_dismiss;
+
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
- mRootView = View.inflate(mContext, R.layout.banner_message, null /* parent */);
- mHolder = PreferenceViewHolder.createInstanceForTests(mRootView);
+ mClickListenerCalled = false;
mBannerPreference = new BannerMessagePreference(mContext);
+ setUpViewHolder();
}
@Test
- public void onBindViewHolder_shouldSetTitle() {
+ public void onBindViewHolder_whenTitleSet_shouldSetTitle() {
mBannerPreference.setTitle("test");
mBannerPreference.onBindViewHolder(mHolder);
@@ -58,7 +81,7 @@ public class BannerMessagePreferenceTest {
}
@Test
- public void onBindViewHolder_shouldSetSummary() {
+ public void onBindViewHolder_whenSummarySet_shouldSetSummary() {
mBannerPreference.setSummary("test");
mBannerPreference.onBindViewHolder(mHolder);
@@ -68,30 +91,114 @@ public class BannerMessagePreferenceTest {
}
@Test
- public void setPositiveButtonText_shouldShowPositiveButton() {
- mBannerPreference.setPositiveButtonText(R.string.tts_settings_title);
+ public void onBindViewHolder_whenPreS_shouldBindView() {
+ assumeAndroidR();
+ mBannerPreference.setSummary("test");
mBannerPreference.onBindViewHolder(mHolder);
- assertThat(((Button) mRootView.findViewById(R.id.banner_positive_btn)).getVisibility())
- .isEqualTo(View.VISIBLE);
+ assertThat(((TextView) mRootView.findViewById(R.id.banner_summary)).getText())
+ .isEqualTo("test");
+ }
+
+ @Test
+ public void onBindViewHolder_whenAtLeastS_whenSubtitleSetByString_shouldSetSubtitle() {
+ assumeAndroidS();
+ mBannerPreference.setSubtitle("test");
+
+ mBannerPreference.onBindViewHolder(mHolder);
+
+ TextView mSubtitleView = mRootView.findViewById(R.id.banner_subtitle);
+ assertThat(mSubtitleView.getText()).isEqualTo("test");
+ assertThat(mSubtitleView.getVisibility()).isEqualTo(View.VISIBLE);
+ }
+
+ @Test
+ public void onBindViewHolder_whenAtLeastS_whenSubtitleSetByResId_shouldSetSubtitle() {
+ assumeAndroidS();
+ mBannerPreference.setSubtitle(TEST_STRING_RES_ID);
+
+ mBannerPreference.onBindViewHolder(mHolder);
+
+ TextView mSubtitleView = mRootView.findViewById(R.id.banner_subtitle);
+ assertThat(mSubtitleView.getText()).isEqualTo(mContext.getString(TEST_STRING_RES_ID));
+ assertThat(mSubtitleView.getVisibility()).isEqualTo(View.VISIBLE);
+ }
+
+ @Test
+ public void onBindViewHolder_whenAtLeastS_whenSubtitleXmlAttribute_shouldSetSubtitle() {
+ assumeAndroidS();
+ AttributeSet mAttributeSet = Robolectric.buildAttributeSet()
+ .addAttribute(R.attr.subtitle, "Test")
+ .build();
+ mBannerPreference = new BannerMessagePreference(mContext, mAttributeSet);
+
+ mBannerPreference.onBindViewHolder(mHolder);
+
+ TextView mSubtitleView = mRootView.findViewById(R.id.banner_subtitle);
+ assertThat(mSubtitleView.getText()).isEqualTo("Test");
+ assertThat(mSubtitleView.getVisibility()).isEqualTo(View.VISIBLE);
+ }
+
+ @Test
+ public void onBindViewHolder_whenAtLeastS_shouldNotShowSubtitleIfUnset() {
+ assumeAndroidS();
+ mBannerPreference.onBindViewHolder(mHolder);
+
+ TextView mSubtitleView = mRootView.findViewById(R.id.banner_subtitle);
+ assertThat(mSubtitleView.getVisibility()).isEqualTo(View.GONE);
+ }
+
+ @Test
+ public void onBindViewHolder_whenAtLeastS_whenIconSet_shouldSetIcon() {
+ assumeAndroidS();
+ mBannerPreference.setIcon(R.drawable.settingslib_ic_cross);
+
+ mBannerPreference.onBindViewHolder(mHolder);
+
+ ImageView mIcon = mRootView.findViewById(R.id.banner_icon);
+ ShadowDrawable shadowDrawable = Shadows.shadowOf(mIcon.getDrawable());
+ assertThat(shadowDrawable.getCreatedFromResId())
+ .isEqualTo(R.drawable.settingslib_ic_cross);
+ }
+
+ @Test
+ public void onBindViewHolder_whenAtLeastS_whenNoIconSet_shouldSetIconToDefault() {
+ assumeAndroidS();
+ mBannerPreference.onBindViewHolder(mHolder);
+
+ ImageView mIcon = mRootView.findViewById(R.id.banner_icon);
+ ShadowDrawable shadowDrawable = Shadows.shadowOf(mIcon.getDrawable());
+ assertThat(shadowDrawable.getCreatedFromResId()).isEqualTo(R.drawable.ic_warning);
+ }
+
+ @Test
+ public void setPositiveButtonText_shouldShowPositiveButton() {
+ mBannerPreference.setPositiveButtonText(TEST_STRING_RES_ID);
+
+ mBannerPreference.onBindViewHolder(mHolder);
+
+ Button mPositiveButton = mRootView.findViewById(R.id.banner_positive_btn);
+ assertThat(mPositiveButton.getVisibility()).isEqualTo(View.VISIBLE);
+ assertThat(mPositiveButton.getText()).isEqualTo(mContext.getString(TEST_STRING_RES_ID));
}
@Test
public void setNegativeButtonText_shouldShowNegativeButton() {
- mBannerPreference.setNegativeButtonText(R.string.tts_settings_title);
+ mBannerPreference.setNegativeButtonText(TEST_STRING_RES_ID);
mBannerPreference.onBindViewHolder(mHolder);
- assertThat(((Button) mRootView.findViewById(R.id.banner_negative_btn)).getVisibility())
- .isEqualTo(View.VISIBLE);
+ Button mNegativeButton = mRootView.findViewById(R.id.banner_negative_btn);
+ assertThat(mNegativeButton.getVisibility()).isEqualTo(View.VISIBLE);
+ assertThat(mNegativeButton.getText()).isEqualTo(mContext.getString(TEST_STRING_RES_ID));
}
@Test
public void withoutSetPositiveButtonText_shouldHidePositiveButton() {
mBannerPreference.onBindViewHolder(mHolder);
- assertThat(((Button) mRootView.findViewById(R.id.banner_positive_btn)).getVisibility())
+ assertThat(mRootView.findViewById(R.id.banner_positive_btn).getVisibility())
.isEqualTo(View.GONE);
}
@@ -99,51 +206,290 @@ public class BannerMessagePreferenceTest {
public void withoutSetNegativeButtonText_shouldHideNegativeButton() {
mBannerPreference.onBindViewHolder(mHolder);
- assertThat(((Button) mRootView.findViewById(R.id.banner_negative_btn)).getVisibility())
+ assertThat(mRootView.findViewById(R.id.banner_negative_btn).getVisibility())
.isEqualTo(View.GONE);
}
@Test
public void setPositiveButtonVisible_withTrue_shouldShowPositiveButton() {
- mBannerPreference.setPositiveButtonText(R.string.tts_settings_title);
+ mBannerPreference.setPositiveButtonText(TEST_STRING_RES_ID);
mBannerPreference.setPositiveButtonVisible(true);
mBannerPreference.onBindViewHolder(mHolder);
- assertThat(((Button) mRootView.findViewById(R.id.banner_positive_btn)).getVisibility())
+ assertThat((mRootView.findViewById(R.id.banner_positive_btn)).getVisibility())
.isEqualTo(View.VISIBLE);
}
@Test
public void setPositiveButtonVisible_withFalse_shouldHidePositiveButton() {
- mBannerPreference.setPositiveButtonText(R.string.tts_settings_title);
+ mBannerPreference.setPositiveButtonText(TEST_STRING_RES_ID);
mBannerPreference.setPositiveButtonVisible(false);
mBannerPreference.onBindViewHolder(mHolder);
- assertThat(((Button) mRootView.findViewById(R.id.banner_positive_btn)).getVisibility())
+ assertThat(mRootView.findViewById(R.id.banner_positive_btn).getVisibility())
.isEqualTo(View.GONE);
}
@Test
public void setNegativeButtonVisible_withTrue_shouldShowNegativeButton() {
- mBannerPreference.setNegativeButtonText(R.string.tts_settings_title);
+ mBannerPreference.setNegativeButtonText(TEST_STRING_RES_ID);
mBannerPreference.setNegativeButtonVisible(true);
mBannerPreference.onBindViewHolder(mHolder);
- assertThat(((Button) mRootView.findViewById(R.id.banner_negative_btn)).getVisibility())
+ assertThat(mRootView.findViewById(R.id.banner_negative_btn).getVisibility())
.isEqualTo(View.VISIBLE);
}
@Test
public void setNegativeButtonVisible_withFalse_shouldHideNegativeButton() {
- mBannerPreference.setNegativeButtonText(R.string.tts_settings_title);
+ mBannerPreference.setNegativeButtonText(TEST_STRING_RES_ID);
mBannerPreference.setNegativeButtonVisible(false);
mBannerPreference.onBindViewHolder(mHolder);
- assertThat(((Button) mRootView.findViewById(R.id.banner_negative_btn)).getVisibility())
+ assertThat(mRootView.findViewById(R.id.banner_negative_btn).getVisibility())
.isEqualTo(View.GONE);
}
+
+ @Test
+ public void setPositiveButtonOnClickListener_setsClickListener() {
+ mBannerPreference.setPositiveButtonOnClickListener(mClickListener);
+
+ mBannerPreference.onBindViewHolder(mHolder);
+ mRootView.findViewById(R.id.banner_positive_btn).callOnClick();
+
+ assertThat(mClickListenerCalled).isTrue();
+ }
+
+ @Test
+ public void setNegativeButtonOnClickListener_setsClickListener() {
+ mBannerPreference.setNegativeButtonOnClickListener(mClickListener);
+
+ mBannerPreference.onBindViewHolder(mHolder);
+ mRootView.findViewById(R.id.banner_negative_btn).callOnClick();
+
+ assertThat(mClickListenerCalled).isTrue();
+ }
+
+ @Test
+ public void setDismissButtonOnClickListener_whenAtLeastS_setsClickListener() {
+ assumeAndroidS();
+ mBannerPreference.setDismissButtonOnClickListener(mClickListener);
+
+ mBannerPreference.onBindViewHolder(mHolder);
+ mRootView.findViewById(R.id.banner_dismiss_btn).callOnClick();
+
+ assertThat(mClickListenerCalled).isTrue();
+ }
+
+ @Test
+ public void onBindViewHolder_whenAtLeastS_withDismissOnClickListener_dismissIsVisible() {
+ assumeAndroidS();
+ mBannerPreference.setDismissButtonOnClickListener(mClickListener);
+
+ mBannerPreference.onBindViewHolder(mHolder);
+
+ assertThat((mRootView.findViewById(R.id.banner_dismiss_btn)).getVisibility())
+ .isEqualTo(View.VISIBLE);
+ }
+
+ @Test
+ public void onBindViewHolder_whenAtLeastS_withNoDismissClickListener_dimissButtonIsGone() {
+ assumeAndroidS();
+
+ mBannerPreference.onBindViewHolder(mHolder);
+
+ assertThat((mRootView.findViewById(R.id.banner_dismiss_btn)).getVisibility())
+ .isEqualTo(View.GONE);
+ }
+
+ @Test
+ public void onBindViewHolder_whenAtLeastS_withNoClickListenerAndVisible_dimissButtonIsGone() {
+ assumeAndroidS();
+ mBannerPreference.setDismissButtonVisible(true);
+
+ mBannerPreference.onBindViewHolder(mHolder);
+
+ assertThat(mRootView.findViewById(R.id.banner_dismiss_btn).getVisibility())
+ .isEqualTo(View.GONE);
+ }
+
+ @Test
+ public void onBindViewHolder_whenAtLeastS_withClickListenerAndNotVisible_dimissButtonIsGone() {
+ assumeAndroidS();
+ mBannerPreference.setDismissButtonOnClickListener(mClickListener);
+ mBannerPreference.setDismissButtonVisible(false);
+
+ mBannerPreference.onBindViewHolder(mHolder);
+
+ ImageButton mDismissButton = mRootView.findViewById(R.id.banner_dismiss_btn);
+ assertThat(mDismissButton.getVisibility()).isEqualTo(View.GONE);
+ }
+
+ @Test
+ public void onBindViewHolder_whenAtLeastS_whenAttentionUnset_setsHighTheme() {
+ assumeAndroidS();
+ Drawable mCardBackgroundSpy = spy(mRootView.getBackground());
+ mRootView.setBackground(mCardBackgroundSpy);
+
+ mBannerPreference.onBindViewHolder(mHolder);
+
+ assertThat(((ImageView) mHolder.findViewById(R.id.banner_icon)).getColorFilter())
+ .isEqualTo(getColorFilter(R.color.banner_accent_attention_high));
+ assertThat(getButtonColor(R.id.banner_positive_btn))
+ .isEqualTo(getColorId(R.color.banner_accent_attention_high));
+ assertThat(getButtonColor(R.id.banner_negative_btn))
+ .isEqualTo(getColorId(R.color.banner_accent_attention_high));
+ verify(mCardBackgroundSpy).setTint(getColorId(R.color.banner_background_attention_high));
+ }
+
+ @Test
+ public void onBindViewHolder_whenAtLeastS_whenAttentionHighByXML_setsHighTheme() {
+ assumeAndroidS();
+ Drawable mCardBackgroundSpy = spy(mRootView.getBackground());
+ mRootView.setBackground(mCardBackgroundSpy);
+ AttributeSet mAttributeSet = Robolectric.buildAttributeSet()
+ .addAttribute(R.attr.attentionLevel, "high")
+ .build();
+ mBannerPreference = new BannerMessagePreference(mContext, mAttributeSet);
+
+ mBannerPreference.onBindViewHolder(mHolder);
+
+ assertThat(((ImageView) mHolder.findViewById(R.id.banner_icon)).getColorFilter())
+ .isEqualTo(getColorFilter(R.color.banner_accent_attention_high));
+ assertThat(getButtonColor(R.id.banner_positive_btn))
+ .isEqualTo(getColorId(R.color.banner_accent_attention_high));
+ assertThat(getButtonColor(R.id.banner_negative_btn))
+ .isEqualTo(getColorId(R.color.banner_accent_attention_high));
+ verify(mCardBackgroundSpy).setTint(getColorId(R.color.banner_background_attention_high));
+ }
+
+ @Test
+ public void onBindViewHolder_whenAtLeastS_whenAttentionMediumByXML_setsMediumTheme() {
+ assumeAndroidS();
+ Drawable mCardBackgroundSpy = spy(mRootView.getBackground());
+ mRootView.setBackground(mCardBackgroundSpy);
+ AttributeSet mAttributeSet = Robolectric.buildAttributeSet()
+ .addAttribute(R.attr.attentionLevel, "medium")
+ .build();
+ mBannerPreference = new BannerMessagePreference(mContext, mAttributeSet);
+
+ mBannerPreference.onBindViewHolder(mHolder);
+
+ assertThat(((ImageView) mHolder.findViewById(R.id.banner_icon)).getColorFilter())
+ .isEqualTo(getColorFilter(R.color.banner_accent_attention_medium));
+ assertThat(getButtonColor(R.id.banner_positive_btn))
+ .isEqualTo(getColorId(R.color.banner_accent_attention_medium));
+ assertThat(getButtonColor(R.id.banner_negative_btn))
+ .isEqualTo(getColorId(R.color.banner_accent_attention_medium));
+ verify(mCardBackgroundSpy).setTint(getColorId(R.color.banner_background_attention_medium));
+ }
+
+ @Test
+ public void onBindViewHolder_whenAtLeastS_whenAttentionLowByXML_setsLowTheme() {
+ assumeAndroidS();
+ Drawable mCardBackgroundSpy = spy(mRootView.getBackground());
+ mRootView.setBackground(mCardBackgroundSpy);
+ AttributeSet mAttributeSet = Robolectric.buildAttributeSet()
+ .addAttribute(R.attr.attentionLevel, "low")
+ .build();
+ mBannerPreference = new BannerMessagePreference(mContext, mAttributeSet);
+
+ mBannerPreference.onBindViewHolder(mHolder);
+
+ assertThat(((ImageView) mHolder.findViewById(R.id.banner_icon)).getColorFilter())
+ .isEqualTo(getColorFilter(R.color.banner_accent_attention_low));
+ assertThat(getButtonColor(R.id.banner_positive_btn))
+ .isEqualTo(getColorId(R.color.banner_accent_attention_low));
+ assertThat(getButtonColor(R.id.banner_negative_btn))
+ .isEqualTo(getColorId(R.color.banner_accent_attention_low));
+ verify(mCardBackgroundSpy).setTint(getColorId(R.color.banner_background_attention_low));
+ }
+
+ @Test
+ public void setAttentionLevel_whenAtLeastS_whenHighAttention_setsHighTheme() {
+ assumeAndroidS();
+ Drawable mCardBackgroundSpy = spy(mRootView.getBackground());
+ mRootView.setBackground(mCardBackgroundSpy);
+ mBannerPreference.setAttentionLevel(BannerMessagePreference.AttentionLevel.HIGH);
+
+ mBannerPreference.onBindViewHolder(mHolder);
+
+ assertThat(((ImageView) mHolder.findViewById(R.id.banner_icon)).getColorFilter())
+ .isEqualTo(getColorFilter(R.color.banner_accent_attention_high));
+ assertThat(getButtonColor(R.id.banner_positive_btn))
+ .isEqualTo(getColorId(R.color.banner_accent_attention_high));
+ assertThat(getButtonColor(R.id.banner_negative_btn))
+ .isEqualTo(getColorId(R.color.banner_accent_attention_high));
+ verify(mCardBackgroundSpy).setTint(getColorId(R.color.banner_background_attention_high));
+ }
+
+ @Test
+ public void setAttentionLevel_whenAtLeastS_whenMedAttention_setsMediumTheme() {
+ assumeAndroidS();
+ Drawable mCardBackgroundSpy = spy(mRootView.getBackground());
+ mRootView.setBackground(mCardBackgroundSpy);
+ mBannerPreference.setAttentionLevel(BannerMessagePreference.AttentionLevel.MEDIUM);
+
+ mBannerPreference.onBindViewHolder(mHolder);
+
+ assertThat(((ImageView) mHolder.findViewById(R.id.banner_icon)).getColorFilter())
+ .isEqualTo(getColorFilter(R.color.banner_accent_attention_medium));
+ assertThat(getButtonColor(R.id.banner_positive_btn))
+ .isEqualTo(getColorId(R.color.banner_accent_attention_medium));
+ assertThat(getButtonColor(R.id.banner_negative_btn))
+ .isEqualTo(getColorId(R.color.banner_accent_attention_medium));
+ verify(mCardBackgroundSpy).setTint(getColorId(R.color.banner_background_attention_medium));
+ }
+
+ @Test
+ public void setAttentionLevel_whenAtLeastS_whenLowAttention_setsLowTheme() {
+ assumeAndroidS();
+ Drawable mCardBackgroundSpy = spy(mRootView.getBackground());
+ mRootView.setBackground(mCardBackgroundSpy);
+ mBannerPreference.setAttentionLevel(BannerMessagePreference.AttentionLevel.LOW);
+
+ mBannerPreference.onBindViewHolder(mHolder);
+
+ assertThat(((ImageView) mHolder.findViewById(R.id.banner_icon)).getColorFilter())
+ .isEqualTo(getColorFilter(R.color.banner_accent_attention_low));
+ assertThat(getButtonColor(R.id.banner_positive_btn))
+ .isEqualTo(getColorId(R.color.banner_accent_attention_low));
+ assertThat(getButtonColor(R.id.banner_negative_btn))
+ .isEqualTo(getColorId(R.color.banner_accent_attention_low));
+ verify(mCardBackgroundSpy).setTint(getColorId(R.color.banner_background_attention_low));
+ }
+
+ private int getButtonColor(int buttonResId) {
+ Button mButton = mRootView.findViewById(buttonResId);
+ return mButton.getTextColors().getDefaultColor();
+ }
+
+ private ColorFilter getColorFilter(@ColorRes int colorResId) {
+ return new PorterDuffColorFilter(getColorId(colorResId), PorterDuff.Mode.SRC_IN);
+ }
+
+ private int getColorId(@ColorRes int colorResId) {
+ return mContext.getResources().getColor(colorResId, mContext.getTheme());
+ }
+
+ private void assumeAndroidR() {
+ ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT", 30);
+ // Reset view holder to use correct layout.
+ }
+
+ private void assumeAndroidS() {
+ ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT", 31);
+ // Re-inflate view to update layout.
+ setUpViewHolder();
+ }
+
+ private void setUpViewHolder() {
+ mRootView =
+ View.inflate(mContext, mBannerPreference.getLayoutResource(), null /* parent */);
+ mHolder = PreferenceViewHolder.createInstanceForTests(mRootView);
+ }
}