16a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux/* 26a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux * Copyright (C) 2015 The Android Open Source Project 36a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux * 46a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux * Licensed under the Apache License, Version 2.0 (the "License"); 56a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux * you may not use this file except in compliance with the License. 66a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux * You may obtain a copy of the License at 76a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux * 86a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux * http://www.apache.org/licenses/LICENSE-2.0 96a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux * 106a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux * Unless required by applicable law or agreed to in writing, software 116a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux * distributed under the License is distributed on an "AS IS" BASIS, 126a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux * See the License for the specific language governing permissions and 146a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux * limitations under the License. 156a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux */ 166a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 176a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieuxpackage com.android.deskclock.data; 186a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 196a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieuximport android.content.ContentResolver; 206a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieuximport android.content.Context; 216a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieuximport android.database.ContentObserver; 226a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieuximport android.media.Ringtone; 236a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieuximport android.media.RingtoneManager; 246a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieuximport android.net.Uri; 256a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieuximport android.os.Handler; 266a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieuximport android.provider.Settings; 276a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieuximport android.util.ArrayMap; 286a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 296a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieuximport com.android.deskclock.LogUtils; 306a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieuximport com.android.deskclock.R; 316a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieuximport com.android.deskclock.provider.Alarm; 326a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 336a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieuximport java.util.Map; 346a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 356a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux/** 366a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux * All alarm data will eventually be accessed via this model. 376a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux */ 386a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieuxfinal class AlarmModel { 396a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 406a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux private final Context mContext; 416a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 426a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux /** The model from which settings are fetched. */ 436a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux private final SettingsModel mSettingsModel; 446a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 456a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux /** The uri of the default ringtone to play for new alarms; mirrors last selection. */ 466a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux private Uri mDefaultAlarmRingtoneUri; 476a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 486a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux /** Maps ringtone uri to ringtone title; looking up a title from scratch is expensive. */ 496a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux private final Map<Uri, String> mRingtoneTitles = new ArrayMap<>(8); 506a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 516a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux AlarmModel(Context context, SettingsModel settingsModel) { 526a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux mContext = context; 536a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux mSettingsModel = settingsModel; 546a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 556a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux // Clear caches affected by system settings when system settings change. 566a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux final ContentResolver cr = mContext.getContentResolver(); 576a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux final ContentObserver observer = new SystemAlarmAlertChangeObserver(); 586a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux cr.registerContentObserver(Settings.System.DEFAULT_ALARM_ALERT_URI, false, observer); 596a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux } 606a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 616a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux Uri getDefaultAlarmRingtoneUri() { 626a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux if (mDefaultAlarmRingtoneUri == null) { 636a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux mDefaultAlarmRingtoneUri = mSettingsModel.getDefaultAlarmRingtoneUri(); 646a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux } 656a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 666a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux return mDefaultAlarmRingtoneUri; 676a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux } 686a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 696a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux void setDefaultAlarmRingtoneUri(Uri uri) { 706a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux mSettingsModel.setDefaultAlarmRingtoneUri(uri); 716a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux mDefaultAlarmRingtoneUri = uri; 726a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux } 736a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 746a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux String getAlarmRingtoneTitle(Uri uri) { 756a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux // Special case: no ringtone has a title of "Silent". 766a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux if (Alarm.NO_RINGTONE_URI.equals(uri)) { 776a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux return mContext.getString(R.string.silent_ringtone_title); 786a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux } 796a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 806a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux // Check the cache. 816a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux String title = mRingtoneTitles.get(uri); 826a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 836a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux if (title == null) { 846a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux // This is slow because a media player is created during Ringtone object creation. 856a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux final Ringtone ringtone = RingtoneManager.getRingtone(mContext, uri); 866a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux if (ringtone == null) { 876a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux LogUtils.e("No ringtone for uri: %s", uri); 886a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux return mContext.getString(R.string.unknown_ringtone_title); 896a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux } 906a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 916a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux // Cache the title for later use. 926a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux title = ringtone.getTitle(mContext); 936a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux mRingtoneTitles.put(uri, title); 946a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux } 956a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux return title; 966a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux } 976a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 986a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux /** 996a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux * This receiver is notified when system settings change. Cached information built on 1006a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux * those system settings must be cleared. 1016a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux */ 1026a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux private final class SystemAlarmAlertChangeObserver extends ContentObserver { 1036a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 1046a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux private SystemAlarmAlertChangeObserver() { 1056a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux super(new Handler()); 1066a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux } 1076a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 1086a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux @Override 1096a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux public void onChange(boolean selfChange) { 1106a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux super.onChange(selfChange); 1116a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 1126a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux LogUtils.i("Detected change to system default alarm ringtone; clearing caches"); 1136a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 1146a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux mDefaultAlarmRingtoneUri = null; 1156a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 1166a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux // Titles such as "Default ringtone (Oxygen)" are wrong after default ringtone changes. 1176a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux mRingtoneTitles.clear(); 1186a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux } 1196a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux } 1206a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux}