Home | History | Annotate | Download | only in notification
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.settings.notification;
     18 
     19 import static com.google.common.truth.Truth.assertThat;
     20 
     21 import static org.mockito.ArgumentMatchers.nullable;
     22 import static org.mockito.Matchers.anyInt;
     23 import static org.mockito.Matchers.eq;
     24 import static org.mockito.Mockito.mock;
     25 import static org.mockito.Mockito.times;
     26 import static org.mockito.Mockito.verify;
     27 import static org.mockito.Mockito.when;
     28 
     29 import android.content.Context;
     30 import android.os.UserHandle;
     31 import android.os.UserManager;
     32 import android.support.v7.preference.Preference;
     33 import android.support.v7.preference.PreferenceCategory;
     34 import android.support.v7.preference.PreferenceScreen;
     35 import android.support.v7.preference.TwoStatePreference;
     36 import android.telephony.TelephonyManager;
     37 
     38 import com.android.settings.DefaultRingtonePreference;
     39 import com.android.settings.R;
     40 import com.android.settings.RingtonePreference;
     41 import com.android.settings.testutils.SettingsRobolectricTestRunner;
     42 import com.android.settings.TestConfig;
     43 
     44 import org.junit.Before;
     45 import org.junit.Test;
     46 import org.junit.runner.RunWith;
     47 import org.mockito.Mock;
     48 import org.mockito.MockitoAnnotations;
     49 import org.robolectric.annotation.Config;
     50 
     51 @RunWith(SettingsRobolectricTestRunner.class)
     52 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
     53 public class WorkSoundPreferenceControllerTest {
     54 
     55     private static final String KEY_WORK_CATEGORY = "sound_work_settings_section";
     56     private static final String KEY_WORK_USE_PERSONAL_SOUNDS = "work_use_personal_sounds";
     57     private static final String KEY_WORK_PHONE_RINGTONE = "work_ringtone";
     58     private static final String KEY_WORK_NOTIFICATION_RINGTONE = "work_notification_ringtone";
     59     private static final String KEY_WORK_ALARM_RINGTONE = "work_alarm_ringtone";
     60 
     61     @Mock
     62     private Context mContext;
     63     @Mock
     64     private PreferenceScreen mScreen;
     65     @Mock
     66     private PreferenceCategory mWorkCategory;
     67     @Mock
     68     private TelephonyManager mTelephonyManager;
     69     @Mock
     70     private AudioHelper mAudioHelper;
     71     @Mock
     72     private SoundSettings mFragment;
     73 
     74     private WorkSoundPreferenceController mController;
     75 
     76     @Before
     77     public void setUp() {
     78         MockitoAnnotations.initMocks(this);
     79         when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
     80         when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
     81         when(mScreen.findPreference(KEY_WORK_CATEGORY))
     82                 .thenReturn(mWorkCategory);
     83         when(mWorkCategory.findPreference(KEY_WORK_USE_PERSONAL_SOUNDS))
     84                 .thenReturn(mock(TwoStatePreference.class));
     85         when(mWorkCategory.findPreference(KEY_WORK_PHONE_RINGTONE))
     86                 .thenReturn(mock(DefaultRingtonePreference.class));
     87         when(mWorkCategory.findPreference(KEY_WORK_NOTIFICATION_RINGTONE))
     88                 .thenReturn(mock(DefaultRingtonePreference.class));
     89         when(mWorkCategory.findPreference(KEY_WORK_ALARM_RINGTONE))
     90                 .thenReturn(mock(DefaultRingtonePreference.class));
     91 
     92         mController = new WorkSoundPreferenceController(mContext, mFragment, null, mAudioHelper);
     93     }
     94 
     95     @Test
     96     public void isAvailable_managedProfileAndNotSingleVolume_shouldReturnTrue() {
     97         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
     98                 .thenReturn(UserHandle.myUserId());
     99         when(mAudioHelper.isUserUnlocked(nullable(UserManager.class), anyInt())).thenReturn(true);
    100         when(mAudioHelper.isSingleVolume()).thenReturn(false);
    101 
    102         assertThat(mController.isAvailable()).isTrue();
    103     }
    104 
    105     @Test
    106     public void isAvailable_noManagedProfile_shouldReturnFalse() {
    107         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    108                 .thenReturn(UserHandle.USER_NULL);
    109         when(mAudioHelper.isUserUnlocked(nullable(UserManager.class), anyInt())).thenReturn(true);
    110         when(mAudioHelper.isSingleVolume()).thenReturn(false);
    111 
    112         assertThat(mController.isAvailable()).isFalse();
    113     }
    114 
    115     @Test
    116     public void isAvailable_singleVolume_shouldReturnFalse() {
    117         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    118                 .thenReturn(UserHandle.myUserId());
    119         when(mAudioHelper.isUserUnlocked(nullable(UserManager.class), anyInt())).thenReturn(true);
    120         when(mAudioHelper.isSingleVolume()).thenReturn(true);
    121 
    122         assertThat(mController.isAvailable()).isFalse();
    123     }
    124 
    125     @Test
    126     public void onManagedProfileAdded_shouldDisplayPreferenceCategory() {
    127         // Given a device without any managed profiles:
    128         when(mAudioHelper.isSingleVolume()).thenReturn(false);
    129         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
    130         when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext);
    131         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    132                 .thenReturn(UserHandle.USER_NULL);
    133 
    134         // When the fragment first displays, the category should not appear.
    135         mController.displayPreference(mScreen);
    136         verify(mWorkCategory).setVisible(false);
    137 
    138         // However, when a managed profile is added later, the category should appear.
    139         mController.onResume();
    140         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    141                 .thenReturn(UserHandle.myUserId());
    142         mController.onManagedProfileAdded(UserHandle.myUserId());
    143 
    144         verify(mWorkCategory).setVisible(true);
    145     }
    146 
    147     @Test
    148     public void onManagedProfileRemoved_shouldHidePreferenceCategory() {
    149         // Given a device with a managed profile:
    150         when(mAudioHelper.isSingleVolume()).thenReturn(false);
    151         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
    152         when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext);
    153         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    154                 .thenReturn(UserHandle.myUserId());
    155         when(mAudioHelper.isUserUnlocked(nullable(UserManager.class), anyInt())).thenReturn(true);
    156 
    157         // Which is in resumed state:
    158         mController.displayPreference(mScreen);
    159         mController.onResume();
    160 
    161         verify(mWorkCategory, times(2)).setVisible(true);
    162 
    163         // When a managed profile is removed, the category should be hidden.
    164         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    165                 .thenReturn(UserHandle.USER_NULL);
    166         mController.onManagedProfileRemoved(UserHandle.myUserId());
    167 
    168         verify(mWorkCategory).setVisible(false);
    169     }
    170 
    171 
    172     @Test
    173     public void displayPreference_isAvailable_shouldShowPreferenceCategory() {
    174         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    175                 .thenReturn(UserHandle.myUserId());
    176         when(mAudioHelper.isUserUnlocked(nullable(UserManager.class), anyInt())).thenReturn(true);
    177         when(mAudioHelper.isSingleVolume()).thenReturn(false);
    178         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
    179         when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext);
    180 
    181         mController.displayPreference(mScreen);
    182         verify(mWorkCategory).setVisible(true);
    183     }
    184 
    185     @Test
    186     public void displayPreference_notAvailable_shouldHidePreferenceCategory() {
    187         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    188                 .thenReturn(UserHandle.USER_NULL);
    189         when(mAudioHelper.isSingleVolume()).thenReturn(true);
    190         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
    191 
    192         mController.displayPreference(mScreen);
    193         verify(mWorkCategory).setVisible(false);
    194     }
    195 
    196     @Test
    197     public void onPreferenceChange_shouldUpdateSummary() {
    198         final Preference preference = mock(Preference.class);
    199         when(preference.getKey()).thenReturn(KEY_WORK_PHONE_RINGTONE);
    200 
    201         mController.onPreferenceChange(preference, "hello");
    202 
    203         verify(preference).setSummary(nullable(String.class));
    204     }
    205 
    206     @Test
    207     public void onResume_noVoiceCapability_shouldHidePhoneRingtone() {
    208         when(mTelephonyManager.isVoiceCapable()).thenReturn(false);
    209         mController = new WorkSoundPreferenceController(mContext, mFragment, null, mAudioHelper);
    210 
    211         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    212                 .thenReturn(UserHandle.myUserId());
    213         when(mAudioHelper.isUserUnlocked(nullable(UserManager.class), anyInt())).thenReturn(true);
    214         when(mAudioHelper.isSingleVolume()).thenReturn(false);
    215         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
    216         when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext);
    217 
    218         // Precondition: work profile is available.
    219         assertThat(mController.isAvailable()).isTrue();
    220 
    221         mController.displayPreference(mScreen);
    222         mController.onResume();
    223 
    224         verify(mWorkCategory.findPreference(KEY_WORK_PHONE_RINGTONE)).setVisible(false);
    225     }
    226 
    227     @Test
    228     public void onResume_availableButLocked_shouldRedactPreferences() {
    229         final String notAvailable = "(not available)";
    230         when(mContext.getString(R.string.managed_profile_not_available_label))
    231                 .thenReturn(notAvailable);
    232 
    233         // Given a device with a managed profile:
    234         when(mAudioHelper.isSingleVolume()).thenReturn(false);
    235         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
    236         when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext);
    237         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    238                 .thenReturn(UserHandle.myUserId());
    239         when(mAudioHelper.isUserUnlocked(nullable(UserManager.class), anyInt())).thenReturn(false);
    240 
    241         // When resumed:
    242         mController.displayPreference(mScreen);
    243         mController.onResume();
    244 
    245         verify(mWorkCategory, times(2)).setVisible(true);
    246 
    247         // Sound preferences should explain that the profile isn't available yet.
    248         verify(mWorkCategory.findPreference(KEY_WORK_PHONE_RINGTONE))
    249                 .setSummary(eq(notAvailable));
    250         verify(mWorkCategory.findPreference(KEY_WORK_NOTIFICATION_RINGTONE))
    251                 .setSummary(eq(notAvailable));
    252         verify(mWorkCategory.findPreference(KEY_WORK_ALARM_RINGTONE))
    253                 .setSummary(eq(notAvailable));
    254     }
    255 
    256     @Test
    257     public void onResume_shouldSetUserIdToPreference() {
    258         final int managedProfileUserId = 10;
    259         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    260                 .thenReturn(managedProfileUserId);
    261         when(mAudioHelper.isUserUnlocked(nullable(UserManager.class), anyInt())).thenReturn(true);
    262         when(mAudioHelper.isSingleVolume()).thenReturn(false);
    263         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
    264         when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext);
    265 
    266         mController.displayPreference(mScreen);
    267         mController.onResume();
    268 
    269         verify((RingtonePreference) mWorkCategory.findPreference(KEY_WORK_PHONE_RINGTONE))
    270                 .setUserId(managedProfileUserId);
    271         verify((RingtonePreference) mWorkCategory.findPreference(KEY_WORK_NOTIFICATION_RINGTONE))
    272                 .setUserId(managedProfileUserId);
    273         verify((RingtonePreference) mWorkCategory.findPreference(KEY_WORK_ALARM_RINGTONE))
    274                 .setUserId(managedProfileUserId);
    275     }
    276 
    277 }
    278