• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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.ContentResolver;
20 import android.content.Context;
21 import android.database.ContentObserver;
22 import android.media.Ringtone;
23 import android.media.RingtoneManager;
24 import android.net.Uri;
25 import android.os.Handler;
26 import android.provider.Settings;
27 import android.util.ArrayMap;
28 
29 import com.android.deskclock.LogUtils;
30 import com.android.deskclock.R;
31 import com.android.deskclock.provider.Alarm;
32 
33 import java.util.Map;
34 
35 /**
36  * All alarm data will eventually be accessed via this model.
37  */
38 final class AlarmModel {
39 
40     private final Context mContext;
41 
42     /** The model from which settings are fetched. */
43     private final SettingsModel mSettingsModel;
44 
45     /** The uri of the default ringtone to play for new alarms; mirrors last selection. */
46     private Uri mDefaultAlarmRingtoneUri;
47 
48     /** Maps ringtone uri to ringtone title; looking up a title from scratch is expensive. */
49     private final Map<Uri, String> mRingtoneTitles = new ArrayMap<>(8);
50 
AlarmModel(Context context, SettingsModel settingsModel)51     AlarmModel(Context context, SettingsModel settingsModel) {
52         mContext = context;
53         mSettingsModel = settingsModel;
54 
55         // Clear caches affected by system settings when system settings change.
56         final ContentResolver cr = mContext.getContentResolver();
57         final ContentObserver observer = new SystemAlarmAlertChangeObserver();
58         cr.registerContentObserver(Settings.System.DEFAULT_ALARM_ALERT_URI, false, observer);
59     }
60 
getDefaultAlarmRingtoneUri()61     Uri getDefaultAlarmRingtoneUri() {
62         if (mDefaultAlarmRingtoneUri == null) {
63             mDefaultAlarmRingtoneUri = mSettingsModel.getDefaultAlarmRingtoneUri();
64         }
65 
66         return mDefaultAlarmRingtoneUri;
67     }
68 
setDefaultAlarmRingtoneUri(Uri uri)69     void setDefaultAlarmRingtoneUri(Uri uri) {
70         mSettingsModel.setDefaultAlarmRingtoneUri(uri);
71         mDefaultAlarmRingtoneUri = uri;
72     }
73 
getAlarmRingtoneTitle(Uri uri)74     String getAlarmRingtoneTitle(Uri uri) {
75         // Special case: no ringtone has a title of "Silent".
76         if (Alarm.NO_RINGTONE_URI.equals(uri)) {
77             return mContext.getString(R.string.silent_ringtone_title);
78         }
79 
80         // Check the cache.
81         String title = mRingtoneTitles.get(uri);
82 
83         if (title == null) {
84             // This is slow because a media player is created during Ringtone object creation.
85             final Ringtone ringtone = RingtoneManager.getRingtone(mContext, uri);
86             if (ringtone == null) {
87                 LogUtils.e("No ringtone for uri: %s", uri);
88                 return mContext.getString(R.string.unknown_ringtone_title);
89             }
90 
91             // Cache the title for later use.
92             title = ringtone.getTitle(mContext);
93             mRingtoneTitles.put(uri, title);
94         }
95         return title;
96     }
97 
98     /**
99      * This receiver is notified when system settings change. Cached information built on
100      * those system settings must be cleared.
101      */
102     private final class SystemAlarmAlertChangeObserver extends ContentObserver {
103 
SystemAlarmAlertChangeObserver()104         private SystemAlarmAlertChangeObserver() {
105             super(new Handler());
106         }
107 
108         @Override
onChange(boolean selfChange)109         public void onChange(boolean selfChange) {
110             super.onChange(selfChange);
111 
112             LogUtils.i("Detected change to system default alarm ringtone; clearing caches");
113 
114             mDefaultAlarmRingtoneUri = null;
115 
116             // Titles such as "Default ringtone (Oxygen)" are wrong after default ringtone changes.
117             mRingtoneTitles.clear();
118         }
119     }
120 }