PreferenceControllers are the way of the future.
Migrates Notification settings (app level, group level, and channel level) into PreferenceControllers (and most importantly: PreferenceControllerTest) Note: this removes the 'Advanced' preference group, but does not yet use the standard system 'Advanced' grouping as it does not currently support our use case (where we don't know how many fields to show outside of 'Advanced' until onResume() and also where we need fields to show below the 'Advanced' group). Test: make RunSettingsRoboTests Change-Id: Iddd1b4771922db322e5f73562e9d63ed077c5396
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user