Merge "PreferenceControllers are the way of the future."

This commit is contained in:
Julia Reynolds
2017-11-08 13:33:40 +00:00
committed by Android (Google) Code Review
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());
}
}