1 /* 2 * Copyright (C) 2020 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.deskclock.ringtone; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.content.SharedPreferences; 22 import android.net.Uri; 23 import android.preference.PreferenceManager; 24 25 import androidx.recyclerview.widget.RecyclerView; 26 import androidx.test.InstrumentationRegistry; 27 import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner; 28 import androidx.test.rule.ActivityTestRule; 29 30 import com.android.deskclock.ItemAdapter; 31 import com.android.deskclock.ItemAdapter.ItemHolder; 32 import com.android.deskclock.R; 33 import com.android.deskclock.Utils; 34 import com.android.deskclock.data.DataModel; 35 import com.android.deskclock.provider.Alarm; 36 37 import org.junit.After; 38 import org.junit.Before; 39 import org.junit.Rule; 40 import org.junit.Test; 41 import org.junit.runner.RunWith; 42 43 import java.util.Iterator; 44 import java.util.List; 45 46 import static org.junit.Assert.assertEquals; 47 48 /** 49 * Exercise the user interface that adjusts the selected ringtone. 50 */ 51 @RunWith(AndroidJUnit4ClassRunner.class) 52 public class RingtonePickerActivityTest { 53 54 private RingtonePickerActivity activity; 55 private RecyclerView ringtoneList; 56 private ItemAdapter<ItemHolder<Uri>> ringtoneAdapter; 57 58 public static final Uri ALERT = Uri.parse("content://settings/system/alarm_alert"); 59 public static final Uri CUSTOM_RINGTONE_1 = Uri.parse("content://media/external/audio/one.ogg"); 60 61 @Rule 62 public ActivityTestRule<RingtonePickerActivity> rule = 63 new ActivityTestRule<>(RingtonePickerActivity.class, true, false); 64 65 @Before 66 @After setUp()67 public void setUp() { 68 Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); 69 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); 70 prefs.edit().clear().commit(); 71 } 72 73 @Test validateDefaultState_TimerRingtonePicker()74 public void validateDefaultState_TimerRingtonePicker() { 75 createTimerRingtonePickerActivity(); 76 77 final List<ItemHolder<Uri>> systemRingtoneHolders = ringtoneAdapter.getItems(); 78 final Iterator<ItemHolder<Uri>> itemsIter = systemRingtoneHolders.iterator(); 79 80 final HeaderHolder filesHeaderHolder = (HeaderHolder) itemsIter.next(); 81 assertEquals(R.string.your_sounds, filesHeaderHolder.getTextResId()); 82 assertEquals(HeaderViewHolder.VIEW_TYPE_ITEM_HEADER, filesHeaderHolder.getItemViewType()); 83 84 final AddCustomRingtoneHolder addNewHolder = (AddCustomRingtoneHolder) itemsIter.next(); 85 assertEquals(AddCustomRingtoneViewHolder.VIEW_TYPE_ADD_NEW, addNewHolder.getItemViewType()); 86 87 final HeaderHolder systemHeaderHolder = (HeaderHolder) itemsIter.next(); 88 assertEquals(R.string.device_sounds, systemHeaderHolder.getTextResId()); 89 assertEquals(HeaderViewHolder.VIEW_TYPE_ITEM_HEADER, systemHeaderHolder.getItemViewType()); 90 91 final RingtoneHolder silentHolder = (RingtoneHolder) itemsIter.next(); 92 assertEquals(Utils.RINGTONE_SILENT, silentHolder.getUri()); 93 assertEquals(RingtoneViewHolder.VIEW_TYPE_SYSTEM_SOUND, silentHolder.getItemViewType()); 94 95 final RingtoneHolder defaultHolder = (RingtoneHolder) itemsIter.next(); 96 assertEquals(RingtoneViewHolder.VIEW_TYPE_SYSTEM_SOUND, defaultHolder.getItemViewType()); 97 98 Runnable assertRunnable = () -> { 99 assertEquals("Silent", silentHolder.getName()); 100 assertEquals("Timer Expired", defaultHolder.getName()); 101 assertEquals(DataModel.getDataModel().getDefaultTimerRingtoneUri(), 102 defaultHolder.getUri()); 103 // Verify initial selection. 104 assertEquals( 105 DataModel.getDataModel().getTimerRingtoneUri(), 106 DataModel.getDataModel().getDefaultTimerRingtoneUri()); 107 }; 108 InstrumentationRegistry.getInstrumentation().runOnMainSync(assertRunnable); 109 } 110 111 @Test validateDefaultState_AlarmRingtonePicker()112 public void validateDefaultState_AlarmRingtonePicker() { 113 createAlarmRingtonePickerActivity(ALERT); 114 115 final List<ItemHolder<Uri>> systemRingtoneHolders = ringtoneAdapter.getItems(); 116 final Iterator<ItemHolder<Uri>> itemsIter = systemRingtoneHolders.iterator(); 117 118 final HeaderHolder filesHeaderHolder = (HeaderHolder) itemsIter.next(); 119 assertEquals(R.string.your_sounds, filesHeaderHolder.getTextResId()); 120 assertEquals(HeaderViewHolder.VIEW_TYPE_ITEM_HEADER, filesHeaderHolder.getItemViewType()); 121 122 final AddCustomRingtoneHolder addNewHolder = (AddCustomRingtoneHolder) itemsIter.next(); 123 assertEquals(AddCustomRingtoneViewHolder.VIEW_TYPE_ADD_NEW, addNewHolder.getItemViewType()); 124 125 final HeaderHolder systemHeaderHolder = (HeaderHolder) itemsIter.next(); 126 assertEquals(R.string.device_sounds, systemHeaderHolder.getTextResId()); 127 assertEquals(HeaderViewHolder.VIEW_TYPE_ITEM_HEADER, systemHeaderHolder.getItemViewType()); 128 129 final RingtoneHolder silentHolder = (RingtoneHolder) itemsIter.next(); 130 assertEquals(Utils.RINGTONE_SILENT, silentHolder.getUri()); 131 assertEquals(RingtoneViewHolder.VIEW_TYPE_SYSTEM_SOUND, silentHolder.getItemViewType()); 132 133 final RingtoneHolder defaultHolder = (RingtoneHolder) itemsIter.next(); 134 assertEquals(RingtoneViewHolder.VIEW_TYPE_SYSTEM_SOUND, defaultHolder.getItemViewType()); 135 136 Runnable assertRunnable = () -> { 137 assertEquals("Silent", silentHolder.getName()); 138 assertEquals("Default alarm sound", defaultHolder.getName()); 139 assertEquals(DataModel.getDataModel().getDefaultAlarmRingtoneUri(), 140 defaultHolder.getUri()); 141 }; 142 InstrumentationRegistry.getInstrumentation().runOnMainSync(assertRunnable); 143 } 144 145 @Test validateDefaultState_TimerRingtonePicker_WithCustomRingtones()146 public void validateDefaultState_TimerRingtonePicker_WithCustomRingtones() { 147 Runnable customRingtoneRunnable = () -> { 148 DataModel.getDataModel().addCustomRingtone(CUSTOM_RINGTONE_1, "CustomSound"); 149 }; 150 InstrumentationRegistry.getInstrumentation().runOnMainSync(customRingtoneRunnable); 151 createTimerRingtonePickerActivity(); 152 153 final List<ItemHolder<Uri>> systemRingtoneHolders = ringtoneAdapter.getItems(); 154 final Iterator<ItemHolder<Uri>> itemsIter = systemRingtoneHolders.iterator(); 155 156 final HeaderHolder filesHeaderHolder = (HeaderHolder) itemsIter.next(); 157 assertEquals(R.string.your_sounds, filesHeaderHolder.getTextResId()); 158 assertEquals(HeaderViewHolder.VIEW_TYPE_ITEM_HEADER, filesHeaderHolder.getItemViewType()); 159 160 final CustomRingtoneHolder customRingtoneHolder = (CustomRingtoneHolder) itemsIter.next(); 161 assertEquals("CustomSound", customRingtoneHolder.getName()); 162 assertEquals(CUSTOM_RINGTONE_1, customRingtoneHolder.getUri()); 163 assertEquals(RingtoneViewHolder.VIEW_TYPE_CUSTOM_SOUND, 164 customRingtoneHolder.getItemViewType()); 165 166 final AddCustomRingtoneHolder addNewHolder = (AddCustomRingtoneHolder) itemsIter.next(); 167 assertEquals(AddCustomRingtoneViewHolder.VIEW_TYPE_ADD_NEW, addNewHolder.getItemViewType()); 168 169 final HeaderHolder systemHeaderHolder = (HeaderHolder) itemsIter.next(); 170 assertEquals(R.string.device_sounds, systemHeaderHolder.getTextResId()); 171 assertEquals(HeaderViewHolder.VIEW_TYPE_ITEM_HEADER, systemHeaderHolder.getItemViewType()); 172 173 final RingtoneHolder silentHolder = (RingtoneHolder) itemsIter.next(); 174 assertEquals(Utils.RINGTONE_SILENT, silentHolder.getUri()); 175 assertEquals(RingtoneViewHolder.VIEW_TYPE_SYSTEM_SOUND, silentHolder.getItemViewType()); 176 177 final RingtoneHolder defaultHolder = (RingtoneHolder) itemsIter.next(); 178 assertEquals(RingtoneViewHolder.VIEW_TYPE_SYSTEM_SOUND, defaultHolder.getItemViewType()); 179 180 Runnable assertRunnable = () -> { 181 assertEquals("Silent", silentHolder.getName()); 182 assertEquals("Timer Expired", defaultHolder.getName()); 183 assertEquals(DataModel.getDataModel().getDefaultTimerRingtoneUri(), 184 defaultHolder.getUri()); 185 // Verify initial selection. 186 assertEquals( 187 DataModel.getDataModel().getTimerRingtoneUri(), 188 DataModel.getDataModel().getDefaultTimerRingtoneUri()); 189 }; 190 InstrumentationRegistry.getInstrumentation().runOnMainSync(assertRunnable); 191 192 Runnable removeCustomRingtoneRunnable = () -> { 193 DataModel.getDataModel().removeCustomRingtone(CUSTOM_RINGTONE_1); 194 }; 195 InstrumentationRegistry.getInstrumentation().runOnMainSync(removeCustomRingtoneRunnable); 196 } 197 198 @Test validateDefaultState_AlarmRingtonePicker_WithCustomRingtones()199 public void validateDefaultState_AlarmRingtonePicker_WithCustomRingtones() { 200 Runnable customRingtoneRunnable = () -> { 201 DataModel.getDataModel().addCustomRingtone(CUSTOM_RINGTONE_1, "CustomSound"); 202 }; 203 InstrumentationRegistry.getInstrumentation().runOnMainSync(customRingtoneRunnable); 204 createAlarmRingtonePickerActivity(ALERT); 205 206 final List<ItemHolder<Uri>> systemRingtoneHolders = ringtoneAdapter.getItems(); 207 final Iterator<ItemHolder<Uri>> itemsIter = systemRingtoneHolders.iterator(); 208 209 final HeaderHolder filesHeaderHolder = (HeaderHolder) itemsIter.next(); 210 assertEquals(R.string.your_sounds, filesHeaderHolder.getTextResId()); 211 assertEquals(HeaderViewHolder.VIEW_TYPE_ITEM_HEADER, filesHeaderHolder.getItemViewType()); 212 213 final CustomRingtoneHolder customRingtoneHolder = (CustomRingtoneHolder) itemsIter.next(); 214 assertEquals("CustomSound", customRingtoneHolder.getName()); 215 assertEquals(CUSTOM_RINGTONE_1, customRingtoneHolder.getUri()); 216 assertEquals(RingtoneViewHolder.VIEW_TYPE_CUSTOM_SOUND, 217 customRingtoneHolder.getItemViewType()); 218 219 final AddCustomRingtoneHolder addNewHolder = (AddCustomRingtoneHolder) itemsIter.next(); 220 assertEquals(AddCustomRingtoneViewHolder.VIEW_TYPE_ADD_NEW, addNewHolder.getItemViewType()); 221 222 final HeaderHolder systemHeaderHolder = (HeaderHolder) itemsIter.next(); 223 assertEquals(R.string.device_sounds, systemHeaderHolder.getTextResId()); 224 assertEquals(HeaderViewHolder.VIEW_TYPE_ITEM_HEADER, systemHeaderHolder.getItemViewType()); 225 226 final RingtoneHolder silentHolder = (RingtoneHolder) itemsIter.next(); 227 assertEquals(Utils.RINGTONE_SILENT, silentHolder.getUri()); 228 assertEquals(RingtoneViewHolder.VIEW_TYPE_SYSTEM_SOUND, silentHolder.getItemViewType()); 229 230 final RingtoneHolder defaultHolder = (RingtoneHolder) itemsIter.next(); 231 assertEquals(RingtoneViewHolder.VIEW_TYPE_SYSTEM_SOUND, defaultHolder.getItemViewType()); 232 233 Runnable assertRunnable = () -> { 234 assertEquals("Silent", silentHolder.getName()); 235 assertEquals("Default alarm sound", defaultHolder.getName()); 236 assertEquals(DataModel.getDataModel().getDefaultAlarmRingtoneUri(), 237 defaultHolder.getUri()); 238 }; 239 InstrumentationRegistry.getInstrumentation().runOnMainSync(assertRunnable); 240 241 Runnable removeCustomRingtoneRunnable = () -> { 242 DataModel.getDataModel().removeCustomRingtone(CUSTOM_RINGTONE_1); 243 }; 244 InstrumentationRegistry.getInstrumentation().runOnMainSync(removeCustomRingtoneRunnable); 245 } 246 createTimerRingtonePickerActivity()247 private void createTimerRingtonePickerActivity() { 248 final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); 249 final Intent newIntent = new Intent(); 250 251 Runnable createIntentRunnable = () -> { 252 final Intent intent = RingtonePickerActivity.createTimerRingtonePickerIntent(context); 253 newIntent.fillIn(intent, 0); 254 }; 255 InstrumentationRegistry.getInstrumentation().runOnMainSync(createIntentRunnable); 256 257 createRingtonePickerActivity(newIntent); 258 } 259 createAlarmRingtonePickerActivity(Uri ringtone)260 private void createAlarmRingtonePickerActivity(Uri ringtone) { 261 final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); 262 final Intent newIntent = new Intent(); 263 264 Runnable createIntentRunnable = () -> { 265 // Use the custom ringtone in some alarms. 266 final Alarm alarm = new Alarm(1, 1); 267 alarm.enabled = true; 268 alarm.vibrate = true; 269 alarm.alert = ringtone; 270 alarm.deleteAfterUse = true; 271 272 final Intent intent = 273 RingtonePickerActivity.createAlarmRingtonePickerIntent(context, alarm); 274 newIntent.fillIn(intent, 0); 275 }; 276 InstrumentationRegistry.getInstrumentation().runOnMainSync(createIntentRunnable); 277 278 createRingtonePickerActivity(newIntent); 279 } 280 281 @SuppressWarnings("unchecked") createRingtonePickerActivity(Intent intent)282 private void createRingtonePickerActivity(Intent intent) { 283 activity = rule.launchActivity(intent); 284 ringtoneList = activity.findViewById(R.id.ringtone_content); 285 ringtoneAdapter = (ItemAdapter<ItemHolder<Uri>>) ringtoneList.getAdapter(); 286 } 287 } 288