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.data
18 
19 import android.content.SharedPreferences
20 import android.net.Uri
21 
22 /**
23  * This class encapsulates the transfer of data between [CustomRingtone] domain objects and
24  * their permanent storage in [SharedPreferences].
25  */
26 internal object CustomRingtoneDAO {
27     /** Key to a preference that stores the set of all custom ringtone ids.  */
28     private const val RINGTONE_IDS = "ringtone_ids"
29 
30     /** Key to a preference that stores the next unused ringtone id.  */
31     private const val NEXT_RINGTONE_ID = "next_ringtone_id"
32 
33     /** Prefix for a key to a preference that stores the URI associated with the ringtone id.  */
34     private const val RINGTONE_URI = "ringtone_uri_"
35 
36     /** Prefix for a key to a preference that stores the title associated with the ringtone id.  */
37     private const val RINGTONE_TITLE = "ringtone_title_"
38 
39     /**
40      * @param uri points to an audio file located on the file system
41      * @param title the title of the audio content at the given `uri`
42      * @return the newly added custom ringtone
43      */
addCustomRingtonenull44     fun addCustomRingtone(prefs: SharedPreferences, uri: Uri, title: String?): CustomRingtone {
45         val id: Long = prefs.getLong(NEXT_RINGTONE_ID, 0)
46         val ids = getRingtoneIds(prefs)
47         ids.add(id.toString())
48 
49         prefs.edit()
50                 .putString(RINGTONE_URI + id, uri.toString())
51                 .putString(RINGTONE_TITLE + id, title)
52                 .putLong(NEXT_RINGTONE_ID, id + 1)
53                 .putStringSet(RINGTONE_IDS, ids)
54                 .apply()
55 
56         return CustomRingtone(id, uri, title, true)
57     }
58 
59     /**
60      * @param id identifies the ringtone to be removed
61      */
removeCustomRingtonenull62     fun removeCustomRingtone(prefs: SharedPreferences, id: Long) {
63         val ids = getRingtoneIds(prefs)
64         ids.remove(id.toString())
65 
66         val editor: SharedPreferences.Editor = prefs.edit()
67         editor.apply {
68             remove(RINGTONE_URI + id)
69             remove(RINGTONE_TITLE + id)
70             if (ids.isEmpty()) {
71                 remove(RINGTONE_IDS)
72                 remove(NEXT_RINGTONE_ID)
73             } else {
74                 putStringSet(RINGTONE_IDS, ids)
75             }
76             apply()
77         }
78     }
79 
80     /**
81      * @return a list of all known custom ringtones
82      */
getCustomRingtonesnull83     fun getCustomRingtones(prefs: SharedPreferences): MutableList<CustomRingtone> {
84         val ids: Set<String> = prefs.getStringSet(RINGTONE_IDS, emptySet<String>())!!
85         val ringtones: MutableList<CustomRingtone> = ArrayList(ids.size)
86 
87         for (id in ids) {
88             val idLong = id.toLong()
89             val uri: Uri = Uri.parse(prefs.getString(RINGTONE_URI + id, null))
90             val title: String? = prefs.getString(RINGTONE_TITLE + id, null)
91             ringtones.add(CustomRingtone(idLong, uri, title, true))
92         }
93 
94         return ringtones
95     }
96 
getRingtoneIdsnull97     private fun getRingtoneIds(prefs: SharedPreferences): MutableSet<String> {
98         return prefs.getStringSet(RINGTONE_IDS, mutableSetOf<String>())!!
99     }
100 }