diff --git a/res/drawable/button_border_selected.xml b/res/drawable/button_border_selected.xml index 65dfe1b67a3..29acbcea8e1 100644 --- a/res/drawable/button_border_selected.xml +++ b/res/drawable/button_border_selected.xml @@ -20,6 +20,6 @@ android:color="@color/notification_importance_selection_bg" /> + android:color="?android:attr/colorAccent"/> diff --git a/res/drawable/ic_bubble_all.xml b/res/drawable/ic_bubble_all.xml new file mode 100644 index 00000000000..fdcf6dc803c --- /dev/null +++ b/res/drawable/ic_bubble_all.xml @@ -0,0 +1,25 @@ + + + + + diff --git a/res/drawable/ic_bubble_none.xml b/res/drawable/ic_bubble_none.xml new file mode 100644 index 00000000000..e8fd7df3def --- /dev/null +++ b/res/drawable/ic_bubble_none.xml @@ -0,0 +1,25 @@ + + + + + diff --git a/res/drawable/ic_bubble_selected.xml b/res/drawable/ic_bubble_selected.xml new file mode 100644 index 00000000000..f9533283b5e --- /dev/null +++ b/res/drawable/ic_bubble_selected.xml @@ -0,0 +1,25 @@ + + + + + diff --git a/res/drawable/ic_create_bubble.xml b/res/drawable/ic_create_bubble.xml index e9433553163..82d5db81210 100644 --- a/res/drawable/ic_create_bubble.xml +++ b/res/drawable/ic_create_bubble.xml @@ -14,17 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - - + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="?android:attr/colorControlNormal"> + + \ No newline at end of file diff --git a/res/layout/bubble_preference.xml b/res/layout/bubble_preference.xml new file mode 100644 index 00000000000..8a64716b757 --- /dev/null +++ b/res/layout/bubble_preference.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/raw-night/bubble_notification_animation.mp4 b/res/raw-night/bubble_notification_animation.mp4 new file mode 100644 index 00000000000..1a25e9378ad Binary files /dev/null and b/res/raw-night/bubble_notification_animation.mp4 differ diff --git a/res/raw/bubble_notification_animation.mp4 b/res/raw/bubble_notification_animation.mp4 new file mode 100644 index 00000000000..299454850e4 Binary files /dev/null and b/res/raw/bubble_notification_animation.mp4 differ diff --git a/res/xml/app_bubble_notification_settings.xml b/res/xml/app_bubble_notification_settings.xml index 8d97f8fda7a..3f52ad38153 100644 --- a/res/xml/app_bubble_notification_settings.xml +++ b/res/xml/app_bubble_notification_settings.xml @@ -13,22 +13,18 @@ See the License for the specific language governing permissions and limitations under the License. --> - + - - - + android:title="@string/notification_bubbles_title" + settings:allowDividerBelow="false"/> diff --git a/res/xml/app_notification_settings.xml b/res/xml/app_notification_settings.xml index ceb08a26e32..f0200ce46b5 100644 --- a/res/xml/app_notification_settings.xml +++ b/res/xml/app_notification_settings.xml @@ -29,6 +29,14 @@ + + + + - + + + + + + + + + + \ No newline at end of file diff --git a/res/xml/configure_notification_settings.xml b/res/xml/configure_notification_settings.xml index 3dcddc8eb19..cb8357bdb0e 100644 --- a/res/xml/configure_notification_settings.xml +++ b/res/xml/configure_notification_settings.xml @@ -50,15 +50,23 @@ - - - + settings:allowDividerAbove="true" + android:summary="@string/manage_conversations" + android:order="6" + android:fragment="com.android.settings.notification.app.ConversationListSettings" + /> + + (mControllers); } } diff --git a/src/com/android/settings/notification/app/BubblePreference.java b/src/com/android/settings/notification/app/BubblePreference.java new file mode 100644 index 00000000000..679b663c8dd --- /dev/null +++ b/src/com/android/settings/notification/app/BubblePreference.java @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2020 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.settings.notification.app; + +import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + +import com.android.settings.Utils; +import com.android.settingslib.R; +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedPreferenceHelper; + +/** + * A tri-state preference allowing a user to specify what gets to bubble. + */ +public class BubblePreference extends Preference implements View.OnClickListener { + RestrictedPreferenceHelper mHelper; + + private int mSelectedPreference; + + private Context mContext; + private Drawable mSelectedBackground; + private Drawable mUnselectedBackground; + + private ButtonViewHolder mBubbleAllButton; + private ButtonViewHolder mBubbleSelectedButton; + private ButtonViewHolder mBubbleNoneButton; + + public BubblePreference(Context context) { + this(context, null); + } + + public BubblePreference(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public BubblePreference(Context context, AttributeSet attrs, int defStyleAttr) { + this(context, attrs, defStyleAttr, 0); + } + + public BubblePreference(Context context, AttributeSet attrs, + int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + mHelper = new RestrictedPreferenceHelper(context, this, attrs); + mHelper.useAdminDisabledSummary(true); + mContext = context; + mSelectedBackground = mContext.getDrawable(R.drawable.button_border_selected); + mUnselectedBackground = mContext.getDrawable(R.drawable.button_border_unselected); + setLayoutResource(R.layout.bubble_preference); + } + + public void setSelectedPreference(int preference) { + mSelectedPreference = preference; + } + + public int getSelectedPreference() { + return mSelectedPreference; + } + + public void setDisabledByAdmin(RestrictedLockUtils.EnforcedAdmin admin) { + if (mHelper.setDisabledByAdmin(admin)) { + notifyChanged(); + } + } + + @Override + public void onBindViewHolder(final PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + + final boolean disabledByAdmin = mHelper.isDisabledByAdmin(); + View summary = holder.findViewById(android.R.id.summary); + if (disabledByAdmin) { + mHelper.onBindViewHolder(holder); + summary.setVisibility(View.VISIBLE); + } else { + summary.setVisibility(View.GONE); + } + holder.itemView.setClickable(false); + + View bubbleAll = holder.findViewById(R.id.bubble_all); + ImageView bubbleAllImage = (ImageView) holder.findViewById(R.id.bubble_all_icon); + TextView bubbleAllText = (TextView) holder.findViewById(R.id.bubble_all_label); + mBubbleAllButton = new ButtonViewHolder(bubbleAll, bubbleAllImage, bubbleAllText, + BUBBLE_PREFERENCE_ALL); + mBubbleAllButton.setSelected(mContext, mSelectedPreference == BUBBLE_PREFERENCE_ALL); + bubbleAll.setTag(BUBBLE_PREFERENCE_ALL); + bubbleAll.setOnClickListener(this); + bubbleAll.setVisibility(disabledByAdmin ? View.GONE : View.VISIBLE); + + View bubbleSelected = holder.findViewById(R.id.bubble_selected); + ImageView bubbleSelectedImage = (ImageView) holder.findViewById(R.id.bubble_selected_icon); + TextView bubbleSelectedText = (TextView) holder.findViewById(R.id.bubble_selected_label); + mBubbleSelectedButton = new ButtonViewHolder(bubbleSelected, bubbleSelectedImage, + bubbleSelectedText, BUBBLE_PREFERENCE_SELECTED); + mBubbleSelectedButton.setSelected(mContext, + mSelectedPreference == BUBBLE_PREFERENCE_SELECTED); + bubbleSelected.setTag(BUBBLE_PREFERENCE_SELECTED); + bubbleSelected.setOnClickListener(this); + bubbleSelected.setVisibility(disabledByAdmin ? View.GONE : View.VISIBLE); + + View bubbleNone = holder.findViewById(R.id.bubble_none); + ImageView bubbleNoneImage = (ImageView) holder.findViewById(R.id.bubble_none_icon); + TextView bubbleNoneText = (TextView) holder.findViewById(R.id.bubble_none_label); + mBubbleNoneButton = new ButtonViewHolder(bubbleNone, bubbleNoneImage, bubbleNoneText, + BUBBLE_PREFERENCE_NONE); + mBubbleNoneButton.setSelected(mContext, mSelectedPreference == BUBBLE_PREFERENCE_NONE); + bubbleNone.setTag(BUBBLE_PREFERENCE_NONE); + bubbleNone.setOnClickListener(this); + bubbleNone.setVisibility(disabledByAdmin ? View.GONE : View.VISIBLE); + } + + @Override + public void onClick(View v) { + final int selected = (int) v.getTag(); + callChangeListener(selected); + + mBubbleAllButton.setSelected(mContext, selected == BUBBLE_PREFERENCE_ALL); + mBubbleSelectedButton.setSelected(mContext, selected == BUBBLE_PREFERENCE_SELECTED); + mBubbleNoneButton.setSelected(mContext, selected == BUBBLE_PREFERENCE_NONE); + } + + private class ButtonViewHolder { + private View mView; + private ImageView mImageView; + private TextView mTextView; + private int mId; + + ButtonViewHolder(View v, ImageView iv, TextView tv, int identifier) { + mView = v; + mImageView = iv; + mTextView = tv; + mId = identifier; + } + + void setSelected(Context context, boolean selected) { + mView.setBackground(selected ? mSelectedBackground : mUnselectedBackground); + mView.setSelected(selected); + + ColorStateList stateList = selected + ? Utils.getColorAccent(context) + : Utils.getColorAttr(context, android.R.attr.textColorPrimary); + mImageView.setImageTintList(stateList); + mTextView.setTextColor(stateList); + } + } +} diff --git a/src/com/android/settings/notification/app/BubblePreferenceController.java b/src/com/android/settings/notification/app/BubblePreferenceController.java index d33ba7e1aa3..3255192a912 100644 --- a/src/com/android/settings/notification/app/BubblePreferenceController.java +++ b/src/com/android/settings/notification/app/BubblePreferenceController.java @@ -16,6 +16,7 @@ package com.android.settings.notification.app; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; import static android.provider.Settings.Global.NOTIFICATION_BUBBLES; import android.annotation.Nullable; @@ -26,11 +27,14 @@ import androidx.annotation.VisibleForTesting; import androidx.fragment.app.FragmentManager; import androidx.preference.Preference; -import com.android.settings.R; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.notification.NotificationBackend; import com.android.settingslib.RestrictedSwitchPreference; +/** + * Preference controller for Bubbles. This is used as the app-specific page and conversation + * settings. + */ public class BubblePreferenceController extends NotificationPreferenceController implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener { @@ -74,40 +78,49 @@ public class BubblePreferenceController extends NotificationPreferenceController return true; } + @Override public void updateState(Preference preference) { - if (mAppRow != null) { - RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference; + if (mIsAppPage && mAppRow != null) { + // We're on the app specific bubble page which displays a tri-state + int backEndPref = mAppRow.bubblePreference; + BubblePreference pref = (BubblePreference) preference; pref.setDisabledByAdmin(mAdmin); - if (mChannel != null) { - pref.setChecked(mChannel.canBubble() && isGloballyEnabled()); - pref.setEnabled(!pref.isDisabledByAdmin()); + if (!isGloballyEnabled()) { + pref.setSelectedPreference(BUBBLE_PREFERENCE_NONE); } else { - pref.setChecked(mAppRow.allowBubbles && isGloballyEnabled()); - pref.setSummary(mContext.getString( - R.string.bubbles_app_toggle_summary, mAppRow.label)); + pref.setSelectedPreference(backEndPref); } + } else if (mChannel != null) { + // We're on the channel specific notification page which displays a toggle. + RestrictedSwitchPreference switchpref = (RestrictedSwitchPreference) preference; + switchpref.setDisabledByAdmin(mAdmin); + switchpref.setChecked(mChannel.canBubble() && isGloballyEnabled()); } } @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - final boolean value = (Boolean) newValue && isGloballyEnabled(); if (mChannel != null) { - mChannel.setAllowBubbles(value); + // Channel page is toggle + mChannel.setAllowBubbles((boolean) newValue); saveChannel(); - return true; - } else if (mAppRow != null && mFragmentManager != null) { - RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference; - // if the global setting is off, toggling app level permission requires extra - // confirmation - if (!isGloballyEnabled() && !pref.isChecked()) { - new BubbleWarningDialogFragment() - .setPkgInfo(mAppRow.pkg, mAppRow.uid) - .show(mFragmentManager, "dialog"); - return false; - } else { - mAppRow.allowBubbles = value; - mBackend.setAllowBubbles(mAppRow.pkg, mAppRow.uid, value); + } else if (mIsAppPage) { + // App page is bubble preference + BubblePreference pref = (BubblePreference) preference; + if (mAppRow != null && mFragmentManager != null) { + final int value = (int) newValue; + if (!isGloballyEnabled() + && pref.getSelectedPreference() == BUBBLE_PREFERENCE_NONE) { + // if the global setting is off, toggling app level permission requires extra + // confirmation + new BubbleWarningDialogFragment() + .setPkgPrefInfo(mAppRow.pkg, mAppRow.uid, value) + .show(mFragmentManager, "dialog"); + return false; + } else { + mAppRow.bubblePreference = value; + mBackend.setAllowBubbles(mAppRow.pkg, mAppRow.uid, value); + } } } return true; @@ -118,21 +131,26 @@ public class BubblePreferenceController extends NotificationPreferenceController NOTIFICATION_BUBBLES, SYSTEM_WIDE_OFF) == SYSTEM_WIDE_ON; } - // Used in app level prompt that confirms the user is ok with turning on bubbles - // globally. If they aren't, undo what + /** + * Used in app level prompt that confirms the user is ok with turning on bubbles + * globally. If they aren't, undo that. + */ public static void revertBubblesApproval(Context mContext, String pkg, int uid) { NotificationBackend backend = new NotificationBackend(); - backend.setAllowBubbles(pkg, uid, false); + backend.setAllowBubbles(pkg, uid, BUBBLE_PREFERENCE_NONE); + // changing the global settings will cause the observer on the host page to reload // correct preference state Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_OFF); } - // Apply global bubbles approval - public static void applyBubblesApproval(Context mContext, String pkg, int uid) { + /** + * Apply global bubbles approval + */ + public static void applyBubblesApproval(Context mContext, String pkg, int uid, int pref) { NotificationBackend backend = new NotificationBackend(); - backend.setAllowBubbles(pkg, uid, true); + backend.setAllowBubbles(pkg, uid, pref); // changing the global settings will cause the observer on the host page to reload // correct preference state Settings.Global.putInt(mContext.getContentResolver(), diff --git a/src/com/android/settings/notification/app/BubbleSummaryPreferenceController.java b/src/com/android/settings/notification/app/BubbleSummaryPreferenceController.java index f13613c4daf..06c6f3a1a84 100644 --- a/src/com/android/settings/notification/app/BubbleSummaryPreferenceController.java +++ b/src/com/android/settings/notification/app/BubbleSummaryPreferenceController.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 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. @@ -16,38 +16,34 @@ package com.android.settings.notification.app; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; import static android.provider.Settings.Global.NOTIFICATION_BUBBLES; -import android.app.settings.SettingsEnums; import android.content.Context; -import android.os.Bundle; +import android.content.Intent; +import android.content.res.Resources; import android.provider.Settings; -import com.android.settings.R; -import com.android.settings.applications.AppInfoBase; -import com.android.settings.core.SubSettingLauncher; -import com.android.settings.notification.NotificationBackend; - import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; -public class BubbleSummaryPreferenceController extends NotificationPreferenceController { +import com.android.settings.R; +import com.android.settings.notification.NotificationBackend; + +/** + * Summary of the app setting for bubbles, available through app notification settings. + */ +public class BubbleSummaryPreferenceController extends NotificationPreferenceController { + private static final String KEY = "bubble_pref_link"; - private static final String KEY = "bubble_link_pref"; @VisibleForTesting - static final int SYSTEM_WIDE_ON = 1; - @VisibleForTesting - static final int SYSTEM_WIDE_OFF = 0; + static final int ON = 1; public BubbleSummaryPreferenceController(Context context, NotificationBackend backend) { super(context, backend); } - @Override - public String getPreferenceKey() { - return KEY; - } - @Override public boolean isAvailable() { if (!super.isAvailable()) { @@ -63,45 +59,47 @@ public class BubbleSummaryPreferenceController extends NotificationPreferenceCon if (isDefaultChannel()) { return true; } else { - return mAppRow != null && mAppRow.allowBubbles; + return mAppRow != null; } } return isGloballyEnabled(); } + @Override + public String getPreferenceKey() { + return KEY; + } + @Override public void updateState(Preference preference) { super.updateState(preference); if (mAppRow != null) { - Bundle args = new Bundle(); - args.putString(AppInfoBase.ARG_PACKAGE_NAME, mAppRow.pkg); - args.putInt(AppInfoBase.ARG_PACKAGE_UID, mAppRow.uid); - - preference.setIntent(new SubSettingLauncher(mContext) - .setDestination(AppBubbleNotificationSettings.class.getName()) - .setArguments(args) - .setSourceMetricsCategory( - SettingsEnums.NOTIFICATION_APP_NOTIFICATION) - .toIntent()); + final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_BUBBLE_SETTINGS); + intent.putExtra(Settings.EXTRA_APP_PACKAGE, mAppRow.pkg); + intent.putExtra(Settings.EXTRA_APP_UID, mAppRow.uid); + preference.setIntent(intent); } } @Override public CharSequence getSummary() { - boolean canBubble = false; - if (mAppRow != null) { - if (mChannel != null) { - canBubble |= mChannel.canBubble() && isGloballyEnabled(); - } else { - canBubble |= mAppRow.allowBubbles && isGloballyEnabled(); - } + if (mAppRow == null) { + return null; + } + int backEndPref = mAppRow.bubblePreference; + Resources res = mContext.getResources(); + if (backEndPref == BUBBLE_PREFERENCE_NONE || !isGloballyEnabled()) { + return res.getString(R.string.bubble_app_setting_none); + } else if (backEndPref == BUBBLE_PREFERENCE_ALL) { + return res.getString(R.string.bubble_app_setting_all); + } else { + return res.getString(R.string.bubble_app_setting_selected); } - return mContext.getString(canBubble ? R.string.switch_on_text : R.string.switch_off_text); } private boolean isGloballyEnabled() { return Settings.Global.getInt(mContext.getContentResolver(), - NOTIFICATION_BUBBLES, SYSTEM_WIDE_OFF) == SYSTEM_WIDE_ON; + NOTIFICATION_BUBBLES, ON) == ON; } } diff --git a/src/com/android/settings/notification/app/BubbleWarningDialogFragment.java b/src/com/android/settings/notification/app/BubbleWarningDialogFragment.java index d3aa7585260..7d5b24a3050 100644 --- a/src/com/android/settings/notification/app/BubbleWarningDialogFragment.java +++ b/src/com/android/settings/notification/app/BubbleWarningDialogFragment.java @@ -27,6 +27,7 @@ import com.android.settings.core.instrumentation.InstrumentedDialogFragment; public class BubbleWarningDialogFragment extends InstrumentedDialogFragment { static final String KEY_PKG = "p"; static final String KEY_UID = "u"; + static final String KEY_SELECTED_PREFERENCE = "pref"; @Override @@ -34,10 +35,11 @@ public class BubbleWarningDialogFragment extends InstrumentedDialogFragment { return SettingsEnums.DIALOG_APP_BUBBLE_SETTINGS; } - public BubbleWarningDialogFragment setPkgInfo(String pkg, int uid) { + public BubbleWarningDialogFragment setPkgPrefInfo(String pkg, int uid, int preference) { Bundle args = new Bundle(); args.putString(KEY_PKG, pkg); args.putInt(KEY_UID, uid); + args.putInt(KEY_SELECTED_PREFERENCE, preference); setArguments(args); return this; } @@ -48,6 +50,7 @@ public class BubbleWarningDialogFragment extends InstrumentedDialogFragment { final Bundle args = getArguments(); final String pkg = args.getString(KEY_PKG); final int uid = args.getInt(KEY_UID); + final int pref = args.getInt(KEY_SELECTED_PREFERENCE); final String title = getResources().getString(R.string.bubbles_feature_disabled_dialog_title); @@ -60,7 +63,7 @@ public class BubbleWarningDialogFragment extends InstrumentedDialogFragment { .setPositiveButton(R.string.bubbles_feature_disabled_button_approve, (dialog, id) -> BubblePreferenceController.applyBubblesApproval( - getContext(), pkg, uid)) + getContext(), pkg, uid, pref)) .setNegativeButton(R.string.bubbles_feature_disabled_button_cancel, (dialog, id) -> BubblePreferenceController.revertBubblesApproval( diff --git a/tests/robotests/src/com/android/settings/development/BubbleGlobalPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/BubbleGlobalPreferenceControllerTest.java deleted file mode 100644 index 9e52a8829c9..00000000000 --- a/tests/robotests/src/com/android/settings/development/BubbleGlobalPreferenceControllerTest.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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. - */ - -package com.android.settings.development; - -import static android.provider.Settings.Global.NOTIFICATION_BUBBLES; - -import static com.android.settings.development.BubbleGlobalPreferenceController.OFF; -import static com.android.settings.development.BubbleGlobalPreferenceController.ON; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.provider.Settings; - -import androidx.preference.PreferenceScreen; -import androidx.preference.SwitchPreference; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -@RunWith(RobolectricTestRunner.class) -public class BubbleGlobalPreferenceControllerTest { - private Context mContext; - - @Mock - private SwitchPreference mPreference; - @Mock - private PreferenceScreen mPreferenceScreen; - - private BubbleGlobalPreferenceController mController; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; - mController = new BubbleGlobalPreferenceController(mContext); - when(mPreferenceScreen.findPreference(mController.getPreferenceKey())) - .thenReturn(mPreference); - mController.displayPreference(mPreferenceScreen); - } - - @Test - public void onPreferenceChange_settingEnabled_allowBubbles_shouldBeOn() { - mController.onPreferenceChange(mPreference, true /* new value */); - - assertThat(isSettingEnabled()).isTrue(); - } - - @Test - public void onPreferenceChange_settingDisabled_allowBubbles_shouldBeOff() { - mController.onPreferenceChange(mPreference, false /* new value */); - - assertThat(isSettingEnabled()).isFalse(); - } - - @Test - public void updateState_settingEnabled_preferenceShouldBeChecked() { - Settings.Global.putInt(mContext.getContentResolver(), - NOTIFICATION_BUBBLES, 1 /* enabled */); - mController.updateState(mPreference); - - verify(mPreference).setChecked(true); - } - - @Test - public void updateState_settingReset_defaultDisabled_preferenceShouldNotBeChecked() { - Settings.Global.putInt(mContext.getContentResolver(), - NOTIFICATION_BUBBLES, 0 /* enabled */); - mController.updateState(mPreference); - - verify(mPreference).setChecked(false); - } - - @Test - public void onDeveloperOptionsSwitchDisabled_shouldDisable() { - mController.onDeveloperOptionsSwitchDisabled(); - - verify(mPreference).setChecked(false); - verify(mPreference).setEnabled(false); - - assertThat(isSettingEnabled()).isFalse(); - } - - private boolean isSettingEnabled() { - return Settings.Global.getInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, - OFF /* default off */) == ON; - } - -} diff --git a/tests/robotests/src/com/android/settings/notification/BubbleNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BubbleNotificationPreferenceControllerTest.java new file mode 100644 index 00000000000..b2cf55b97b2 --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/BubbleNotificationPreferenceControllerTest.java @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2020 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.settings.notification; + +import static android.provider.Settings.Global.NOTIFICATION_BUBBLES; + +import static com.android.settings.core.BasePreferenceController.AVAILABLE; +import static com.android.settings.notification.BadgingNotificationPreferenceController.OFF; +import static com.android.settings.notification.BadgingNotificationPreferenceController.ON; + +import static com.google.common.truth.Truth.assertThat; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.provider.Settings; + +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; +import androidx.preference.TwoStatePreference; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class BubbleNotificationPreferenceControllerTest { + + private Context mContext; + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private PreferenceScreen mScreen; + + private BubbleNotificationPreferenceController mController; + private Preference mPreference; + + private static final String KEY_NOTIFICATION_BUBBLES = "notification_bubbles"; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mController = new BubbleNotificationPreferenceController(mContext, + KEY_NOTIFICATION_BUBBLES); + mPreference = new Preference(RuntimeEnvironment.application); + mPreference.setKey(mController.getPreferenceKey()); + when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference); + } + + @Test + public void getAvilabilityStatus_returnsAvailable() { + assertEquals(AVAILABLE, mController.getAvailabilityStatus()); + } + + @Test + public void updateState_settingIsOn_preferenceSetChecked() { + final TwoStatePreference preference = mock(TwoStatePreference.class); + Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, ON); + + mController.updateState(preference); + + verify(preference).setChecked(true); + } + + @Test + public void updateState_settingIsOff_preferenceSetUnchecked() { + final TwoStatePreference preference = mock(TwoStatePreference.class); + Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, OFF); + assertThat(Settings.Global.getInt(mContext.getContentResolver(), + NOTIFICATION_BUBBLES, ON)).isEqualTo(OFF); + + mController.updateState(preference); + + verify(preference).setChecked(false); + } + + @Test + public void isChecked_settingIsOff_shouldReturnFalse() { + Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, OFF); + + assertThat(mController.isChecked()).isFalse(); + } + + @Test + public void isChecked_settingIsOn_shouldReturnTrue() { + Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, ON); + + assertThat(mController.isChecked()).isTrue(); + } + + @Test + public void setChecked_setFalse_disablesSetting() { + Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, ON); + + mController.setChecked(false); + int updatedValue = Settings.Global.getInt(mContext.getContentResolver(), + NOTIFICATION_BUBBLES, -1); + + assertThat(updatedValue).isEqualTo(OFF); + } + + @Test + public void setChecked_setTrue_enablesSetting() { + Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, OFF); + + mController.setChecked(true); + int updatedValue = Settings.Global.getInt(mContext.getContentResolver(), + NOTIFICATION_BUBBLES, -1); + + assertThat(updatedValue).isEqualTo(ON); + } + + @Test + public void isSliceable_returnsFalse() { + assertThat(mController.isSliceable()).isFalse(); + } +} diff --git a/tests/robotests/src/com/android/settings/notification/BubbleSummaryNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BubbleSummaryNotificationPreferenceControllerTest.java new file mode 100644 index 00000000000..b5f505b6e82 --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/BubbleSummaryNotificationPreferenceControllerTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2020 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.settings.notification; + +import static android.provider.Settings.Global.NOTIFICATION_BUBBLES; + +import static com.android.settings.notification.BadgingNotificationPreferenceController.OFF; +import static com.android.settings.notification.BadgingNotificationPreferenceController.ON; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.provider.Settings; + +import androidx.preference.Preference; + +import com.android.settings.R; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class BubbleSummaryNotificationPreferenceControllerTest { + + private Context mContext; + + private BubbleSummaryNotificationPreferenceController mController; + private Preference mPreference; + + private static final String KEY_NOTIFICATION_BUBBLES = "notification_bubbles"; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mController = new BubbleSummaryNotificationPreferenceController(mContext, + KEY_NOTIFICATION_BUBBLES); + mPreference = new Preference(RuntimeEnvironment.application); + } + + @Test + public void getSummary_NOTIFICATION_BUBBLESIsOff_returnOffString() { + Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, OFF); + + assertThat(mController.getSummary()).isEqualTo("Off"); + } + + @Test + public void getSummary_NOTIFICATION_BUBBLESIsOff_returnOnString() { + Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, ON); + + String onString = mContext.getString(R.string.notifications_bubble_setting_on_summary); + assertThat(mController.getSummary()).isEqualTo(onString); + } +} diff --git a/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java index c2c45cb1707..0cf6dc67829 100644 --- a/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java @@ -17,6 +17,9 @@ package com.android.settings.notification.app; import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED; import static android.app.NotificationManager.IMPORTANCE_HIGH; import static android.app.NotificationManager.IMPORTANCE_LOW; import static android.app.NotificationManager.IMPORTANCE_NONE; @@ -25,8 +28,8 @@ import static android.provider.Settings.Global.NOTIFICATION_BUBBLES; import static com.android.settings.notification.app.BubblePreferenceController.SYSTEM_WIDE_OFF; import static com.android.settings.notification.app.BubblePreferenceController.SYSTEM_WIDE_ON; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -44,6 +47,11 @@ import android.content.Context; import android.os.UserManager; import android.provider.Settings; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentTransaction; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + import com.android.settings.notification.NotificationBackend; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedSwitchPreference; @@ -58,11 +66,6 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.shadows.ShadowApplication; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentTransaction; -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; - @RunWith(RobolectricTestRunner.class) public class BubblePreferenceControllerTest { @@ -125,7 +128,7 @@ public class BubblePreferenceControllerTest { public void testIsAvailable_channel_yesIfAppOff() { Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.allowBubbles = false; + appRow.bubblePreference = BUBBLE_PREFERENCE_NONE; NotificationChannel channel = mock(NotificationChannel.class); when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); mController.onResume(appRow, channel, null, null, null, null); @@ -177,7 +180,7 @@ public class BubblePreferenceControllerTest { @Test public void testIsAvailable_defaultChannel() { NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.allowBubbles = true; + appRow.bubblePreference = BUBBLE_PREFERENCE_ALL; NotificationChannel channel = mock(NotificationChannel.class); when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID); @@ -190,7 +193,7 @@ public class BubblePreferenceControllerTest { @Test public void testIsAvailable_channel() { NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.allowBubbles = true; + appRow.bubblePreference = BUBBLE_PREFERENCE_ALL; NotificationChannel channel = mock(NotificationChannel.class); when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); mController.onResume(appRow, channel, null, null, null, null); @@ -213,7 +216,20 @@ public class BubblePreferenceControllerTest { } @Test - public void testUpdateState_channelNotBlockable() { + public void testUpdateState_app_disabledByAdmin() { + NotificationChannel channel = mock(NotificationChannel.class); + when(channel.getId()).thenReturn("something"); + mAppPageController.onResume(new NotificationBackend.AppRow(), channel, null, + null, null, mock(RestrictedLockUtils.EnforcedAdmin.class)); + + BubblePreference pref = new BubblePreference(mContext); + mAppPageController.updateState(pref); + + assertFalse(pref.isEnabled()); + } + + @Test + public void testUpdateState_channel_channelNotBlockable() { Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); NotificationChannel channel = mock(NotificationChannel.class); @@ -251,21 +267,24 @@ public class BubblePreferenceControllerTest { Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); appRow.label = "App!"; - appRow.allowBubbles = true; - mController.onResume(appRow, null, null, null, null, null); + appRow.bubblePreference = BUBBLE_PREFERENCE_ALL; + mAppPageController.onResume(appRow, null, null, null, null, null); - RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext); - mController.updateState(pref); - assertTrue(pref.isChecked()); + BubblePreference pref = new BubblePreference(mContext); + mAppPageController.updateState(pref); + assertEquals(BUBBLE_PREFERENCE_ALL, pref.getSelectedPreference()); - appRow.allowBubbles = false; - mController.onResume(appRow, null, null, null, null, null); + appRow.bubblePreference = BUBBLE_PREFERENCE_NONE; + mAppPageController.onResume(appRow, null, null, null, null, null); - mController.updateState(pref); - assertFalse(pref.isChecked()); + mAppPageController.updateState(pref); + assertEquals(BUBBLE_PREFERENCE_NONE, pref.getSelectedPreference()); - assertNotNull(pref.getSummary()); - assertTrue(pref.getSummary().toString().contains(appRow.label)); + appRow.bubblePreference = BUBBLE_PREFERENCE_SELECTED; + mAppPageController.onResume(appRow, null, null, null, null, null); + + mAppPageController.updateState(pref); + assertEquals(BUBBLE_PREFERENCE_SELECTED, pref.getSelectedPreference()); } @Test @@ -274,22 +293,21 @@ public class BubblePreferenceControllerTest { NOTIFICATION_BUBBLES, SYSTEM_WIDE_OFF); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); appRow.label = "App!"; - appRow.allowBubbles = true; - mController.onResume(appRow, null, null, null, null, null); + appRow.bubblePreference = BUBBLE_PREFERENCE_ALL; + mAppPageController.onResume(appRow, null, null, null, null, null); - RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext); - mController.updateState(pref); - assertFalse(pref.isChecked()); + BubblePreference pref = new BubblePreference(mContext); + mAppPageController.updateState(pref); + assertEquals(BUBBLE_PREFERENCE_NONE, pref.getSelectedPreference()); } @Test public void testOnPreferenceChange_on_channel() { Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.allowBubbles = true; + appRow.bubblePreference = BUBBLE_PREFERENCE_SELECTED; NotificationChannel channel = new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_LOW); - channel.setAllowBubbles(false); mController.onResume(appRow, channel, null, null, null, null); RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext); @@ -306,10 +324,9 @@ public class BubblePreferenceControllerTest { public void testOnPreferenceChange_off_channel() { Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.allowBubbles = true; + appRow.bubblePreference = BUBBLE_PREFERENCE_SELECTED; NotificationChannel channel = new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH); - channel.setAllowBubbles(true); mController.onResume(appRow, channel, null, null, null, null); RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext); @@ -322,59 +339,78 @@ public class BubblePreferenceControllerTest { assertFalse(channel.canBubble()); } + @Test - public void testOnPreferenceChange_on_app() { + public void testOnPreferenceChange_app_all() { Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.allowBubbles = false; - mController.onResume(appRow, null, null, null, null, null); + appRow.bubblePreference = BUBBLE_PREFERENCE_NONE; + mAppPageController.onResume(appRow, null, null, null, null, null); - RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext); + BubblePreference pref = new BubblePreference(mContext); when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref); - mController.displayPreference(mScreen); - mController.updateState(pref); + mAppPageController.displayPreference(mScreen); + mAppPageController.updateState(pref); - mController.onPreferenceChange(pref, true); + mAppPageController.onPreferenceChange(pref, BUBBLE_PREFERENCE_ALL); - assertTrue(appRow.allowBubbles); - verify(mBackend, times(1)).setAllowBubbles(any(), anyInt(), eq(true)); + assertEquals(appRow.bubblePreference, BUBBLE_PREFERENCE_ALL); + verify(mBackend, times(1)).setAllowBubbles(any(), anyInt(), eq(BUBBLE_PREFERENCE_ALL)); } @Test - public void testOnPreferenceChange_off_app() { - Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON); - NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.allowBubbles = true; - mController.onResume(appRow, null, null, null, null, null); - - RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext); - when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref); - mController.displayPreference(mScreen); - mController.updateState(pref); - - mController.onPreferenceChange(pref, false); - - assertFalse(appRow.allowBubbles); - verify(mBackend, times(1)).setAllowBubbles(any(), anyInt(), eq(false)); - } - - @Test - public void testOnPreferenceChange_on_app_offGlobally() { + public void testOnPreferenceChange_app_all_offGlobally() { Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_OFF); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.allowBubbles = false; - mController.onResume(appRow, null, null, null, null, null); + appRow.bubblePreference = BUBBLE_PREFERENCE_NONE; + mAppPageController.onResume(appRow, null, null, null, null, null); - RestrictedSwitchPreference pref = new RestrictedSwitchPreference(mContext); + BubblePreference pref = new BubblePreference(mContext); when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref); - mController.displayPreference(mScreen); - mController.updateState(pref); + mAppPageController.displayPreference(mScreen); + mAppPageController.updateState(pref); - mController.onPreferenceChange(pref, true); + mAppPageController.onPreferenceChange(pref, BUBBLE_PREFERENCE_ALL); - assertFalse(appRow.allowBubbles); - verify(mBackend, never()).setAllowBubbles(any(), anyInt(), eq(true)); + assertEquals(appRow.bubblePreference, BUBBLE_PREFERENCE_NONE); + verify(mBackend, never()).setAllowBubbles(any(), anyInt(), eq(BUBBLE_PREFERENCE_ALL)); verify(mFragmentManager, times(1)).beginTransaction(); } + + @Test + public void testOnPreferenceChange_app_selected() { + Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON); + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.bubblePreference = BUBBLE_PREFERENCE_ALL; + mAppPageController.onResume(appRow, null, null, null, null, null); + + BubblePreference pref = new BubblePreference(mContext); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref); + mAppPageController.displayPreference(mScreen); + mAppPageController.updateState(pref); + + mAppPageController.onPreferenceChange(pref, BUBBLE_PREFERENCE_NONE); + + assertEquals(BUBBLE_PREFERENCE_NONE, appRow.bubblePreference); + verify(mBackend, times(1)).setAllowBubbles(any(), anyInt(), eq(BUBBLE_PREFERENCE_NONE)); + } + + @Test + public void testOnPreferenceChange_app_none() { + Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON); + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.bubblePreference = BUBBLE_PREFERENCE_ALL; + mAppPageController.onResume(appRow, null, null, null, null, null); + + BubblePreference pref = new BubblePreference(mContext); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref); + mAppPageController.displayPreference(mScreen); + mAppPageController.updateState(pref); + + mAppPageController.onPreferenceChange(pref, BUBBLE_PREFERENCE_NONE); + + assertEquals(BUBBLE_PREFERENCE_NONE, appRow.bubblePreference); + verify(mBackend, times(1)).setAllowBubbles(any(), anyInt(), eq(BUBBLE_PREFERENCE_NONE)); + } } diff --git a/tests/robotests/src/com/android/settings/notification/app/BubbleSummaryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/BubbleSummaryPreferenceControllerTest.java index 80abfbb5f20..9d664ac02c8 100644 --- a/tests/robotests/src/com/android/settings/notification/app/BubbleSummaryPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/app/BubbleSummaryPreferenceControllerTest.java @@ -17,28 +17,31 @@ package com.android.settings.notification.app; import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED; import static android.app.NotificationManager.IMPORTANCE_HIGH; import static android.provider.Settings.Global.NOTIFICATION_BUBBLES; -import static com.android.settings.notification.app.BubbleSummaryPreferenceController.SYSTEM_WIDE_OFF; -import static com.android.settings.notification.app.BubbleSummaryPreferenceController.SYSTEM_WIDE_ON; +import static com.android.settings.notification.app.BubblePreferenceController.SYSTEM_WIDE_OFF; +import static com.android.settings.notification.app.BubblePreferenceController.SYSTEM_WIDE_ON; import static junit.framework.TestCase.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.NotificationChannel; import android.content.Context; import android.provider.Settings; +import androidx.preference.Preference; + +import com.android.settings.R; import com.android.settings.notification.NotificationBackend; import org.junit.Before; @@ -50,8 +53,6 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.shadows.ShadowApplication; -import androidx.preference.Preference; - @RunWith(RobolectricTestRunner.class) public class BubbleSummaryPreferenceControllerTest { @@ -70,13 +71,13 @@ public class BubbleSummaryPreferenceControllerTest { } @Test - public void testNoCrashIfNoOnResume() { + public void isAvailable_noOnResume_shouldNotCrash() { mController.isAvailable(); mController.updateState(mock(Preference.class)); } @Test - public void testIsAvailable_notIfAppBlocked() { + public void isAvailable_appBlocked_shouldReturnFalse() { NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); appRow.banned = true; mController.onResume(appRow, mock(NotificationChannel.class), null, null, null, null); @@ -84,53 +85,52 @@ public class BubbleSummaryPreferenceControllerTest { } @Test - public void testIsAvailable_notIfOffGlobally() { - NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - NotificationChannel channel = mock(NotificationChannel.class); - when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); - mController.onResume(appRow, channel, null, null, null, null); - Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, - SYSTEM_WIDE_OFF); - - assertFalse(mController.isAvailable()); - } - - @Test - public void testIsAvailable_app() { + public void isAvailable_nullChannelNOTIFICATION_BUBBLESisOn_shouldReturnTrue() { + Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); mController.onResume(appRow, null, null, null, null, null); - Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON); assertTrue(mController.isAvailable()); } @Test - public void testIsNotAvailable_app_globalOff() { - NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - mController.onResume(appRow, null, null, null, null, null); + public void isAvailable_nullChannelNOTIFICATION_BUBBLESisOff_shouldReturnFalse() { Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_OFF); + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + mController.onResume(appRow, null, null, null, null, null); assertFalse(mController.isAvailable()); } @Test - public void testIsAvailable_defaultChannel() { + public void isAvailable_nonNullChannelNOTIFICATION_BUBBLESisOff_shouldReturnFalse() { + Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, + SYSTEM_WIDE_OFF); + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + NotificationChannel channel = mock(NotificationChannel.class); + when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); + mController.onResume(appRow, channel, null, null, null, null); + + assertFalse(mController.isAvailable()); + } + + @Test + public void isAvailable_defaultChannelNOTIFICATION_BUBBLESisOn_shouldReturnTrue() { + Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON); NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.allowBubbles = true; NotificationChannel channel = mock(NotificationChannel.class); when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID); mController.onResume(appRow, channel, null, null, null, null); - Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON); assertTrue(mController.isAvailable()); } @Test - public void testUpdateState() { + public void updateState_setsIntent() { NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.allowBubbles = true; + appRow.bubblePreference = BUBBLE_PREFERENCE_ALL; mController.onResume(appRow, null, null, null, null, null); Preference pref = new Preference(mContext); @@ -139,22 +139,53 @@ public class BubbleSummaryPreferenceControllerTest { } @Test - public void testGetSummary() { - Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON); - NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); - appRow.allowBubbles = true; - mController.onResume(appRow, null, null, null, null, null); - - assertEquals("On", mController.getSummary()); - + public void getSummary_NOTIFICATION_BUBBLESIsOff_returnsNoneString() { Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_OFF); - assertEquals("Off", mController.getSummary()); - Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON); - appRow.allowBubbles = false; + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); mController.onResume(appRow, null, null, null, null, null); - assertEquals("Off", mController.getSummary()); + String noneString = mContext.getString(R.string.bubble_app_setting_none); + assertEquals(noneString, mController.getSummary()); + } + + @Test + public void getSummary_BUBBLE_PREFERENCE_NONEisSelected_returnsNoneString() { + Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, + SYSTEM_WIDE_ON); + + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.bubblePreference = BUBBLE_PREFERENCE_NONE; + mController.onResume(appRow, null, null, null, null, null); + + String noneString = mContext.getString(R.string.bubble_app_setting_none); + assertEquals(noneString, mController.getSummary()); + } + + @Test + public void getSummary_BUBBLE_PREFERENCE_ALLisSelected_returnsAllString() { + Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, + SYSTEM_WIDE_ON); + + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.bubblePreference = BUBBLE_PREFERENCE_ALL; + mController.onResume(appRow, null, null, null, null, null); + + String allString = mContext.getString(R.string.bubble_app_setting_all); + assertEquals(allString, mController.getSummary()); + } + + @Test + public void getSummary_BUBBLE_PREFERENCE_SELECTEDisSelected_returnsSelectedString() { + Settings.Global.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, + SYSTEM_WIDE_ON); + + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.bubblePreference = BUBBLE_PREFERENCE_SELECTED; + mController.onResume(appRow, null, null, null, null, null); + + String selectedString = mContext.getString(R.string.bubble_app_setting_selected); + assertEquals(selectedString, mController.getSummary()); } }