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.database.MatrixCursor 21 import android.media.AudioManager 22 import android.media.RingtoneManager 23 import android.net.Uri 24 import androidx.loader.content.AsyncTaskLoader 25 26 import com.android.deskclock.ItemAdapter.ItemHolder 27 import com.android.deskclock.LogUtils 28 import com.android.deskclock.R 29 import com.android.deskclock.Utils 30 import com.android.deskclock.data.CustomRingtone 31 import com.android.deskclock.data.DataModel 32 33 /** 34 * Assembles the list of ItemHolders that back the RecyclerView used to choose a ringtone. 35 */ 36 internal class RingtoneLoader( 37 context: Context, 38 private val mDefaultRingtoneUri: Uri, 39 private val mDefaultRingtoneTitle: String 40 ) : AsyncTaskLoader<List<ItemHolder<Uri?>>>(context) { 41 private var mCustomRingtones: List<CustomRingtone>? = null 42 onStartLoadingnull43 override fun onStartLoading() { 44 super.onStartLoading() 45 46 mCustomRingtones = DataModel.dataModel.customRingtones 47 forceLoad() 48 } 49 loadInBackgroundnull50 override fun loadInBackground(): List<ItemHolder<Uri?>> { 51 // Prime the ringtone title cache for later access. 52 DataModel.dataModel.loadRingtoneTitles() 53 DataModel.dataModel.loadRingtonePermissions() 54 55 // Fetch the standard system ringtones. 56 val ringtoneManager = RingtoneManager(context) 57 ringtoneManager.setType(AudioManager.STREAM_ALARM) 58 59 val systemRingtoneCursor = try { 60 ringtoneManager.cursor 61 } catch (e: Exception) { 62 LogUtils.e("Could not get system ringtone cursor") 63 MatrixCursor(arrayOf()) 64 } 65 val systemRingtoneCount = systemRingtoneCursor.count 66 // item count = # system ringtones + # custom ringtones + 2 headers + Add new music item 67 val itemCount = systemRingtoneCount + mCustomRingtones!!.size + 3 68 69 val itemHolders: MutableList<ItemHolder<Uri?>> = ArrayList(itemCount) 70 71 // Add the item holder for the Music heading. 72 itemHolders.add(HeaderHolder(R.string.your_sounds)) 73 74 // Add an item holder for each custom ringtone and also cache a pretty name. 75 for (ringtone in mCustomRingtones!!) { 76 itemHolders.add(CustomRingtoneHolder(ringtone)) 77 } 78 79 // Add an item holder for the "Add new" music ringtone. 80 itemHolders.add(AddCustomRingtoneHolder()) 81 82 // Add an item holder for the Ringtones heading. 83 itemHolders.add(HeaderHolder(R.string.device_sounds)) 84 85 // Add an item holder for the silent ringtone. 86 itemHolders.add(SystemRingtoneHolder(Utils.RINGTONE_SILENT, null)) 87 88 // Add an item holder for the system default alarm sound. 89 itemHolders.add(SystemRingtoneHolder(mDefaultRingtoneUri, mDefaultRingtoneTitle)) 90 91 // Add an item holder for each system ringtone. 92 for (i in 0 until systemRingtoneCount) { 93 val ringtoneUri = ringtoneManager.getRingtoneUri(i) 94 itemHolders.add(SystemRingtoneHolder(ringtoneUri, null)) 95 } 96 97 return itemHolders 98 } 99 onResetnull100 override fun onReset() { 101 super.onReset() 102 mCustomRingtones = null 103 } 104 }