diff --git a/res/xml/modes_other_settings.xml b/res/xml/modes_other_settings.xml new file mode 100644 index 00000000000..2dc2c7e0f61 --- /dev/null +++ b/res/xml/modes_other_settings.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/res/xml/modes_rule_settings.xml b/res/xml/modes_rule_settings.xml index 12a683e6bec..7a08a68d8c0 100644 --- a/res/xml/modes_rule_settings.xml +++ b/res/xml/modes_rule_settings.xml @@ -26,4 +26,8 @@ android:key="zen_mode_people" android:title="@string/zen_category_people"/> + + \ No newline at end of file diff --git a/src/com/android/settings/notification/modes/ZenModeFragment.java b/src/com/android/settings/notification/modes/ZenModeFragment.java index 1626d91bd85..51772f00a45 100644 --- a/src/com/android/settings/notification/modes/ZenModeFragment.java +++ b/src/com/android/settings/notification/modes/ZenModeFragment.java @@ -41,6 +41,8 @@ public class ZenModeFragment extends ZenModeFragmentBase { prefControllers.add(new ZenModeHeaderController(context, "header", this, mBackend)); prefControllers.add(new ZenModePeopleLinkPreferenceController( context, "zen_mode_people", mBackend)); + prefControllers.add(new ZenModeOtherLinkPreferenceController( + context, "zen_other_settings", mBackend)); return prefControllers; } diff --git a/src/com/android/settings/notification/modes/ZenModeOtherFragment.java b/src/com/android/settings/notification/modes/ZenModeOtherFragment.java new file mode 100644 index 00000000000..1149cd1312f --- /dev/null +++ b/src/com/android/settings/notification/modes/ZenModeOtherFragment.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2024 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.modes; + +import static android.service.notification.ZenPolicy.PRIORITY_CATEGORY_ALARMS; +import static android.service.notification.ZenPolicy.PRIORITY_CATEGORY_EVENTS; +import static android.service.notification.ZenPolicy.PRIORITY_CATEGORY_MEDIA; +import static android.service.notification.ZenPolicy.PRIORITY_CATEGORY_REMINDERS; +import static android.service.notification.ZenPolicy.PRIORITY_CATEGORY_SYSTEM; + +import android.app.settings.SettingsEnums; +import android.content.Context; +import com.android.settings.R; +import com.android.settingslib.core.AbstractPreferenceController; + +import java.util.ArrayList; +import java.util.List; + +/** + * Mode > Alarms & Other Interruptions + */ +public class ZenModeOtherFragment extends ZenModeFragmentBase { + + @Override + protected List createPreferenceControllers(Context context) { + List controllers = new ArrayList<>(); + controllers.add(new ZenModeOtherPreferenceController( + context, "modes_category_alarm", mBackend)); + controllers.add(new ZenModeOtherPreferenceController( + context, "modes_category_media", mBackend)); + controllers.add(new ZenModeOtherPreferenceController( + context, "modes_category_system", mBackend)); + controllers.add(new ZenModeOtherPreferenceController( + context, "modes_category_reminders", mBackend)); + controllers.add(new ZenModeOtherPreferenceController( + context, "modes_category_events", mBackend)); + return controllers; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.modes_other_settings; + } + + @Override + public int getMetricsCategory() { + // TODO: b/332937635 - make this the correct metrics category + return SettingsEnums.NOTIFICATION_ZEN_MODE_PRIORITY; + } +} diff --git a/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceController.java new file mode 100644 index 00000000000..a43f8b056e1 --- /dev/null +++ b/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceController.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2024 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.modes; + + +import static com.android.settings.notification.modes.ZenModeFragmentBase.MODE_ID; + +import android.content.Context; +import android.os.Bundle; +import androidx.preference.Preference; +import com.android.settings.core.SubSettingLauncher; + +/** + * Preference with a link and summary about what other sounds can break through the mode + */ +public class ZenModeOtherLinkPreferenceController extends AbstractZenModePreferenceController { + + ZenModeSummaryHelper mSummaryHelper; + + public ZenModeOtherLinkPreferenceController(Context context, String key, + ZenModesBackend backend) { + super(context, key, backend); + mSummaryHelper = new ZenModeSummaryHelper(mContext, mBackend); + } + + @Override + public void updateState(Preference preference) { + super.updateState(preference); + Bundle bundle = new Bundle(); + bundle.putString(MODE_ID, getMode().getId()); + preference.setIntent(new SubSettingLauncher(mContext) + .setDestination(ZenModeOtherFragment.class.getName()) + .setSourceMetricsCategory(0) + .setArguments(bundle) + .toIntent()); + preference.setSummary(mSummaryHelper.getOtherSoundCategoriesSummary(getMode())); + } +} diff --git a/src/com/android/settings/notification/modes/ZenModeOtherPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeOtherPreferenceController.java new file mode 100644 index 00000000000..e31fa0fa08b --- /dev/null +++ b/src/com/android/settings/notification/modes/ZenModeOtherPreferenceController.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 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.modes; + +import static android.service.notification.ZenPolicy.PRIORITY_CATEGORY_ALARMS; +import static android.service.notification.ZenPolicy.PRIORITY_CATEGORY_EVENTS; +import static android.service.notification.ZenPolicy.PRIORITY_CATEGORY_MEDIA; +import static android.service.notification.ZenPolicy.PRIORITY_CATEGORY_REMINDERS; +import static android.service.notification.ZenPolicy.PRIORITY_CATEGORY_SYSTEM; + +import android.content.Context; +import android.service.notification.ZenPolicy; +import androidx.preference.Preference; +import androidx.preference.TwoStatePreference; + +public class ZenModeOtherPreferenceController extends AbstractZenModePreferenceController + implements Preference.OnPreferenceChangeListener { + + public ZenModeOtherPreferenceController(Context context, String key, + ZenModesBackend backend) { + super(context, key, backend); + } + + @Override + public void updateState(Preference preference) { + super.updateState(preference); + + TwoStatePreference pref = (TwoStatePreference) preference; + pref.setChecked(getMode().getPolicy().isCategoryAllowed(getCategory(), true)); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final boolean allow = (Boolean) newValue; + + ZenPolicy diffPolicy = new ZenPolicy.Builder() + .allowCategory(getCategory(), allow) + .build(); + getMode().setPolicy(diffPolicy); + mBackend.updateMode(getMode()); + + return true; + } + + private int getCategory() { + switch (getPreferenceKey()) { + case "modes_category_alarm": + return PRIORITY_CATEGORY_ALARMS; + case "modes_category_media": + return PRIORITY_CATEGORY_MEDIA; + case "modes_category_system": + return PRIORITY_CATEGORY_SYSTEM; + case "modes_category_reminders": + return PRIORITY_CATEGORY_REMINDERS; + case "modes_category_events": + return PRIORITY_CATEGORY_EVENTS; + } + return -1; + } +} diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceControllerTest.java new file mode 100644 index 00000000000..26da6ab8dc6 --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeOtherLinkPreferenceControllerTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2024 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.modes; + +import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import android.app.AutomaticZenRule; +import android.app.Flags; +import android.content.Context; +import android.net.Uri; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; +import android.service.notification.ZenPolicy; +import androidx.preference.Preference; +import org.junit.Before; +import org.junit.Rule; +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) +@EnableFlags(Flags.FLAG_MODES_UI) +public final class ZenModeOtherLinkPreferenceControllerTest { + + private ZenModeOtherLinkPreferenceController mController; + + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + + private Context mContext; + @Mock + private ZenModesBackend mBackend; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + + mContext = RuntimeEnvironment.application; + + mController = new ZenModeOtherLinkPreferenceController( + mContext, "something", mBackend); + } + + @Test + @EnableFlags(Flags.FLAG_MODES_UI) + public void testHasSummary() { + Preference pref = mock(Preference.class); + ZenMode zenMode = new ZenMode("id", + new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) + .setType(AutomaticZenRule.TYPE_DRIVING) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder().allowAllSounds().build()) + .build(), true); + mController.updateZenMode(pref, zenMode); + verify(pref).setSummary(any()); + } +} \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeOtherPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeOtherPreferenceControllerTest.java new file mode 100644 index 00000000000..6dd918a145f --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeOtherPreferenceControllerTest.java @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2024 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.modes; + +import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY; +import static android.service.notification.ZenPolicy.STATE_ALLOW; +import static android.service.notification.ZenPolicy.STATE_UNSET; +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import android.app.AutomaticZenRule; +import android.app.Flags; +import android.content.Context; +import android.net.Uri; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; +import android.service.notification.ZenPolicy; +import androidx.preference.TwoStatePreference; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +@EnableFlags(Flags.FLAG_MODES_UI) +public final class ZenModeOtherPreferenceControllerTest { + + private Context mContext; + @Mock + private ZenModesBackend mBackend; + + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + } + + @Test + public void testUpdateState_alarms() { + TwoStatePreference preference = mock(TwoStatePreference.class); + ZenMode zenMode = new ZenMode("id", + new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) + .setType(AutomaticZenRule.TYPE_DRIVING) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder().allowAlarms(true).build()) + .build(), true); + + ZenModeOtherPreferenceController controller = + new ZenModeOtherPreferenceController(mContext, "modes_category_alarm", mBackend); + + controller.updateZenMode(preference, zenMode); + + verify(preference).setChecked(true); + } + + @Test + public void testOnPreferenceChange_alarms() { + TwoStatePreference preference = mock(TwoStatePreference.class); + ZenMode zenMode = new ZenMode("id", + new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) + .setType(AutomaticZenRule.TYPE_DRIVING) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder().allowAlarms(false).build()) + .build(), true); + + ZenModeOtherPreferenceController controller = + new ZenModeOtherPreferenceController(mContext, "modes_category_alarm", mBackend); + + controller.updateZenMode(preference, zenMode); + + controller.onPreferenceChange(preference, true); + + ArgumentCaptor captor = ArgumentCaptor.forClass(ZenMode.class); + verify(mBackend).updateMode(captor.capture()); + assertThat(captor.getValue().getPolicy().getPriorityCategoryAlarms()) + .isEqualTo(STATE_ALLOW); + assertThat(captor.getValue().getPolicy().getPriorityCategoryEvents()) + .isEqualTo(STATE_UNSET); + } + + @Test + public void testUpdateState_media() { + TwoStatePreference preference = mock(TwoStatePreference.class); + ZenMode zenMode = new ZenMode("id", + new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) + .setType(AutomaticZenRule.TYPE_DRIVING) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder().allowMedia(true).build()) + .build(), true); + + ZenModeOtherPreferenceController controller = + new ZenModeOtherPreferenceController(mContext, "modes_category_media", mBackend); + + controller.updateZenMode(preference, zenMode); + + verify(preference).setChecked(true); + } + + @Test + public void testOnPreferenceChange_media() { + TwoStatePreference preference = mock(TwoStatePreference.class); + ZenMode zenMode = new ZenMode("id", + new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) + .setType(AutomaticZenRule.TYPE_DRIVING) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder().allowMedia(false).build()) + .build(), true); + + ZenModeOtherPreferenceController controller = + new ZenModeOtherPreferenceController(mContext, "modes_category_media", mBackend); + + controller.updateZenMode(preference, zenMode); + + controller.onPreferenceChange(preference, true); + + ArgumentCaptor captor = ArgumentCaptor.forClass(ZenMode.class); + verify(mBackend).updateMode(captor.capture()); + assertThat(captor.getValue().getPolicy().getPriorityCategoryMedia()) + .isEqualTo(STATE_ALLOW); + assertThat(captor.getValue().getPolicy().getPriorityCategoryEvents()) + .isEqualTo(STATE_UNSET); + } + + @Test + public void testUpdateState_system() { + TwoStatePreference preference = mock(TwoStatePreference.class); + ZenMode zenMode = new ZenMode("id", + new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) + .setType(AutomaticZenRule.TYPE_DRIVING) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder().allowSystem(true).build()) + .build(), true); + + ZenModeOtherPreferenceController controller = + new ZenModeOtherPreferenceController(mContext, "modes_category_system", mBackend); + + controller.updateZenMode(preference, zenMode); + + verify(preference).setChecked(true); + } + + @Test + public void testOnPreferenceChange_system() { + TwoStatePreference preference = mock(TwoStatePreference.class); + ZenMode zenMode = new ZenMode("id", + new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) + .setType(AutomaticZenRule.TYPE_DRIVING) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder().allowSystem(false).build()) + .build(), true); + + ZenModeOtherPreferenceController controller = + new ZenModeOtherPreferenceController(mContext, "modes_category_system", mBackend); + + controller.updateZenMode(preference, zenMode); + + controller.onPreferenceChange(preference, true); + + ArgumentCaptor captor = ArgumentCaptor.forClass(ZenMode.class); + verify(mBackend).updateMode(captor.capture()); + assertThat(captor.getValue().getPolicy().getPriorityCategorySystem()) + .isEqualTo(STATE_ALLOW); + assertThat(captor.getValue().getPolicy().getPriorityCategoryEvents()) + .isEqualTo(STATE_UNSET); + } + + @Test + public void testUpdateState_reminders() { + TwoStatePreference preference = mock(TwoStatePreference.class); + ZenMode zenMode = new ZenMode("id", + new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) + .setType(AutomaticZenRule.TYPE_DRIVING) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder().allowReminders(true).build()) + .build(), true); + + ZenModeOtherPreferenceController controller = + new ZenModeOtherPreferenceController(mContext, "modes_category_reminders", + mBackend); + + controller.updateZenMode(preference, zenMode); + + verify(preference).setChecked(true); + } + + @Test + public void testOnPreferenceChange_reminders() { + TwoStatePreference preference = mock(TwoStatePreference.class); + ZenMode zenMode = new ZenMode("id", + new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) + .setType(AutomaticZenRule.TYPE_DRIVING) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder().allowReminders(false).build()) + .build(), true); + + ZenModeOtherPreferenceController controller = + new ZenModeOtherPreferenceController(mContext, "modes_category_reminders", + mBackend); + + controller.updateZenMode(preference, zenMode); + + controller.onPreferenceChange(preference, true); + + ArgumentCaptor captor = ArgumentCaptor.forClass(ZenMode.class); + verify(mBackend).updateMode(captor.capture()); + assertThat(captor.getValue().getPolicy().getPriorityCategoryReminders()) + .isEqualTo(STATE_ALLOW); + assertThat(captor.getValue().getPolicy().getPriorityCategoryEvents()) + .isEqualTo(STATE_UNSET); + } + + @Test + public void testUpdateState_events() { + TwoStatePreference preference = mock(TwoStatePreference.class); + ZenMode zenMode = new ZenMode("id", + new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) + .setType(AutomaticZenRule.TYPE_DRIVING) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder().allowEvents(true).build()) + .build(), true); + + ZenModeOtherPreferenceController controller = + new ZenModeOtherPreferenceController(mContext, "modes_category_events", mBackend); + + controller.updateZenMode(preference, zenMode); + + verify(preference).setChecked(true); + } + + @Test + public void testOnPreferenceChange_events() { + TwoStatePreference preference = mock(TwoStatePreference.class); + ZenMode zenMode = new ZenMode("id", + new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) + .setType(AutomaticZenRule.TYPE_DRIVING) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder().allowEvents(false).build()) + .build(), true); + + ZenModeOtherPreferenceController controller = + new ZenModeOtherPreferenceController(mContext, "modes_category_events", mBackend); + + controller.updateZenMode(preference, zenMode); + + controller.onPreferenceChange(preference, true); + + ArgumentCaptor captor = ArgumentCaptor.forClass(ZenMode.class); + verify(mBackend).updateMode(captor.capture()); + assertThat(captor.getValue().getPolicy().getPriorityCategoryEvents()) + .isEqualTo(STATE_ALLOW); + assertThat(captor.getValue().getPolicy().getPriorityCategoryAlarms()) + .isEqualTo(STATE_UNSET); + } +} \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeRepeatCallersPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeRepeatCallersPreferenceControllerTest.java new file mode 100644 index 00000000000..7bbb042c471 --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeRepeatCallersPreferenceControllerTest.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2024 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.modes; + +import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY; +import static android.service.notification.ZenPolicy.PEOPLE_TYPE_ANYONE; +import static android.service.notification.ZenPolicy.PEOPLE_TYPE_STARRED; +import static android.service.notification.ZenPolicy.STATE_ALLOW; +import static android.service.notification.ZenPolicy.STATE_DISALLOW; +import static android.service.notification.ZenPolicy.STATE_UNSET; +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import android.app.AutomaticZenRule; +import android.app.Flags; +import android.content.Context; +import android.net.Uri; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; +import android.service.notification.ZenPolicy; +import androidx.preference.TwoStatePreference; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +@EnableFlags(Flags.FLAG_MODES_UI) +public final class ZenModeRepeatCallersPreferenceControllerTest { + + private Context mContext; + @Mock + private ZenModesBackend mBackend; + + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + } + + @Test + public void testUpdateState_allCalls() { + TwoStatePreference preference = mock(TwoStatePreference.class); + ZenMode zenMode = new ZenMode("id", + new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) + .setType(AutomaticZenRule.TYPE_DRIVING) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder() + .allowCalls(PEOPLE_TYPE_ANYONE) + .build()) + .build(), true); + + ZenModeRepeatCallersPreferenceController controller = + new ZenModeRepeatCallersPreferenceController(mContext, "repeat", mBackend, 1); + + controller.updateZenMode(preference, zenMode); + + verify(preference).setChecked(true); + verify(preference).setEnabled(false); + } + + @Test + public void testUpdateState_someCalls() { + TwoStatePreference preference = mock(TwoStatePreference.class); + ZenMode zenMode = new ZenMode("id", + new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) + .setType(AutomaticZenRule.TYPE_DRIVING) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder() + .allowCalls(PEOPLE_TYPE_STARRED) + .allowRepeatCallers(true) + .build()) + .build(), true); + + ZenModeRepeatCallersPreferenceController controller = + new ZenModeRepeatCallersPreferenceController(mContext, "repeat", mBackend, 1); + + controller.updateZenMode(preference, zenMode); + + verify(preference).setChecked(true); + verify(preference).setEnabled(true); + } + + @Test + public void testOnPreferenceChange() { + TwoStatePreference preference = mock(TwoStatePreference.class); + ZenMode zenMode = new ZenMode("id", + new AutomaticZenRule.Builder("Driving", Uri.parse("drive")) + .setType(AutomaticZenRule.TYPE_DRIVING) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder().allowRepeatCallers(true).build()) + .build(), true); + + ZenModeRepeatCallersPreferenceController controller = + new ZenModeRepeatCallersPreferenceController(mContext, "repeat", mBackend, 1); + + controller.updateZenMode(preference, zenMode); + + controller.onPreferenceChange(preference, false); + + ArgumentCaptor captor = ArgumentCaptor.forClass(ZenMode.class); + verify(mBackend).updateMode(captor.capture()); + assertThat(captor.getValue().getPolicy().getPriorityCategoryRepeatCallers()) + .isEqualTo(STATE_DISALLOW); + assertThat(captor.getValue().getPolicy().getPriorityCategoryEvents()) + .isEqualTo(STATE_UNSET); + assertThat(captor.getValue().getPolicy().getPriorityCallSenders()) + .isEqualTo(STATE_UNSET); + } +} \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModesSummaryHelperTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModesSummaryHelperTest.java index 621c5b06f9d..67be82f9032 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModesSummaryHelperTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModesSummaryHelperTest.java @@ -85,4 +85,84 @@ public class ZenModesSummaryHelperTest { assertThat(mSummaryHelper.getPeopleSummary(zenMode)).isEqualTo("All people can interrupt"); } + + @Test + public void getOtherSoundCategoriesSummary_single() { + AutomaticZenRule rule = new AutomaticZenRule.Builder("Bedtime", Uri.parse("bed")) + .setType(AutomaticZenRule.TYPE_BEDTIME) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder().allowAlarms(true).build()) + .build(); + ZenMode zenMode = new ZenMode("id", rule, true); + + assertThat(mSummaryHelper.getOtherSoundCategoriesSummary(zenMode)).isEqualTo( + "Alarms can interrupt"); + } + + @Test + public void getOtherSoundCategoriesSummary_duo() { + AutomaticZenRule rule = new AutomaticZenRule.Builder("Bedtime", Uri.parse("bed")) + .setType(AutomaticZenRule.TYPE_BEDTIME) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder().allowAlarms(true).allowMedia(true).build()) + .build(); + ZenMode zenMode = new ZenMode("id", rule, true); + + assertThat(mSummaryHelper.getOtherSoundCategoriesSummary(zenMode)).isEqualTo( + "Alarms and media can interrupt"); + } + + @Test + public void getOtherSoundCategoriesSummary_trio() { + AutomaticZenRule rule = new AutomaticZenRule.Builder("Bedtime", Uri.parse("bed")) + .setType(AutomaticZenRule.TYPE_BEDTIME) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder() + .allowAlarms(true) + .allowMedia(true) + .allowSystem(true) + .build()) + .build(); + ZenMode zenMode = new ZenMode("id", rule, true); + + assertThat(mSummaryHelper.getOtherSoundCategoriesSummary(zenMode)).isEqualTo( + "Alarms, media, and touch sounds can interrupt"); + } + + @Test + public void getOtherSoundCategoriesSummary_quad() { + AutomaticZenRule rule = new AutomaticZenRule.Builder("Bedtime", Uri.parse("bed")) + .setType(AutomaticZenRule.TYPE_BEDTIME) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder() + .allowAlarms(true) + .allowMedia(true) + .allowSystem(true) + .allowReminders(true) + .build()) + .build(); + ZenMode zenMode = new ZenMode("id", rule, true); + + assertThat(mSummaryHelper.getOtherSoundCategoriesSummary(zenMode)).isEqualTo( + "Alarms, media, and 2 more can interrupt"); + } + + @Test + public void getOtherSoundCategoriesSummary_all() { + AutomaticZenRule rule = new AutomaticZenRule.Builder("Bedtime", Uri.parse("bed")) + .setType(AutomaticZenRule.TYPE_BEDTIME) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder() + .allowAlarms(true) + .allowMedia(true) + .allowSystem(true) + .allowReminders(true) + .allowEvents(true) + .build()) + .build(); + ZenMode zenMode = new ZenMode("id", rule, true); + + assertThat(mSummaryHelper.getOtherSoundCategoriesSummary(zenMode)).isEqualTo( + "Alarms, media, and 3 more can interrupt"); + } }