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 import static org.mockito.ArgumentMatchers.nullable;
     21 import static org.mockito.Matchers.anyInt;
     22 import static org.mockito.Matchers.eq;
     23 import static org.mockito.Mockito.mock;
     24 import static org.mockito.Mockito.times;
     25 import static org.mockito.Mockito.verify;
     26 import static org.mockito.Mockito.when;
     27 
     28 import android.content.Context;
     29 import android.os.UserHandle;
     30 import android.os.UserManager;
     31 import android.support.v7.preference.Preference;
     32 import android.support.v7.preference.PreferenceCategory;
     33 import android.support.v7.preference.PreferenceScreen;
     34 import android.support.v7.preference.TwoStatePreference;
     35 import android.telephony.TelephonyManager;
     36 
     37 import com.android.settings.DefaultRingtonePreference;
     38 import com.android.settings.R;
     39 import com.android.settings.RingtonePreference;
     40 import com.android.settings.testutils.SettingsRobolectricTestRunner;
     41 
     42 import org.junit.Before;
     43 import org.junit.Test;
     44 import org.junit.runner.RunWith;
     45 import org.mockito.Mock;
     46 import org.mockito.MockitoAnnotations;
     47 
     48 @RunWith(SettingsRobolectricTestRunner.class)
     49 public class WorkSoundPreferenceControllerTest {
     50 
     51     private static final String KEY_WORK_CATEGORY = "sound_work_settings_section";
     52     private static final String KEY_WORK_USE_PERSONAL_SOUNDS = "work_use_personal_sounds";
     53     private static final String KEY_WORK_PHONE_RINGTONE = "work_ringtone";
     54     private static final String KEY_WORK_NOTIFICATION_RINGTONE = "work_notification_ringtone";
     55     private static final String KEY_WORK_ALARM_RINGTONE = "work_alarm_ringtone";
     56 
     57     @Mock
     58     private Context mContext;
     59     @Mock
     60     private PreferenceScreen mScreen;
     61     @Mock
     62     private PreferenceCategory mWorkCategory;
     63     @Mock
     64     private TelephonyManager mTelephonyManager;
     65     @Mock
     66     private AudioHelper mAudioHelper;
     67     @Mock
     68     private SoundSettings mFragment;
     69 
     70     private WorkSoundPreferenceController mController;
     71 
     72     @Before
     73     public void setUp() {
     74         MockitoAnnotations.initMocks(this);
     75         when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
     76         when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
     77         when(mScreen.findPreference(KEY_WORK_CATEGORY))
     78                 .thenReturn(mWorkCategory);
     79         when(mWorkCategory.findPreference(KEY_WORK_USE_PERSONAL_SOUNDS))
     80                 .thenReturn(mock(TwoStatePreference.class));
     81         when(mWorkCategory.findPreference(KEY_WORK_PHONE_RINGTONE))
     82                 .thenReturn(mock(DefaultRingtonePreference.class));
     83         when(mWorkCategory.findPreference(KEY_WORK_NOTIFICATION_RINGTONE))
     84                 .thenReturn(mock(DefaultRingtonePreference.class));
     85         when(mWorkCategory.findPreference(KEY_WORK_ALARM_RINGTONE))
     86                 .thenReturn(mock(DefaultRingtonePreference.class));
     87 
     88         mController = new WorkSoundPreferenceController(mContext, mFragment, null, mAudioHelper);
     89     }
     90 
     91     @Test
     92     public void isAvailable_managedProfileAndNotSingleVolume_shouldReturnTrue() {
     93         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
     94                 .thenReturn(UserHandle.myUserId());
     95         when(mAudioHelper.isUserUnlocked(nullable(UserManager.class), anyInt())).thenReturn(true);
     96         when(mAudioHelper.isSingleVolume()).thenReturn(false);
     97 
     98         assertThat(mController.isAvailable()).isTrue();
     99     }
    100 
    101     @Test
    102     public void isAvailable_noManagedProfile_shouldReturnFalse() {
    103         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    104                 .thenReturn(UserHandle.USER_NULL);
    105         when(mAudioHelper.isUserUnlocked(nullable(UserManager.class), anyInt())).thenReturn(true);
    106         when(mAudioHelper.isSingleVolume()).thenReturn(false);
    107 
    108         assertThat(mController.isAvailable()).isFalse();
    109     }
    110 
    111     @Test
    112     public void isAvailable_singleVolume_shouldReturnFalse() {
    113         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    114                 .thenReturn(UserHandle.myUserId());
    115         when(mAudioHelper.isUserUnlocked(nullable(UserManager.class), anyInt())).thenReturn(true);
    116         when(mAudioHelper.isSingleVolume()).thenReturn(true);
    117 
    118         assertThat(mController.isAvailable()).isFalse();
    119     }
    120 
    121     @Test
    122     public void onManagedProfileAdded_shouldDisplayPreferenceCategory() {
    123         // Given a device without any managed profiles:
    124         when(mAudioHelper.isSingleVolume()).thenReturn(false);
    125         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
    126         when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext);
    127         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    128                 .thenReturn(UserHandle.USER_NULL);
    129 
    130         // When the fragment first displays, the category should not appear.
    131         mController.displayPreference(mScreen);
    132         verify(mWorkCategory).setVisible(false);
    133 
    134         // However, when a managed profile is added later, the category should appear.
    135         mController.onResume();
    136         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    137                 .thenReturn(UserHandle.myUserId());
    138         mController.onManagedProfileAdded(UserHandle.myUserId());
    139 
    140         verify(mWorkCategory).setVisible(true);
    141     }
    142 
    143     @Test
    144     public void onManagedProfileRemoved_shouldHidePreferenceCategory() {
    145         // Given a device with a managed profile:
    146         when(mAudioHelper.isSingleVolume()).thenReturn(false);
    147         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
    148         when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext);
    149         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    150                 .thenReturn(UserHandle.myUserId());
    151         when(mAudioHelper.isUserUnlocked(nullable(UserManager.class), anyInt())).thenReturn(true);
    152 
    153         // Which is in resumed state:
    154         mController.displayPreference(mScreen);
    155         mController.onResume();
    156 
    157         verify(mWorkCategory, times(2)).setVisible(true);
    158 
    159         // When a managed profile is removed, the category should be hidden.
    160         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    161                 .thenReturn(UserHandle.USER_NULL);
    162         mController.onManagedProfileRemoved(UserHandle.myUserId());
    163 
    164         verify(mWorkCategory).setVisible(false);
    165     }
    166 
    167 
    168     @Test
    169     public void displayPreference_isAvailable_shouldShowPreferenceCategory() {
    170         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    171                 .thenReturn(UserHandle.myUserId());
    172         when(mAudioHelper.isUserUnlocked(nullable(UserManager.class), anyInt())).thenReturn(true);
    173         when(mAudioHelper.isSingleVolume()).thenReturn(false);
    174         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
    175         when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext);
    176 
    177         mController.displayPreference(mScreen);
    178         verify(mWorkCategory).setVisible(true);
    179     }
    180 
    181     @Test
    182     public void displayPreference_notAvailable_shouldHidePreferenceCategory() {
    183         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    184                 .thenReturn(UserHandle.USER_NULL);
    185         when(mAudioHelper.isSingleVolume()).thenReturn(true);
    186         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
    187 
    188         mController.displayPreference(mScreen);
    189         verify(mWorkCategory).setVisible(false);
    190     }
    191 
    192     @Test
    193     public void onPreferenceChange_shouldUpdateSummary() {
    194         final Preference preference = mock(Preference.class);
    195         when(preference.getKey()).thenReturn(KEY_WORK_PHONE_RINGTONE);
    196 
    197         mController.onPreferenceChange(preference, "hello");
    198 
    199         verify(preference).setSummary(nullable(String.class));
    200     }
    201 
    202     @Test
    203     public void onResume_noVoiceCapability_shouldHidePhoneRingtone() {
    204         when(mTelephonyManager.isVoiceCapable()).thenReturn(false);
    205         mController = new WorkSoundPreferenceController(mContext, mFragment, null, mAudioHelper);
    206 
    207         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    208                 .thenReturn(UserHandle.myUserId());
    209         when(mAudioHelper.isUserUnlocked(nullable(UserManager.class), anyInt())).thenReturn(true);
    210         when(mAudioHelper.isSingleVolume()).thenReturn(false);
    211         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
    212         when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext);
    213 
    214         // Precondition: work profile is available.
    215         assertThat(mController.isAvailable()).isTrue();
    216 
    217         mController.displayPreference(mScreen);
    218         mController.onResume();
    219 
    220         verify(mWorkCategory.findPreference(KEY_WORK_PHONE_RINGTONE)).setVisible(false);
    221     }
    222 
    223     @Test
    224     public void onResume_availableButLocked_shouldRedactPreferences() {
    225         final String notAvailable = "(not available)";
    226         when(mContext.getString(R.string.managed_profile_not_available_label))
    227                 .thenReturn(notAvailable);
    228 
    229         // Given a device with a managed profile:
    230         when(mAudioHelper.isSingleVolume()).thenReturn(false);
    231         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
    232         when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext);
    233         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    234                 .thenReturn(UserHandle.myUserId());
    235         when(mAudioHelper.isUserUnlocked(nullable(UserManager.class), anyInt())).thenReturn(false);
    236 
    237         // When resumed:
    238         mController.displayPreference(mScreen);
    239         mController.onResume();
    240 
    241         verify(mWorkCategory, times(2)).setVisible(true);
    242 
    243         // Sound preferences should explain that the profile isn't available yet.
    244         verify(mWorkCategory.findPreference(KEY_WORK_PHONE_RINGTONE))
    245                 .setSummary(eq(notAvailable));
    246         verify(mWorkCategory.findPreference(KEY_WORK_NOTIFICATION_RINGTONE))
    247                 .setSummary(eq(notAvailable));
    248         verify(mWorkCategory.findPreference(KEY_WORK_ALARM_RINGTONE))
    249                 .setSummary(eq(notAvailable));
    250     }
    251 
    252     @Test
    253     public void onResume_shouldSetUserIdToPreference() {
    254         final int managedProfileUserId = 10;
    255         when(mAudioHelper.getManagedProfileId(nullable(UserManager.class)))
    256                 .thenReturn(managedProfileUserId);
    257         when(mAudioHelper.isUserUnlocked(nullable(UserManager.class), anyInt())).thenReturn(true);
    258         when(mAudioHelper.isSingleVolume()).thenReturn(false);
    259         when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
    260         when(mAudioHelper.createPackageContextAsUser(anyInt())).thenReturn(mContext);
    261 
    262         mController.displayPreference(mScreen);
    263         mController.onResume();
    264 
    265         verify((RingtonePreference) mWorkCategory.findPreference(KEY_WORK_PHONE_RINGTONE))
    266                 .setUserId(managedProfileUserId);
    267         verify((RingtonePreference) mWorkCategory.findPreference(KEY_WORK_NOTIFICATION_RINGTONE))
    268                 .setUserId(managedProfileUserId);
    269         verify((RingtonePreference) mWorkCategory.findPreference(KEY_WORK_ALARM_RINGTONE))
    270                 .setUserId(managedProfileUserId);
    271     }
    272 }
    273