19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.media;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.Cursor;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri;
23098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkeyimport android.os.Binder;
24098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkeyimport android.os.RemoteException;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.DrmStore;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.MediaStore;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Ringtone provides a quick method for playing a ringtone, notification, or
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * other similar types of sounds.
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For ways of retrieving {@link Ringtone} objects or to show a ringtone
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * picker, see {@link RingtoneManager}.
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see RingtoneManager
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Ringtone {
42098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    private static final String TAG = "Ringtone";
43098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    private static final boolean LOGD = true;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String[] MEDIA_COLUMNS = new String[] {
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MediaStore.Audio.Media._ID,
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MediaStore.Audio.Media.DATA,
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MediaStore.Audio.Media.TITLE
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String[] DRM_COLUMNS = new String[] {
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DrmStore.Audio._ID,
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DrmStore.Audio.DATA,
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DrmStore.Audio.TITLE
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
57098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    private final Context mContext;
58098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    private final AudioManager mAudioManager;
59098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    private final boolean mAllowRemote;
60098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    private final IRingtonePlayer mRemotePlayer;
61098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    private final Binder mRemoteToken;
62098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey
63098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    private MediaPlayer mLocalPlayer;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Uri mUri;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mTitle;
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mStreamType = AudioManager.STREAM_RING;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
70098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    /** {@hide} */
71098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    public Ringtone(Context context, boolean allowRemote) {
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
73524dc046b1225087f481878a5c3ae7f733c9f0e2Eric Laurent        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
74098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        mAllowRemote = allowRemote;
75098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        mRemotePlayer = allowRemote ? mAudioManager.getRingtonePlayer() : null;
76098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        mRemoteToken = allowRemote ? new Binder() : null;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the stream type where this ringtone will be played.
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param streamType The stream, see {@link AudioManager}.
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setStreamType(int streamType) {
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStreamType = streamType;
86098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey
87098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        // The stream type has to be set before the media player is prepared.
88098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        // Re-initialize it.
89098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        setUri(mUri);
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Gets the stream type where this ringtone will be played.
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The stream type, see {@link AudioManager}.
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getStreamType() {
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mStreamType;
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a human-presentable title for ringtone. Looks in media and DRM
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * content providers. If not in either, uses the filename
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context A context used for querying.
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String getTitle(Context context) {
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mTitle != null) return mTitle;
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mTitle = getTitle(context, mUri, true);
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static String getTitle(Context context, Uri uri, boolean followSettingsUri) {
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Cursor cursor = null;
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ContentResolver res = context.getContentResolver();
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String title = null;
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (uri != null) {
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String authority = uri.getAuthority();
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (Settings.AUTHORITY.equals(authority)) {
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (followSettingsUri) {
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Uri actualUri = RingtoneManager.getActualDefaultRingtoneUri(context,
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            RingtoneManager.getDefaultType(uri));
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String actualTitle = getTitle(context, actualUri, false);
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    title = context
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            .getString(com.android.internal.R.string.ringtone_default_with_actual,
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    actualTitle);
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
1311d8e5c588035550293ecd2558a2e285ee2789d38Jeff Sharkey                try {
1321d8e5c588035550293ecd2558a2e285ee2789d38Jeff Sharkey                    if (DrmStore.AUTHORITY.equals(authority)) {
1331d8e5c588035550293ecd2558a2e285ee2789d38Jeff Sharkey                        cursor = res.query(uri, DRM_COLUMNS, null, null, null);
1341d8e5c588035550293ecd2558a2e285ee2789d38Jeff Sharkey                    } else if (MediaStore.AUTHORITY.equals(authority)) {
1351d8e5c588035550293ecd2558a2e285ee2789d38Jeff Sharkey                        cursor = res.query(uri, MEDIA_COLUMNS, null, null, null);
1361d8e5c588035550293ecd2558a2e285ee2789d38Jeff Sharkey                    }
1371d8e5c588035550293ecd2558a2e285ee2789d38Jeff Sharkey                } catch (SecurityException e) {
1381d8e5c588035550293ecd2558a2e285ee2789d38Jeff Sharkey                    // missing cursor is handled below
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1401d8e5c588035550293ecd2558a2e285ee2789d38Jeff Sharkey
1416b51a98acbc710a4e1a1656d85bb5d3c92f82fe9Josh Guilfoyle                try {
1426b51a98acbc710a4e1a1656d85bb5d3c92f82fe9Josh Guilfoyle                    if (cursor != null && cursor.getCount() == 1) {
1436b51a98acbc710a4e1a1656d85bb5d3c92f82fe9Josh Guilfoyle                        cursor.moveToFirst();
1446b51a98acbc710a4e1a1656d85bb5d3c92f82fe9Josh Guilfoyle                        return cursor.getString(2);
1456b51a98acbc710a4e1a1656d85bb5d3c92f82fe9Josh Guilfoyle                    } else {
1466b51a98acbc710a4e1a1656d85bb5d3c92f82fe9Josh Guilfoyle                        title = uri.getLastPathSegment();
1476b51a98acbc710a4e1a1656d85bb5d3c92f82fe9Josh Guilfoyle                    }
1486b51a98acbc710a4e1a1656d85bb5d3c92f82fe9Josh Guilfoyle                } finally {
1496b51a98acbc710a4e1a1656d85bb5d3c92f82fe9Josh Guilfoyle                    if (cursor != null) {
1506b51a98acbc710a4e1a1656d85bb5d3c92f82fe9Josh Guilfoyle                        cursor.close();
1516b51a98acbc710a4e1a1656d85bb5d3c92f82fe9Josh Guilfoyle                    }
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (title == null) {
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            title = context.getString(com.android.internal.R.string.ringtone_unknown);
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (title == null) {
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                title = "";
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return title;
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
166098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey
167098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    /**
168098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey     * Set {@link Uri} to be used for ringtone playback. Attempts to open
169098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey     * locally, otherwise will delegate playback to remote
170098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey     * {@link IRingtonePlayer}.
171098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey     *
172098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey     * @hide
173098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey     */
174098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    public void setUri(Uri uri) {
175098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        destroyLocalPlayer();
176098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey
177098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        mUri = uri;
178098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        if (mUri == null) {
179098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            return;
180e1bd048cf2af24cbd93e549875c875239e5f4829Marco Nelissen        }
181098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey
182098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        // TODO: detect READ_EXTERNAL and specific content provider case, instead of relying on throwing
183098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey
184098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        // try opening uri locally before delegating to remote player
185098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        mLocalPlayer = new MediaPlayer();
186098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        try {
187098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            mLocalPlayer.setDataSource(mContext, mUri);
188098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            mLocalPlayer.setAudioStreamType(mStreamType);
189098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            mLocalPlayer.prepare();
190098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey
191098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        } catch (SecurityException e) {
192098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            destroyLocalPlayer();
193098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            if (!mAllowRemote) {
1941d8e5c588035550293ecd2558a2e285ee2789d38Jeff Sharkey                Log.w(TAG, "Remote playback not allowed: " + e);
195098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            }
196098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        } catch (IOException e) {
197098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            destroyLocalPlayer();
198098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            if (!mAllowRemote) {
1991d8e5c588035550293ecd2558a2e285ee2789d38Jeff Sharkey                Log.w(TAG, "Remote playback not allowed: " + e);
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
203098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        if (LOGD) {
204098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            if (mLocalPlayer != null) {
205098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey                Log.d(TAG, "Successfully created local player");
206098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            } else {
207098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey                Log.d(TAG, "Problem opening; delegating to remote player");
208098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            }
209098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        }
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
212098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    /** {@hide} */
213098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    public Uri getUri() {
214098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        return mUri;
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
216e47e8520fa48bd014287eda94ea39927de73d6bcDianne Hackborn
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Plays the ringtone.
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void play() {
221098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        if (mLocalPlayer != null) {
222098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            // do not play ringtones if stream volume is 0
223524dc046b1225087f481878a5c3ae7f733c9f0e2Eric Laurent            // (typically because ringer mode is silent).
224524dc046b1225087f481878a5c3ae7f733c9f0e2Eric Laurent            if (mAudioManager.getStreamVolume(mStreamType) != 0) {
225098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey                mLocalPlayer.start();
226098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            }
227098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        } else if (mAllowRemote) {
22865c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkey            final Uri canonicalUri = mUri.getCanonicalUri();
229098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            try {
23065c4a2b26cd8776b0927e9b0e07ecf53bd31b627Jeff Sharkey                mRemotePlayer.play(mRemoteToken, canonicalUri, mStreamType);
231098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            } catch (RemoteException e) {
232098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey                Log.w(TAG, "Problem playing ringtone: " + e);
233524dc046b1225087f481878a5c3ae7f733c9f0e2Eric Laurent            }
234098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        } else {
2351d8e5c588035550293ecd2558a2e285ee2789d38Jeff Sharkey            Log.w(TAG, "Neither local nor remote playback available");
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Stops a playing ringtone.
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void stop() {
243098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        if (mLocalPlayer != null) {
244098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            destroyLocalPlayer();
245098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        } else if (mAllowRemote) {
246098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            try {
247098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey                mRemotePlayer.stop(mRemoteToken);
248098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            } catch (RemoteException e) {
249098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey                Log.w(TAG, "Problem stopping ringtone: " + e);
250098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            }
251098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        }
252098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    }
253098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey
254098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey    private void destroyLocalPlayer() {
255098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        if (mLocalPlayer != null) {
256098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            mLocalPlayer.reset();
257098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            mLocalPlayer.release();
258098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            mLocalPlayer = null;
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Whether this ringtone is currently playing.
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return True if playing, false otherwise.
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isPlaying() {
268098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        if (mLocalPlayer != null) {
269098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            return mLocalPlayer.isPlaying();
270098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        } else if (mAllowRemote) {
271098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            try {
272098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey                return mRemotePlayer.isPlaying(mRemoteToken);
273098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            } catch (RemoteException e) {
274098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey                Log.w(TAG, "Problem checking ringtone: " + e);
275098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey                return false;
276098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey            }
277098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        } else {
2781d8e5c588035550293ecd2558a2e285ee2789d38Jeff Sharkey            Log.w(TAG, "Neither local nor remote playback available");
2791d8e5c588035550293ecd2558a2e285ee2789d38Jeff Sharkey            return false;
280098d580cc2bb6c0891c756a4e5230c6c6b0d2376Jeff Sharkey        }
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void setTitle(String title) {
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTitle = title;
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
287