1098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey/* 2098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey * Copyright (C) 2012 The Android Open Source Project 3098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey * 4098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey * you may not use this file except in compliance with the License. 6098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey * You may obtain a copy of the License at 7098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey * 8098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey * 10098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 11098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey * See the License for the specific language governing permissions and 14098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey * limitations under the License. 15098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey */ 16098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 17098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkeypackage com.android.systemui.media; 18098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 19783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkeyimport android.content.ContentResolver; 20098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkeyimport android.content.Context; 2165c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkeyimport android.content.pm.PackageManager.NameNotFoundException; 22783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkeyimport android.database.Cursor; 2381f871e2b96125d57b76c07169e868e516443794Jean-Michel Triviimport android.media.AudioAttributes; 24098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkeyimport android.media.IAudioService; 25098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkeyimport android.media.IRingtonePlayer; 26098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkeyimport android.media.Ringtone; 27098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkeyimport android.net.Uri; 28098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkeyimport android.os.Binder; 29098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkeyimport android.os.IBinder; 30783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkeyimport android.os.ParcelFileDescriptor; 31098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkeyimport android.os.Process; 32098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkeyimport android.os.RemoteException; 33098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkeyimport android.os.ServiceManager; 3465c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkeyimport android.os.UserHandle; 35783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkeyimport android.provider.MediaStore; 36783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkeyimport android.provider.MediaStore.Audio.AudioColumns; 37cd686b5b6d4166b510df8e32138479a9559bc117John Spurlockimport android.util.Log; 38098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 39783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkeyimport com.android.internal.util.Preconditions; 40098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkeyimport com.android.systemui.SystemUI; 41098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 42098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkeyimport java.io.FileDescriptor; 43783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkeyimport java.io.IOException; 44098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkeyimport java.io.PrintWriter; 45098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkeyimport java.util.HashMap; 46098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 47098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey/** 48098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey * Service that offers to play ringtones by {@link Uri}, since our process has 49098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE}. 50098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey */ 51098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkeypublic class RingtonePlayer extends SystemUI { 52098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey private static final String TAG = "RingtonePlayer"; 53b6e404a95f31f4681265eb53d2b7969f900151ccJeff Sharkey private static final boolean LOGD = false; 54098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 55098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey // TODO: support Uri switching under same IBinder 56098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 57098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey private IAudioService mAudioService; 58098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 59098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey private final NotificationPlayer mAsyncPlayer = new NotificationPlayer(TAG); 60b8bacccfc159fe204e5b09b52de55f8ba853f713John Spurlock private final HashMap<IBinder, Client> mClients = new HashMap<IBinder, Client>(); 61098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 62098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey @Override 63098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey public void start() { 64098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey mAsyncPlayer.setUsesWakeLock(mContext); 65098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 66098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey mAudioService = IAudioService.Stub.asInterface( 67098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey ServiceManager.getService(Context.AUDIO_SERVICE)); 68098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey try { 69098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey mAudioService.setRingtonePlayer(mCallback); 70098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } catch (RemoteException e) { 71cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock Log.e(TAG, "Problem registering RingtonePlayer: " + e); 72098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 73098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 74098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 75098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey /** 76098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey * Represents an active remote {@link Ringtone} client. 77098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey */ 78098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey private class Client implements IBinder.DeathRecipient { 79098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey private final IBinder mToken; 80098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey private final Ringtone mRingtone; 81098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 8281f871e2b96125d57b76c07169e868e516443794Jean-Michel Trivi public Client(IBinder token, Uri uri, UserHandle user, AudioAttributes aa) { 83098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey mToken = token; 8465c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkey 8565c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkey mRingtone = new Ringtone(getContextForUser(user), false); 8681f871e2b96125d57b76c07169e868e516443794Jean-Michel Trivi mRingtone.setAudioAttributes(aa); 87098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey mRingtone.setUri(uri); 88098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 89098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 90098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey @Override 91098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey public void binderDied() { 92cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock if (LOGD) Log.d(TAG, "binderDied() token=" + mToken); 93098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey synchronized (mClients) { 94098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey mClients.remove(mToken); 95098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 96098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey mRingtone.stop(); 97098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 98098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 99098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 100098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey private IRingtonePlayer mCallback = new IRingtonePlayer.Stub() { 101098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey @Override 102462045e89aed0163a4681b8221f0df3f26900136Jean-Michel Trivi public void play(IBinder token, Uri uri, AudioAttributes aa, float volume, boolean looping) 103462045e89aed0163a4681b8221f0df3f26900136Jean-Michel Trivi throws RemoteException { 10465c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkey if (LOGD) { 105cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock Log.d(TAG, "play(token=" + token + ", uri=" + uri + ", uid=" 10665c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkey + Binder.getCallingUid() + ")"); 10765c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkey } 108098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey Client client; 109098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey synchronized (mClients) { 110098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey client = mClients.get(token); 111098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey if (client == null) { 11265c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkey final UserHandle user = Binder.getCallingUserHandle(); 11381f871e2b96125d57b76c07169e868e516443794Jean-Michel Trivi client = new Client(token, uri, user, aa); 114098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey token.linkToDeath(client, 0); 115098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey mClients.put(token, client); 116098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 117098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 118462045e89aed0163a4681b8221f0df3f26900136Jean-Michel Trivi client.mRingtone.setLooping(looping); 119462045e89aed0163a4681b8221f0df3f26900136Jean-Michel Trivi client.mRingtone.setVolume(volume); 120098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey client.mRingtone.play(); 121098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 122098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 123098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey @Override 124098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey public void stop(IBinder token) { 125cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock if (LOGD) Log.d(TAG, "stop(token=" + token + ")"); 126098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey Client client; 127098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey synchronized (mClients) { 128098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey client = mClients.remove(token); 129098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 130098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey if (client != null) { 131098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey client.mToken.unlinkToDeath(client, 0); 132098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey client.mRingtone.stop(); 133098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 134098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 135098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 136098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey @Override 137098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey public boolean isPlaying(IBinder token) { 138cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock if (LOGD) Log.d(TAG, "isPlaying(token=" + token + ")"); 139098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey Client client; 140098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey synchronized (mClients) { 141098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey client = mClients.get(token); 142098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 143098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey if (client != null) { 144098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey return client.mRingtone.isPlaying(); 145098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } else { 146098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey return false; 147098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 148098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 149098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 150098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey @Override 151462045e89aed0163a4681b8221f0df3f26900136Jean-Michel Trivi public void setPlaybackProperties(IBinder token, float volume, boolean looping) { 152462045e89aed0163a4681b8221f0df3f26900136Jean-Michel Trivi Client client; 153462045e89aed0163a4681b8221f0df3f26900136Jean-Michel Trivi synchronized (mClients) { 154462045e89aed0163a4681b8221f0df3f26900136Jean-Michel Trivi client = mClients.get(token); 155462045e89aed0163a4681b8221f0df3f26900136Jean-Michel Trivi } 156462045e89aed0163a4681b8221f0df3f26900136Jean-Michel Trivi if (client != null) { 157462045e89aed0163a4681b8221f0df3f26900136Jean-Michel Trivi client.mRingtone.setVolume(volume); 158462045e89aed0163a4681b8221f0df3f26900136Jean-Michel Trivi client.mRingtone.setLooping(looping); 159462045e89aed0163a4681b8221f0df3f26900136Jean-Michel Trivi } 160462045e89aed0163a4681b8221f0df3f26900136Jean-Michel Trivi // else no client for token when setting playback properties but will be set at play() 161462045e89aed0163a4681b8221f0df3f26900136Jean-Michel Trivi } 162462045e89aed0163a4681b8221f0df3f26900136Jean-Michel Trivi 163462045e89aed0163a4681b8221f0df3f26900136Jean-Michel Trivi @Override 16481f871e2b96125d57b76c07169e868e516443794Jean-Michel Trivi public void playAsync(Uri uri, UserHandle user, boolean looping, AudioAttributes aa) { 165cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock if (LOGD) Log.d(TAG, "playAsync(uri=" + uri + ", user=" + user + ")"); 166098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey if (Binder.getCallingUid() != Process.SYSTEM_UID) { 167098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey throw new SecurityException("Async playback only available from system UID."); 168098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 1694a05bbcd38604cbbcbac66af1abc69ecffddad8bSungmin Choi if (UserHandle.ALL.equals(user)) { 170e4de5a0d3b6e0c897c1cea0912b58e11db962365Xiaohui Chen user = UserHandle.SYSTEM; 1714a05bbcd38604cbbcbac66af1abc69ecffddad8bSungmin Choi } 17281f871e2b96125d57b76c07169e868e516443794Jean-Michel Trivi mAsyncPlayer.play(getContextForUser(user), uri, looping, aa); 173098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 174098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 175098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey @Override 176098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey public void stopAsync() { 177cd686b5b6d4166b510df8e32138479a9559bc117John Spurlock if (LOGD) Log.d(TAG, "stopAsync()"); 178098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey if (Binder.getCallingUid() != Process.SYSTEM_UID) { 179098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey throw new SecurityException("Async playback only available from system UID."); 180098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 181098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey mAsyncPlayer.stop(); 182098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 18368de157b7810be72a283b9e0db292895d96988a9Todd Kennedy 18468de157b7810be72a283b9e0db292895d96988a9Todd Kennedy @Override 18568de157b7810be72a283b9e0db292895d96988a9Todd Kennedy public String getTitle(Uri uri) { 18668de157b7810be72a283b9e0db292895d96988a9Todd Kennedy final UserHandle user = Binder.getCallingUserHandle(); 18768de157b7810be72a283b9e0db292895d96988a9Todd Kennedy return Ringtone.getTitle(getContextForUser(user), uri, 18868de157b7810be72a283b9e0db292895d96988a9Todd Kennedy false /*followSettingsUri*/, false /*allowRemote*/); 18968de157b7810be72a283b9e0db292895d96988a9Todd Kennedy } 190783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey 191783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey @Override 192783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey public ParcelFileDescriptor openRingtone(Uri uri) { 193783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey final UserHandle user = Binder.getCallingUserHandle(); 194783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey final ContentResolver resolver = getContextForUser(user).getContentResolver(); 195783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey 196783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey // Only open the requested Uri if it's a well-known ringtone or 197783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey // other sound from the platform media store, otherwise this opens 198783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey // up arbitrary access to any file on external storage. 199783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey if (uri.toString().startsWith(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI.toString())) { 200783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey try (Cursor c = resolver.query(uri, new String[] { 201783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey MediaStore.Audio.AudioColumns.IS_RINGTONE, 202783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey MediaStore.Audio.AudioColumns.IS_ALARM, 203783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey MediaStore.Audio.AudioColumns.IS_NOTIFICATION 204783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey }, null, null, null)) { 205783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey if (c.moveToFirst()) { 206783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey if (c.getInt(0) != 0 || c.getInt(1) != 0 || c.getInt(2) != 0) { 207783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey try { 208783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey return resolver.openFileDescriptor(uri, "r"); 209783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey } catch (IOException e) { 210783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey throw new SecurityException(e); 211783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey } 212783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey } 213783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey } 214783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey } 215783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey } 216783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey throw new SecurityException("Uri is not ringtone, alarm, or notification: " + uri); 217783ee0ca8707a4e2977d1afd42cd01a3885a06e6Jeff Sharkey } 218098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey }; 219098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey 22065c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkey private Context getContextForUser(UserHandle user) { 22165c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkey try { 22265c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkey return mContext.createPackageContextAsUser(mContext.getPackageName(), 0, user); 22365c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkey } catch (NameNotFoundException e) { 22465c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkey throw new RuntimeException(e); 22565c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkey } 22665c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkey } 22765c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkey 228098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey @Override 229098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 230098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey pw.println("Clients:"); 231098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey synchronized (mClients) { 232098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey for (Client client : mClients.values()) { 233098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey pw.print(" mToken="); 234098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey pw.print(client.mToken); 235098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey pw.print(" mUri="); 236098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey pw.println(client.mRingtone.getUri()); 237098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 238098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 239098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey } 240098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey} 241