PreferenceControllers are the way of the future.

Migrates Notification settings (app level, group level, and channel
level) into PreferenceControllers (and most importantly:
PreferenceControllerTest)

Note: this removes the 'Advanced' preference group, but does
not yet use the standard system 'Advanced' grouping as it does
not currently support our use case (where we don't know how many
fields to show outside of 'Advanced' until onResume() and also
where we need fields to show below the 'Advanced' group).

Test: make RunSettingsRoboTests
Change-Id: Iddd1b4771922db322e5f73562e9d63ed077c5396
This commit is contained in:
Julia Reynolds
2017-10-13 15:12:07 -04:00
parent 187ff21a7c
commit ac3f7e80dc
44 changed files with 5332 additions and 1024 deletions

View File

@@ -0,0 +1,244 @@
/*
* Copyright (C) 2017 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.app.NotificationChannel.DEFAULT_CHANNEL_ID;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
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.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
public class AllowSoundPreferenceControllerTest {
private Context mContext;
@Mock
private NotificationBackend mBackend;
@Mock
private NotificationManager mNm;
@Mock
private UserManager mUm;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceScreen mScreen;
@Mock
NotificationSettingsBase.ImportanceListener mImportanceListener;
private AllowSoundPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
mContext = shadowApplication.getApplicationContext();
mController =
spy(new AllowSoundPreferenceController(mContext, mImportanceListener, mBackend));
}
@Test
public void testNoCrashIfNoOnResume() throws Exception {
mController.isAvailable();
mController.updateState(mock(RestrictedSwitchPreference.class));
mController.onPreferenceChange(mock(RestrictedSwitchPreference.class), true);
}
@Test
public void testIsAvailable_notIfNull() throws Exception {
mController.onResume(null, mock(NotificationChannel.class), null, null);
assertFalse(mController.isAvailable());
mController.onResume(mock(NotificationBackend.AppRow.class), null, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfAppBlocked() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.banned = true;
mController.onResume(appRow, mock(NotificationChannel.class), null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfAppCreatedChannel() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn("something new");
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
mController.onResume(appRow, channel, null, null);
assertTrue(mController.isAvailable());
}
@Test
public void testUpdateState_disabledByAdmin() throws Exception {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn("something");
mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
RestrictedLockUtils.EnforcedAdmin.class));
Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertFalse(pref.isEnabled());
}
@Test
public void testUpdateState_notConfigurable() throws Exception {
String lockedId = "locked";
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.lockedChannelId = lockedId;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn(lockedId);
mController.onResume(appRow, channel, null, null);
Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertFalse(pref.isEnabled());
}
@Test
public void testUpdateState_configurable() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn("something");
mController.onResume(appRow, channel, null, null);
Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertTrue(pref.isEnabled());
}
@Test
public void testUpdateState_checkedForHighImportanceChannel() throws Exception {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertTrue(pref.isChecked());
}
@Test
public void testUpdateState_checkedForUnspecifiedImportanceChannel() throws Exception {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_UNSPECIFIED);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
RestrictedSwitchPreference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertTrue(pref.isChecked());
}
@Test
public void testUpdateState_notCheckedForLowImportanceChannel() throws Exception {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertFalse(pref.isChecked());
}
@Test
public void testOnPreferenceChange_on() {
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_LOW);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
pref.setChecked(true);
mController.onPreferenceChange(pref, true);
assertEquals(IMPORTANCE_UNSPECIFIED, mController.mChannel.getImportance());
verify(mImportanceListener, times(1)).onImportanceChanged();
}
@Test
public void testOnPreferenceChange_off() {
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
pref.setChecked(false);
mController.onPreferenceChange(pref, false);
verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
assertEquals(IMPORTANCE_LOW, mController.mChannel.getImportance());
verify(mImportanceListener, times(1)).onImportanceChanged();
}
}

View File

@@ -0,0 +1,135 @@
/*
* Copyright (C) 2017 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.app.NotificationChannel.DEFAULT_CHANNEL_ID;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
public class AppLinkPreferenceControllerTest {
private Context mContext;
@Mock
private NotificationManager mNm;
@Mock
private UserManager mUm;
private AppLinkPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
mContext = shadowApplication.getApplicationContext();
mController = spy(new AppLinkPreferenceController(mContext));
}
@Test
public void testNoCrashIfNoOnResume() throws Exception {
mController.isAvailable();
mController.updateState(mock(Preference.class));
}
@Test
public void testIsAvailable_notIfNull() throws Exception {
mController.onResume(null, null, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfAppBlocked() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.banned = true;
mController.onResume(appRow, null, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfChannelBlocked() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notNoIntent() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.settingsIntent = new Intent("test");
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
mController.onResume(appRow, channel, null, null);
assertTrue(mController.isAvailable());
}
@Test
public void testUpdateState() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
Intent intent = new Intent("action");
appRow.settingsIntent = intent;
mController.onResume(appRow, null, null, null);
Preference pref = new Preference(RuntimeEnvironment.application);
mController.updateState(pref);
assertEquals(intent, pref.getIntent());
}
}

View File

@@ -0,0 +1,298 @@
/*
* Copyright (C) 2017 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.app.NotificationChannel.DEFAULT_CHANNEL_ID;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import static android.provider.Settings.Secure.NOTIFICATION_BADGING;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
import android.os.UserManager;
import android.provider.Settings;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
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.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
public class BadgePreferenceControllerTest {
private Context mContext;
@Mock
private NotificationBackend mBackend;
@Mock
private NotificationManager mNm;
@Mock
private UserManager mUm;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceScreen mScreen;
private BadgePreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
mContext = shadowApplication.getApplicationContext();
mController = spy(new BadgePreferenceController(mContext, mBackend));
}
@Test
public void testNoCrashIfNoOnResume() throws Exception {
mController.isAvailable();
mController.updateState(mock(RestrictedSwitchPreference.class));
mController.onPreferenceChange(mock(RestrictedSwitchPreference.class), true);
}
@Test
public void testIsAvailable_notIfAppBlocked() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.banned = true;
mController.onResume(appRow, mock(NotificationChannel.class), null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfChannelBlocked() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_channel_notIfAppOff() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.showBadge = false;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfOffGlobally() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BADGING, 0);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_app() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
mController.onResume(appRow, null, null, null);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BADGING, 1);
assertTrue(mController.isAvailable());
}
@Test
public void testIsAvailable_channel() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.showBadge = true;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BADGING, 1);
assertTrue(mController.isAvailable());
}
@Test
public void testUpdateState_disabledByAdmin() throws Exception {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn("something");
mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
RestrictedLockUtils.EnforcedAdmin.class));
Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertFalse(pref.isEnabled());
}
@Test
public void testUpdateState_channelNotConfigurable() throws Exception {
String lockedId = "locked";
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.lockedChannelId = lockedId;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn(lockedId);
mController.onResume(appRow, channel, null, null);
Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertFalse(pref.isEnabled());
}
@Test
public void testUpdateState_channel() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.lockedChannelId = "a";
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.canShowBadge()).thenReturn(true);
mController.onResume(appRow, channel, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertTrue(pref.isChecked());
when(channel.canShowBadge()).thenReturn(false);
mController.onResume(appRow, channel, null, null);
mController.updateState(pref);
assertFalse(pref.isChecked());
}
@Test
public void testUpdateState_app() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.showBadge = true;
mController.onResume(appRow, null, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertTrue(pref.isChecked());
appRow.showBadge = false;
mController.onResume(appRow, null, null, null);
mController.updateState(pref);
assertFalse(pref.isChecked());
}
@Test
public void testOnPreferenceChange_on_channel() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.showBadge = true;
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_LOW);
channel.setShowBadge(false);
mController.onResume(appRow, channel, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
mController.onPreferenceChange(pref, true);
assertTrue(channel.canShowBadge());
verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
}
@Test
public void testOnPreferenceChange_off_channel() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.showBadge = true;
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
channel.setShowBadge(true);
mController.onResume(appRow, channel, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
mController.onPreferenceChange(pref, false);
verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
assertFalse(channel.canShowBadge());
}
@Test
public void testOnPreferenceChange_on_app() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.showBadge = false;
mController.onResume(appRow, null, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
mController.onPreferenceChange(pref, true);
assertTrue(appRow.showBadge);
verify(mBackend, times(1)).setShowBadge(any(), anyInt(), eq(true));
}
@Test
public void testOnPreferenceChange_off_app() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.showBadge = true;
mController.onResume(appRow, null, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
mController.onPreferenceChange(pref, false);
assertFalse(appRow.showBadge);
verify(mBackend, times(1)).setShowBadge(any(), anyInt(), eq(false));
}
}

View File

@@ -0,0 +1,272 @@
/*
* Copyright (C) 2017 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.app.NotificationChannel.DEFAULT_CHANNEL_ID;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
import android.os.UserManager;
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.widget.SwitchBar;
import com.android.settings.wrapper.NotificationChannelGroupWrapper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
public class BlockPreferenceControllerTest {
private Context mContext;
@Mock
private NotificationBackend mBackend;
@Mock
private NotificationManager mNm;
@Mock
private UserManager mUm;
@Mock
NotificationSettingsBase.ImportanceListener mImportanceListener;
private BlockPreferenceController mController;
@Mock
private LayoutPreference mPreference;
private SwitchBar mSwitch;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
mContext = shadowApplication.getApplicationContext();
mController = spy(new BlockPreferenceController(mContext, mImportanceListener, mBackend));
mSwitch = new SwitchBar(mContext);
when(mPreference.findViewById(R.id.switch_bar)).thenReturn(mSwitch);
}
@Test
public void testNoCrashIfNoOnResume() throws Exception {
mController.isAvailable();
mController.updateState(mock(LayoutPreference.class));
mController.onSwitchChanged(null, false);
}
@Test
public void testIsAvailable_notIfNull() throws Exception {
mController.onResume(null, null, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfChannelNotBlockable() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.systemApp = true;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfGroupNotBlockable() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.systemApp = true;
mController.onResume(appRow, null, mock(NotificationChannelGroupWrapper.class), null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfAppNotBlockable() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.systemApp = true;
mController.onResume(appRow, null, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_systemApp() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.systemApp = true;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
mController.onResume(appRow, channel, null, null);
assertTrue(mController.isAvailable());
}
@Test
public void testIsAvailable_nonSystemApp() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.systemApp = false;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
assertTrue(mController.isAvailable());
}
@Test
public void testUpdateState_app() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.banned = true;
mController.onResume(appRow, null, null, null);
mController.updateState(mPreference);
assertNotNull(mPreference.findViewById(R.id.switch_bar));
assertFalse(mSwitch.isChecked());
appRow.banned = false;
mController.onResume(appRow, null, null, null);
mController.updateState(mPreference);
assertTrue(mSwitch.isChecked());
}
@Test
public void testUpdateState_group() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
when(group.getGroup()).thenReturn(mock(NotificationChannelGroup.class));
when(group.isBlocked()).thenReturn(true);
mController.onResume(appRow, null, group, null);
mController.updateState(mPreference);
assertFalse(mSwitch.isChecked());
appRow.banned = true;
mController.onResume(appRow, null, group, null);
when(group.isBlocked()).thenReturn(true);
mController.updateState(mPreference);
assertFalse(mSwitch.isChecked());
appRow.banned = false;
mController.onResume(appRow, null, group, null);
when(group.isBlocked()).thenReturn(false);
mController.updateState(mPreference);
assertTrue(mSwitch.isChecked());
}
@Test
public void testUpdateState_channelBlocked() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_NONE);
mController.onResume(appRow, channel, null, null);
mController.updateState(mPreference);
assertFalse(mSwitch.isChecked());
appRow.banned = true;
channel = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
mController.updateState(mPreference);
assertFalse(mSwitch.isChecked());
appRow.banned = false;
channel = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
mController.updateState(mPreference);
assertTrue(mSwitch.isChecked());
}
@Test
public void testUpdateState_noCrashIfCalledTwice() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
mController.onResume(appRow, channel, null, null);
mController.updateState(mPreference);
mController.updateState(mPreference);
}
@Test
public void testUpdateState_doesNotResetImportance() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
mController.onResume(appRow, channel, null, null);
mController.updateState(mPreference);
assertEquals(IMPORTANCE_LOW, channel.getImportance());
}
@Test
public void testOnSwitchChanged_channel_default() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_UNSPECIFIED);
mController.onResume(appRow, channel, null, null);
mController.updateState(mPreference);
mController.onSwitchChanged(null, false);
assertEquals(IMPORTANCE_NONE, channel.getImportance());
mController.onSwitchChanged(null, true);
assertEquals(IMPORTANCE_UNSPECIFIED, channel.getImportance());
verify(mBackend, times(2)).updateChannel(any(), anyInt(), any());
}
@Test
public void testOnSwitchChanged_channel_nonDefault() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
mController.updateState(mPreference);
mController.onSwitchChanged(null, false);
assertEquals(IMPORTANCE_NONE, channel.getImportance());
mController.onSwitchChanged(null, true);
assertEquals(IMPORTANCE_DEFAULT, channel.getImportance());
verify(mBackend, times(2)).updateChannel(any(), anyInt(), any());
}
}

View File

@@ -0,0 +1,129 @@
/*
* Copyright (C) 2017 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 junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import com.android.settings.TestConfig;
import com.android.settings.wrapper.NotificationChannelGroupWrapper;
import org.junit.Before;
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.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@RunWith(RobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class DeletedChannelsPreferenceControllerTest {
private Context mContext;
@Mock
private NotificationBackend mBackend;
@Mock
private NotificationManager mNm;
@Mock
private UserManager mUm;
private DeletedChannelsPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
mContext = shadowApplication.getApplicationContext();
mController = new DeletedChannelsPreferenceController(mContext, mBackend);
}
@Test
public void noCrashIfNoOnResume() throws Exception {
mController.isAvailable();
mController.updateState(mock(Preference.class));
}
@Test
public void isAvailable_appScreen_notIfAppBlocked() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.banned = true;
mController.onResume(appRow, null, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void isAvailable_groupScreen_never() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
mController.onResume(appRow, null, mock(NotificationChannelGroupWrapper.class), null);
assertFalse(mController.isAvailable());
}
@Test
public void isAvailable_channelScreen_never() throws Exception {
mController.onResume(
new NotificationBackend.AppRow(), mock(NotificationChannel.class), null, null);
assertFalse(mController.isAvailable());
}
@Test
public void isAvailable_appScreen_notIfNoDeletedChannels() throws Exception {
when(mBackend.getDeletedChannelCount(any(), anyInt())).thenReturn(0);
mController.onResume(new NotificationBackend.AppRow(), null, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void isAvailable_appScreen() throws Exception {
when(mBackend.getDeletedChannelCount(any(), anyInt())).thenReturn(1);
mController.onResume(new NotificationBackend.AppRow(), null, null, null);
assertTrue(mController.isAvailable());
}
@Test
public void updateState() throws Exception {
when(mBackend.getDeletedChannelCount(any(), anyInt())).thenReturn(1);
mController.onResume(new NotificationBackend.AppRow(), null, null, null);
Preference pref = mock(Preference.class);
mController.updateState(pref);
verify(pref, times(1)).setEnabled(false);
verify(pref, times(1)).setSelectable(false);
verify(mBackend, times(1)).getDeletedChannelCount(any(), anyInt());
ArgumentCaptor<CharSequence> argumentCaptor = ArgumentCaptor.forClass(CharSequence.class);
verify(pref, times(1)).setTitle(argumentCaptor.capture());
assertTrue(argumentCaptor.getValue().toString().contains("1"));
}
}

View File

@@ -0,0 +1,175 @@
/*
* Copyright (C) 2017 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.app.NotificationChannel.DEFAULT_CHANNEL_ID;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.wrapper.NotificationChannelGroupWrapper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
public class DescriptionPreferenceControllerTest {
private Context mContext;
@Mock
private NotificationManager mNm;
@Mock
private UserManager mUm;
private DescriptionPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
mContext = shadowApplication.getApplicationContext();
mController = spy(new DescriptionPreferenceController(mContext));
}
@Test
public void testNoCrashIfNoOnResume() throws Exception {
mController.isAvailable();
mController.updateState(mock(Preference.class));
}
@Test
public void testIsAvailable_notIfNull() throws Exception {
mController.onResume(null, null, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfChannelGroupBlocked() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
when(group.isBlocked()).thenReturn(true);
mController.onResume(appRow, null, group, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfChannelBlocked() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfNoChannelDesc() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfNoChannelGroupDesc() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
when(group.getGroup()).thenReturn(mock(NotificationChannelGroup.class));
mController.onResume(appRow, null, group, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_channel() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
when(channel.getDescription()).thenReturn("AAA");
mController.onResume(appRow, channel, null, null);
assertTrue(mController.isAvailable());
}
@Test
public void testIsAvailable_channelGroup() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
when(group.getGroup()).thenReturn(mock(NotificationChannelGroup.class));
when(group.getDescription()).thenReturn("something");
when(group.isBlocked()).thenReturn(false);
mController.onResume(appRow, null, group, null);
assertTrue(mController.isAvailable());
}
@Test
public void testUpdateState_channel() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
when(channel.getDescription()).thenReturn("AAA");
mController.onResume(appRow, channel, null, null);
Preference pref = new Preference(RuntimeEnvironment.application);
mController.updateState(pref);
assertEquals("AAA", pref.getTitle());
assertFalse(pref.isEnabled());
assertFalse(pref.isSelectable());
}
@Test
public void testUpdateState_channelGroup() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
when(group.getGroup()).thenReturn(mock(NotificationChannelGroup.class));
when(group.getDescription()).thenReturn("something");
mController.onResume(appRow, null, group, null);
Preference pref = new Preference(RuntimeEnvironment.application);
mController.updateState(pref);
assertEquals("something", pref.getTitle());
assertFalse(pref.isEnabled());
assertFalse(pref.isSelectable());
}
}

View File

@@ -0,0 +1,240 @@
/*
* Copyright (C) 2017 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.app.NotificationChannel.DEFAULT_CHANNEL_ID;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_MIN;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
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.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
public class DndPreferenceControllerTest {
private Context mContext;
@Mock
private NotificationBackend mBackend;
@Mock
private NotificationManager mNm;
@Mock
private UserManager mUm;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceScreen mScreen;
@Mock
private Lifecycle mLifecycle;
private DndPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
mContext = shadowApplication.getApplicationContext();
mController = spy(new DndPreferenceController(mContext, mLifecycle, mBackend));
}
@Test
public void testNoCrashIfNoOnResume() throws Exception {
mController.isAvailable();
mController.updateState(mock(RestrictedSwitchPreference.class));
mController.onPreferenceChange(mock(RestrictedSwitchPreference.class), true);
mController.onResume();
}
@Test
public void testIsAvailable_notIfNotImportant_noVisEffects() throws Exception {
when(mNm.getNotificationPolicy()).thenReturn(new NotificationManager.Policy(0, 0, 0, 0));
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_LOW);
mController.onResume();
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfNotImportant_visEffects() throws Exception {
when(mNm.getNotificationPolicy()).thenReturn(new NotificationManager.Policy(0, 0, 0, 1));
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_MIN);
mController.onResume();
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_importance_noVisEffects() throws Exception {
when(mNm.getNotificationPolicy()).thenReturn(new NotificationManager.Policy(0, 0, 0, 0));
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
mController.onResume();
mController.onResume(appRow, channel, null, null);
assertTrue(mController.isAvailable());
}
@Test
public void testIsAvailable_important_visEffects() throws Exception {
when(mNm.getNotificationPolicy()).thenReturn(new NotificationManager.Policy(0, 0, 0, 1));
assertTrue(mNm.getNotificationPolicy().suppressedVisualEffects != 0);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_LOW);
mController.onResume();
mController.onResume(appRow, channel, null, null);
assertTrue(mController.isAvailable());
}
@Test
public void testUpdateState_disabledByAdmin() throws Exception {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn("something");
mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
RestrictedLockUtils.EnforcedAdmin.class));
Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertFalse(pref.isEnabled());
}
@Test
public void testUpdateState_notConfigurable() throws Exception {
String lockedId = "locked";
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.lockedChannelId = lockedId;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn(lockedId);
mController.onResume(appRow, channel, null, null);
Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertFalse(pref.isEnabled());
}
@Test
public void testUpdateState_configurable() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn("something");
mController.onResume(appRow, channel, null, null);
Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertTrue(pref.isEnabled());
}
@Test
public void testUpdateState_bypassDnd() throws Exception {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.canBypassDnd()).thenReturn(true);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertTrue(pref.isChecked());
}
@Test
public void testUpdateState_noBypassDnd() throws Exception {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.canBypassDnd()).thenReturn(false);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertFalse(pref.isChecked());
}
@Test
public void testOnPreferenceChange_on() {
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_LOW);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
mController.onPreferenceChange(pref, true);
assertTrue(channel.canBypassDnd());
verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
}
@Test
public void testOnPreferenceChange_off() {
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
mController.onPreferenceChange(pref, false);
assertFalse(channel.canBypassDnd());
verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
}
}

View File

@@ -0,0 +1,146 @@
/*
* Copyright (C) 2017 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.app.NotificationManager.IMPORTANCE_NONE;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Activity;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
import android.os.UserManager;
import android.support.v14.preference.PreferenceFragment;
import android.view.View;
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.wrapper.NotificationChannelGroupWrapper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
public class HeaderPreferenceControllerTest {
private Context mContext;
@Mock
private NotificationManager mNm;
@Mock
private UserManager mUm;
private HeaderPreferenceController mController;
@Mock
private LayoutPreference mPreference;
@Mock
private View mView;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
mContext = shadowApplication.getApplicationContext();
PreferenceFragment fragment = mock(PreferenceFragment.class);
when(fragment.getContext()).thenReturn(mContext);
Activity activity = mock(Activity.class);
when(activity.getApplicationContext()).thenReturn(mContext);
when(fragment.getActivity()).thenReturn(activity);
mController = spy(new HeaderPreferenceController(mContext, fragment));
when(mPreference.findViewById(anyInt())).thenReturn(mView);
}
@Test
public void testNoCrashIfNoOnResume() throws Exception {
mController.isAvailable();
mController.updateState(mock(LayoutPreference.class));
}
@Test
public void testIsAvailable_notIfNull() throws Exception {
mController.onResume(null, null, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.banned = true;
mController.onResume(appRow, null, null, null);
assertTrue(mController.isAvailable());
}
@Test
public void testGetLabel() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.label = "bananas";
mController.onResume(appRow, null, null, null);
assertEquals(appRow.label, mController.getLabel());
NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
NotificationChannelGroupWrapper gWrapper = new NotificationChannelGroupWrapper(group);
mController.onResume(appRow, null, gWrapper, null);
assertEquals(group.getName(), mController.getLabel());
NotificationChannel channel = new NotificationChannel("cid", "cname", IMPORTANCE_NONE);
mController.onResume(appRow, channel, gWrapper, null);
assertEquals(channel.getName(), mController.getLabel());
}
@Test
public void testGetSummary() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.label = "bananas";
mController.onResume(appRow, null, null, null);
assertEquals("", mController.getSummary());
NotificationChannelGroup group = new NotificationChannelGroup("id", "name");
NotificationChannelGroupWrapper gWrapper = new NotificationChannelGroupWrapper(group);
mController.onResume(appRow, null, gWrapper, null);
assertEquals(appRow.label, mController.getSummary());
NotificationChannel channel = new NotificationChannel("cid", "cname", IMPORTANCE_NONE);
mController.onResume(appRow, channel, gWrapper, null);
assertTrue(mController.getSummary().toString().contains(group.getName()));
assertTrue(mController.getSummary().toString().contains(appRow.label));
mController.onResume(appRow, channel, null, null);
assertFalse(mController.getSummary().toString().contains(group.getName()));
assertTrue(mController.getSummary().toString().contains(appRow.label));
}
}

View File

@@ -0,0 +1,166 @@
/*
* Copyright (C) 2017 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.app.NotificationChannel.DEFAULT_CHANNEL_ID;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import android.text.TextUtils;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.RestrictedLockUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
public class ImportancePreferenceControllerTest {
private Context mContext;
@Mock
private NotificationManager mNm;
@Mock
private UserManager mUm;
private ImportancePreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
mContext = shadowApplication.getApplicationContext();
mController = spy(new ImportancePreferenceController(mContext));
}
@Test
public void testNoCrashIfNoOnResume() throws Exception {
mController.isAvailable();
mController.updateState(mock(Preference.class));
}
@Test
public void testIsAvailable_notIfNull() throws Exception {
mController.onResume(null, null, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfAppBlocked() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.banned = true;
mController.onResume(appRow, mock(NotificationChannel.class), null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfChannelBlocked() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notForDefaultChannel() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
mController.onResume(appRow, channel, null, null);
assertTrue(mController.isAvailable());
}
@Test
public void testUpdateState_disabledByAdmin() throws Exception {
NotificationChannel channel = mock(NotificationChannel.class);
mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
RestrictedLockUtils.EnforcedAdmin.class));
Preference pref = new Preference(RuntimeEnvironment.application);
mController.updateState(pref);
assertFalse(pref.isEnabled());
assertNull(pref.getIntent());
}
@Test
public void testUpdateState_notConfigurable() throws Exception {
String lockedId = "locked";
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.lockedChannelId = lockedId;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn(lockedId);
mController.onResume(appRow, channel, null, null);
Preference pref = new Preference(RuntimeEnvironment.application);
mController.updateState(pref);
assertFalse(pref.isEnabled());
assertNull(pref.getIntent());
}
@Test
public void testUpdateState() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
Preference pref = new Preference(RuntimeEnvironment.application);
mController.updateState(pref);
assertTrue(pref.isEnabled());
assertNotNull(pref.getIntent());
assertFalse(TextUtils.isEmpty(pref.getSummary()));
}
}

View File

@@ -0,0 +1,245 @@
/*
* Copyright (C) 2017 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.app.NotificationChannel.DEFAULT_CHANNEL_ID;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.provider.Settings.System.NOTIFICATION_LIGHT_PULSE;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
import android.os.UserManager;
import android.provider.Settings;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
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.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O, shadows = {
SettingsShadowResources.class,
})
public class LightsPreferenceControllerTest {
private Context mContext;
@Mock
private NotificationBackend mBackend;
@Mock
private NotificationManager mNm;
@Mock
private UserManager mUm;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceScreen mScreen;
private LightsPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
mContext = shadowApplication.getApplicationContext();
mController = spy(new LightsPreferenceController(mContext, mBackend));
// By default allow lights
SettingsShadowResources.overrideResource(
com.android.internal.R.bool.config_intrusiveNotificationLed, true);
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_LIGHT_PULSE, 1);
}
@Test
public void testNoCrashIfNoOnResume() throws Exception {
mController.isAvailable();
mController.updateState(mock(RestrictedSwitchPreference.class));
mController.onPreferenceChange(mock(RestrictedSwitchPreference.class), true);
}
@Test
public void testIsAvailable_notIfConfigNotAllowed() throws Exception {
SettingsShadowResources.overrideResource(
com.android.internal.R.bool.config_intrusiveNotificationLed, false);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfSettingNotAllowed() throws Exception {
Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_LIGHT_PULSE, 0);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfNotImportant() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_LOW);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfDefaultChannel() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "", IMPORTANCE_DEFAULT);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
mController.onResume(appRow, channel, null, null);
assertTrue(mController.isAvailable());
}
@Test
public void testUpdateState_disabledByAdmin() throws Exception {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn("something");
mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
RestrictedLockUtils.EnforcedAdmin.class));
Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertFalse(pref.isEnabled());
}
@Test
public void testUpdateState_notConfigurable() throws Exception {
String lockedId = "locked";
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.lockedChannelId = lockedId;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn(lockedId);
mController.onResume(appRow, channel, null, null);
Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertFalse(pref.isEnabled());
}
@Test
public void testUpdateState_configurable() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn("something");
mController.onResume(appRow, channel, null, null);
Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertTrue(pref.isEnabled());
}
@Test
public void testUpdateState_lightsOn() throws Exception {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.shouldShowLights()).thenReturn(true);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertTrue(pref.isChecked());
}
@Test
public void testUpdateState_lightsOff() throws Exception {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.shouldShowLights()).thenReturn(false);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertFalse(pref.isChecked());
}
@Test
public void testOnPreferenceChange_on() {
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_DEFAULT);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
mController.onPreferenceChange(pref, true);
assertTrue(channel.shouldShowLights());
verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
}
@Test
public void testOnPreferenceChange_off() {
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
mController.onPreferenceChange(pref, false);
assertFalse(channel.shouldShowLights());
verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
}
}

View File

@@ -0,0 +1,316 @@
/*
* Copyright (C) 2017 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.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_MIN;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.wrapper.NotificationChannelGroupWrapper;
import com.android.settingslib.RestrictedLockUtils;
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.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
public class NotificationPreferenceControllerTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@Mock
private NotificationBackend mBackend;
@Mock
private NotificationManager mNm;
@Mock
private UserManager mUm;
private TestPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
mContext = shadowApplication.getApplicationContext();
mController = new TestPreferenceController(mContext, mBackend);
}
@Test
public void noCrashIfNoOnResume() throws Exception {
mController.isAvailable();
mController.updateState(mock(Preference.class));
assertFalse(mController.checkCanBeVisible(IMPORTANCE_UNSPECIFIED));
mController.saveChannel();
assertFalse(mController.isChannelConfigurable());
assertFalse(mController.isChannelBlockable());
assertFalse(mController.isChannelGroupBlockable());
}
@Test
public void isAvailable_notIfNull() throws Exception {
mController.onResume(null, null, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void isAvailable_notIfAppBlocked() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.banned = true;
mController.onResume(appRow, mock(NotificationChannel.class),
mock(NotificationChannelGroupWrapper.class), null);
assertFalse(mController.isAvailable());
}
@Test
public void isAvailable_notIfChannelBlocked() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void isAvailable_notIfChannelGroupBlocked() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
mController.onResume(appRow, channel, group, null);
when(group.isBlocked()).thenReturn(true);
assertFalse(mController.isAvailable());
}
@Test
public void isAvailable() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_DEFAULT);
NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
when(group.isBlocked()).thenReturn(false);
mController.onResume(appRow, channel, group, null);
assertTrue(mController.isAvailable());
}
@Test
public void testOnResume() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
RestrictedLockUtils.EnforcedAdmin admin = mock(RestrictedLockUtils.EnforcedAdmin.class);
mController.onResume(appRow, channel, group, admin);
assertEquals(appRow, mController.mAppRow);
assertEquals(channel, mController.mChannel);
assertEquals(group, mController.mChannelGroup);
assertEquals(admin, mController.mAdmin);
}
@Test
public void testCanBeVisible_unspecified() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_UNSPECIFIED);
mController.onResume(appRow, channel, null, null);
assertTrue(mController.checkCanBeVisible(IMPORTANCE_MIN));
}
@Test
public void testCanBeVisible_sameImportance() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
mController.onResume(appRow, channel, null, null);
assertTrue(mController.checkCanBeVisible(IMPORTANCE_LOW));
}
@Test
public void testCanBeVisible_greaterImportance() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
mController.onResume(appRow, channel, null, null);
assertTrue(mController.checkCanBeVisible(IMPORTANCE_MIN));
}
@Test
public void testCanBeVisible_lesserImportance() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_LOW);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.checkCanBeVisible(IMPORTANCE_DEFAULT));
}
@Test
public void testSaveImportance() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_DEFAULT);
mController.onResume(appRow, channel, null, null);
mController.saveChannel();
verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
}
@Test
public void testIsConfigurable() {
String sameId = "bananas";
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.lockedChannelId = sameId;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn(sameId);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isChannelConfigurable());
when(channel.getId()).thenReturn("something new");
mController.onResume(appRow, channel, null, null);
assertTrue(mController.isChannelConfigurable());
}
@Test
public void testIsChannelBlockable_nonSystemAppsBlockable() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.systemApp = false;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.isBlockableSystem()).thenReturn(false);
mController.onResume(appRow, channel, null, null);
assertTrue(mController.isChannelBlockable());
}
@Test
public void testIsChannelBlockable_mostSystemAppsNotBlockable() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.systemApp = true;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.isBlockableSystem()).thenReturn(false);
when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isChannelBlockable());
}
@Test
public void testIsChannelBlockable_someSystemAppsAreBlockable() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.systemApp = true;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.isBlockableSystem()).thenReturn(true);
mController.onResume(appRow, channel, null, null);
assertTrue(mController.isChannelBlockable());
}
@Test
public void testIsChannelBlockable_canUndoSystemBlock() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.systemApp = true;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.isBlockableSystem()).thenReturn(false);
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
mController.onResume(appRow, channel, null, null);
assertTrue(mController.isChannelBlockable());
}
@Test
public void testIsChannelGroupBlockable_nonSystemBlockable() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.systemApp = false;
NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
when(group.isBlocked()).thenReturn(false);
mController.onResume(appRow, null, group, null);
assertTrue(mController.isChannelGroupBlockable());
}
@Test
public void testIsChannelGroupBlockable_SystemNotBlockable() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.systemApp = true;
NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
when(group.isBlocked()).thenReturn(false);
mController.onResume(appRow, null, group, null);
assertFalse(mController.isChannelGroupBlockable());
}
@Test
public void testIsChannelGroupBlockable_canUndoSystemBlock() {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.systemApp = true;
NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
when(group.isBlocked()).thenReturn(true);
mController.onResume(appRow, null, group, null);
assertTrue(mController.isChannelGroupBlockable());
}
private final class TestPreferenceController extends NotificationPreferenceController {
public TestPreferenceController(Context context,
NotificationBackend backend) {
super(context, backend);
}
@Override
public String getPreferenceKey() {
return null;
}
}
}

View File

@@ -0,0 +1,147 @@
/*
* Copyright (C) 2017 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.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
import android.os.UserManager;
import android.support.v7.preference.Preference;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.wrapper.NotificationChannelGroupWrapper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
public class NotificationsOffPreferenceControllerTest {
private Context mContext;
@Mock
private NotificationManager mNm;
@Mock
private UserManager mUm;
private NotificationsOffPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
mContext = shadowApplication.getApplicationContext();
mController = spy(new NotificationsOffPreferenceController(mContext));
}
@Test
public void testNoCrashIfNoOnResume() throws Exception {
mController.isAvailable();
mController.updateState(mock(Preference.class));
}
@Test
public void testIsAvailable_yesIfAppBlocked() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.banned = true;
mController.onResume(appRow, null, null, null);
assertTrue(mController.isAvailable());
}
@Test
public void testIsAvailable_yesIfChannelGroupBlocked() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
when(group.isBlocked()).thenReturn(true);
mController.onResume(appRow, null, group, null);
assertTrue(mController.isAvailable());
}
@Test
public void testIsAvailable_yesIfChannelBlocked() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
mController.onResume(appRow, channel, null, null);
assertTrue(mController.isAvailable());
}
@Test
public void testUpdateState_channel() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getImportance()).thenReturn(IMPORTANCE_NONE);
mController.onResume(appRow, channel, null, null);
Preference pref = new Preference(RuntimeEnvironment.application);
mController.updateState(pref);
assertTrue(pref.getTitle().toString().contains("category"));
assertFalse(pref.isEnabled());
assertFalse(pref.isSelectable());
}
@Test
public void testUpdateState_channelGroup() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannelGroupWrapper group = mock(NotificationChannelGroupWrapper.class);
when(group.isBlocked()).thenReturn(true);
mController.onResume(appRow, null, group, null);
Preference pref = new Preference(RuntimeEnvironment.application);
mController.updateState(pref);
assertTrue(pref.getTitle().toString().contains("group"));
assertFalse(pref.isEnabled());
assertFalse(pref.isSelectable());
}
@Test
public void testUpdateState_app() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.banned = true;
mController.onResume(appRow, null, null, null);
Preference pref = new Preference(RuntimeEnvironment.application);
mController.updateState(pref);
assertTrue(pref.getTitle().toString().contains("app"));
assertFalse(pref.isEnabled());
assertFalse(pref.isSelectable());
}
}

View File

@@ -0,0 +1,257 @@
/*
* Copyright (C) 2017 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.app.NotificationChannel.DEFAULT_CHANNEL_ID;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Fragment;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.UserManager;
import android.provider.Settings;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.util.AttributeSet;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.RestrictedLockUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
public class SoundPreferenceControllerTest {
private Context mContext;
@Mock
private NotificationBackend mBackend;
@Mock
private NotificationManager mNm;
@Mock
private UserManager mUm;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceScreen mScreen;
@Mock
private SettingsPreferenceFragment mFragment;
@Mock
private NotificationSettingsBase.ImportanceListener mImportanceListener;
private SoundPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
mContext = shadowApplication.getApplicationContext();
mController = spy(new SoundPreferenceController(
mContext, mFragment, mImportanceListener, mBackend));
}
@Test
public void testNoCrashIfNoOnResume() throws Exception {
mController.isAvailable();
mController.updateState(mock(NotificationSoundPreference.class));
mController.onPreferenceChange(mock(NotificationSoundPreference.class), Uri.EMPTY);
mController.handlePreferenceTreeClick(mock(NotificationSoundPreference.class));
mController.onActivityResult(1, 1, null);
mController.hasValidSound(null);
}
@Test
public void testIsAvailable_notIfChannelNull() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
mController.onResume(appRow, null, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfNotImportant() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_LOW);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfDefaultChannel() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "", IMPORTANCE_DEFAULT);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
mController.onResume(appRow, channel, null, null);
assertTrue(mController.isAvailable());
}
@Test
public void testDisplayPreference_savesPreference() throws Exception {
NotificationSoundPreference pref = mock(NotificationSoundPreference.class);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.onActivityResult(SoundPreferenceController.CODE, 1, new Intent());
verify(pref, times(1)).onActivityResult(anyInt(), anyInt(), any());
}
@Test
public void testUpdateState_disabledByAdmin() throws Exception {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn("something");
mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
RestrictedLockUtils.EnforcedAdmin.class));
Preference pref = new NotificationSoundPreference(mContext, mock(AttributeSet.class));
mController.updateState(pref);
assertFalse(pref.isEnabled());
}
@Test
public void testUpdateState_notConfigurable() throws Exception {
String lockedId = "locked";
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.lockedChannelId = lockedId;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn(lockedId);
mController.onResume(appRow, channel, null, null);
Preference pref = new NotificationSoundPreference(mContext, mock(AttributeSet.class));
mController.updateState(pref);
assertFalse(pref.isEnabled());
}
@Test
public void testUpdateState_configurable() throws Exception {
Uri sound = Settings.System.DEFAULT_ALARM_ALERT_URI;
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn("something");
when(channel.getSound()).thenReturn(sound);
mController.onResume(appRow, channel, null, null);
NotificationSoundPreference pref =
new NotificationSoundPreference(mContext, mock(AttributeSet.class));
mController.updateState(pref);
assertEquals(sound, pref.onRestoreRingtone());
assertTrue(pref.isEnabled());
}
@Test
public void testOnPreferenceChange() throws Exception {
Uri sound = Settings.System.DEFAULT_ALARM_ALERT_URI;
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
channel.setSound(sound, Notification.AUDIO_ATTRIBUTES_DEFAULT);
mController.onResume(appRow, channel, null, null);
NotificationSoundPreference pref =
new NotificationSoundPreference(mContext, mock(AttributeSet.class));
mController.updateState(pref);
mController.onPreferenceChange(pref, Uri.EMPTY);
assertEquals(Uri.EMPTY, channel.getSound());
assertEquals(Notification.AUDIO_ATTRIBUTES_DEFAULT, channel.getAudioAttributes());
verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
}
@Test
public void testOnPreferenceTreeClick_incorrectPref() throws Exception {
NotificationSoundPreference pref = mock(NotificationSoundPreference.class);
mController.handlePreferenceTreeClick(pref);
verify(pref, never()).onPrepareRingtonePickerIntent(any());
verify(mFragment, never()).startActivityForResult(any(), anyInt());
}
@Test
public void testOnPreferenceTreeClick_correctPref() throws Exception {
NotificationSoundPreference pref =
spy(new NotificationSoundPreference(mContext, mock(AttributeSet.class)));
pref.setKey(mController.getPreferenceKey());
mController.handlePreferenceTreeClick(pref);
verify(pref, times(1)).onPrepareRingtonePickerIntent(any());
verify(mFragment, times(1)).startActivityForResult(any(), anyInt());
}
@Test
public void testOnActivityResult() {
NotificationSoundPreference pref = mock(NotificationSoundPreference.class);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.onActivityResult(SoundPreferenceController.CODE, 1, new Intent("hi"));
verify(pref, times(1)).onActivityResult(anyInt(), anyInt(), any());
verify(mImportanceListener, times(1)).onImportanceChanged();
}
@Test
public void testHasValidSound() {
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
assertTrue(mController.hasValidSound(channel));
channel.setSound(Uri.EMPTY, Notification.AUDIO_ATTRIBUTES_DEFAULT);
assertFalse(mController.hasValidSound(channel));
channel.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT);
assertFalse(mController.hasValidSound(channel));
}
}

View File

@@ -0,0 +1,230 @@
/*
* Copyright (C) 2017 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.app.NotificationChannel.DEFAULT_CHANNEL_ID;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
import android.os.UserManager;
import android.os.Vibrator;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
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.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O)
public class VibrationPreferenceControllerTest {
private Context mContext;
@Mock
private NotificationBackend mBackend;
@Mock
private NotificationManager mNm;
@Mock
Vibrator mVibrator;
@Mock
private UserManager mUm;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceScreen mScreen;
private VibrationPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
shadowApplication.setSystemService(Context.VIBRATOR_SERVICE, mVibrator);
mContext = shadowApplication.getApplicationContext();
mController = spy(new VibrationPreferenceController(mContext, mBackend));
// by default allow vibration
when(mVibrator.hasVibrator()).thenReturn(true);
}
@Test
public void testNoCrashIfNoOnResume() throws Exception {
mController.isAvailable();
mController.updateState(mock(RestrictedSwitchPreference.class));
mController.onPreferenceChange(mock(RestrictedSwitchPreference.class), true);
}
@Test
public void testIsAvailable_notSystemDoesNotHave() throws Exception {
when(mVibrator.hasVibrator()).thenReturn(false);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfNotImportant() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_LOW);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfDefaultChannel() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "", IMPORTANCE_DEFAULT);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
mController.onResume(appRow, channel, null, null);
assertTrue(mController.isAvailable());
}
@Test
public void testUpdateState_disabledByAdmin() throws Exception {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn("something");
mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
RestrictedLockUtils.EnforcedAdmin.class));
Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertFalse(pref.isEnabled());
}
@Test
public void testUpdateState_notConfigurable() throws Exception {
String lockedId = "locked";
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
appRow.lockedChannelId = lockedId;
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn(lockedId);
mController.onResume(appRow, channel, null, null);
Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertFalse(pref.isEnabled());
}
@Test
public void testUpdateState_configurable() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn("something");
mController.onResume(appRow, channel, null, null);
Preference pref = new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertTrue(pref.isEnabled());
}
@Test
public void testUpdateState_vibrateOn() throws Exception {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.shouldVibrate()).thenReturn(true);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertTrue(pref.isChecked());
}
@Test
public void testUpdateState_vibrateOff() throws Exception {
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.shouldVibrate()).thenReturn(false);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
assertFalse(pref.isChecked());
}
@Test
public void testOnPreferenceChange_on() {
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_DEFAULT);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
mController.updateState(pref);
mController.onPreferenceChange(pref, true);
assertTrue(channel.shouldVibrate());
verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
}
@Test
public void testOnPreferenceChange_off() {
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "a", IMPORTANCE_HIGH);
mController.onResume(new NotificationBackend.AppRow(), channel, null, null);
RestrictedSwitchPreference pref =
new RestrictedSwitchPreference(RuntimeEnvironment.application);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
mController.displayPreference(mScreen);
mController.updateState(pref);
mController.onPreferenceChange(pref, false);
assertFalse(channel.shouldVibrate());
verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
}
}

View File

@@ -0,0 +1,326 @@
/*
* Copyright (C) 2017 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.app.NotificationChannel.DEFAULT_CHANNEL_ID;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_MIN;
import static android.app.NotificationManager.VISIBILITY_NO_OVERRIDE;
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS;
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.UserInfo;
import android.os.Build;
import android.os.UserManager;
import android.provider.Settings;
import android.support.v7.preference.PreferenceScreen;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowRestrictionUtils;
import com.android.settingslib.RestrictedLockUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = Build.VERSION_CODES.O, shadows = {
ShadowRestrictionUtils.class,
})
public class VisibilityPreferenceControllerTest {
private Context mContext;
@Mock
private NotificationBackend mBackend;
@Mock
private NotificationManager mNm;
@Mock
private LockPatternUtils mLockUtils;
@Mock
private UserManager mUm;
@Mock
private DevicePolicyManager mDm;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceScreen mScreen;
private VisibilityPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
shadowApplication.setSystemService(Context.DEVICE_POLICY_SERVICE, mDm);
mContext = shadowApplication.getApplicationContext();
mController = spy(new VisibilityPreferenceController(mContext, mLockUtils, mBackend));
// by default the lockscreen is secure
when(mLockUtils.isSecure(anyInt())).thenReturn(true);
// and notifications are visible in redacted form
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1);
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1);
// and not restricted
ShadowRestrictionUtils.setRestricted(false);
// with no managed profile
UserInfo userInfo = new UserInfo();
when(mUm.getUserInfo(anyInt())).thenReturn(userInfo);
}
@Test
public void testNoCrashIfNoOnResume() throws Exception {
mController.isAvailable();
mController.updateState(mock(RestrictedDropDownPreference.class));
mController.onPreferenceChange(mock(RestrictedDropDownPreference.class), true);
}
@Test
public void testIsAvailable_notSecure() throws Exception {
when(mLockUtils.isSecure(anyInt())).thenReturn(false);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable_notIfNotImportant() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_MIN);
mController.onResume(appRow, channel, null, null);
assertFalse(mController.isAvailable());
}
@Test
public void testIsAvailable() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel =
new NotificationChannel(DEFAULT_CHANNEL_ID, "", IMPORTANCE_DEFAULT);
mController.onResume(appRow, channel, null, null);
assertTrue(mController.isAvailable());
channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
mController.onResume(appRow, channel, null, null);
assertTrue(mController.isAvailable());
}
@Test
public void testUpdateState_disabledByAdmin_disableSecure() throws Exception {
ShadowRestrictionUtils.setRestricted(true);
UserInfo userInfo = new UserInfo(2, "user 2", UserInfo.FLAG_MANAGED_PROFILE);
when(mUm.getUserInfo(anyInt())).thenReturn(userInfo);
List<ComponentName> components = new ArrayList<>();
components.add(new ComponentName("", ""));
when(mDm.getActiveAdminsAsUser(anyInt())).thenReturn(components);
when(mDm.getKeyguardDisabledFeatures(any(), anyInt()))
.thenReturn(KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn("something");
mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
RestrictedLockUtils.EnforcedAdmin.class));
RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
mController.updateState(pref);
verify(pref, times(2)).addRestrictedItem(any());
}
@Test
public void testUpdateState_disabledByAdmin_disableUnredacted() throws Exception {
ShadowRestrictionUtils.setRestricted(true);
UserInfo userInfo = new UserInfo(2, "user 2", UserInfo.FLAG_MANAGED_PROFILE);
when(mUm.getUserInfo(anyInt())).thenReturn(userInfo);
List<ComponentName> components = new ArrayList<>();
components.add(new ComponentName("", ""));
when(mDm.getActiveAdminsAsUser(anyInt())).thenReturn(components);
when(mDm.getKeyguardDisabledFeatures(any(), anyInt()))
.thenReturn(KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getId()).thenReturn("something");
mController.onResume(new NotificationBackend.AppRow(), channel, null, mock(
RestrictedLockUtils.EnforcedAdmin.class));
RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
mController.updateState(pref);
verify(pref, times(1)).addRestrictedItem(any());
}
@Test
public void testUpdateState_noLockScreenNotificationsGlobally() throws Exception {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
mController.onResume(appRow, channel, null, null);
RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
mController.updateState(pref);
ArgumentCaptor<String[]> argumentCaptor = ArgumentCaptor.forClass(String[].class);
verify(pref, times(1)).setEntryValues(argumentCaptor.capture());
assertFalse(Arrays.asList(argumentCaptor.getValue())
.contains(VISIBILITY_NO_OVERRIDE));
}
@Test
public void testUpdateState_noPrivateLockScreenNotificationsGlobally() throws Exception {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
mController.onResume(appRow, channel, null, null);
RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
mController.updateState(pref);
ArgumentCaptor<String[]> argumentCaptor = ArgumentCaptor.forClass(String[].class);
verify(pref, times(1)).setEntryValues(argumentCaptor.capture());
assertFalse(Arrays.asList(argumentCaptor.getValue())
.contains(VISIBILITY_NO_OVERRIDE));
}
@Test
public void testUpdateState_noGlobalRestriction() throws Exception {
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
mController.onResume(appRow, channel, null, null);
RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
mController.updateState(pref);
ArgumentCaptor<String[]> argumentCaptor = ArgumentCaptor.forClass(String[].class);
verify(pref, times(1)).setEntryValues(argumentCaptor.capture());
List<String> values = Arrays.asList(argumentCaptor.getValue());
assertEquals(3, values.size());
assertTrue(values.contains(String.valueOf(VISIBILITY_NO_OVERRIDE)));
assertTrue(values.contains(String.valueOf(Notification.VISIBILITY_PRIVATE)));
assertTrue(values.contains(String.valueOf(Notification.VISIBILITY_SECRET)));
}
@Test
public void testUpdateState_noChannelOverride() throws Exception {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getLockscreenVisibility()).thenReturn(VISIBILITY_NO_OVERRIDE);
mController.onResume(appRow, channel, null, null);
RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
mController.updateState(pref);
ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
verify(pref, times(1)).setValue(argumentCaptor.capture());
assertEquals(String.valueOf(Notification.VISIBILITY_PRIVATE), argumentCaptor.getValue());
}
@Test
public void testUpdateState_channelOverride() throws Exception {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = mock(NotificationChannel.class);
when(channel.getLockscreenVisibility()).thenReturn(Notification.VISIBILITY_SECRET);
mController.onResume(appRow, channel, null, null);
RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
mController.updateState(pref);
ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
verify(pref, times(1)).setValue(argumentCaptor.capture());
assertEquals(String.valueOf(Notification.VISIBILITY_SECRET), argumentCaptor.getValue());
}
@Test
public void testOnPreferenceChange_noOverride() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", 4);
channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
mController.onResume(appRow, channel, null, null);
RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
mController.updateState(pref);
mController.onPreferenceChange(pref, String.valueOf(Notification.VISIBILITY_PRIVATE));
assertEquals(VISIBILITY_NO_OVERRIDE, channel.getLockscreenVisibility());
verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
}
@Test
public void testOnPreferenceChange_override() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0);
NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
NotificationChannel channel = new NotificationChannel("", "", 4);
channel.setLockscreenVisibility(VISIBILITY_NO_OVERRIDE);
mController.onResume(appRow, channel, null, null);
RestrictedDropDownPreference pref = mock(RestrictedDropDownPreference.class);
mController.updateState(pref);
mController.onPreferenceChange(pref, String.valueOf(Notification.VISIBILITY_SECRET));
assertEquals(Notification.VISIBILITY_SECRET, channel.getLockscreenVisibility());
verify(mBackend, times(1)).updateChannel(any(), anyInt(), any());
}
}