19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 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.Context;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.PowerManager;
228cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparksimport android.os.SystemClock;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
258cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparksimport java.util.LinkedList;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Plays a series of audio URIs, but does all the hard work on another thread
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * so that any slowness with preparing or loading doesn't block the calling thread.
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class AsyncPlayer {
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int PLAY = 1;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int STOP = 2;
348cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks    private static final boolean mDebug = false;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final class Command {
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int code;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Context context;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Uri uri;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean looping;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int stream;
428cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks        long requestTime;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String toString() {
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "{ code=" + code + " looping=" + looping + " stream=" + stream
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " uri=" + uri + " }";
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5030c918ce7fbe171944b28fc91b3f22b3d631872dGlenn Kasten    private final LinkedList<Command> mCmdQueue = new LinkedList();
518cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks
528cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks    private void startSound(Command cmd) {
538cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks        // Preparing can be slow, so if there is something else
548cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks        // is playing, let it continue until we're done, so there
558cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks        // is less of a glitch.
568cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks        try {
578cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks            if (mDebug) Log.d(mTag, "Starting playback");
588cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks            MediaPlayer player = new MediaPlayer();
598cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks            player.setAudioStreamType(cmd.stream);
608cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks            player.setDataSource(cmd.context, cmd.uri);
618cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks            player.setLooping(cmd.looping);
628cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks            player.prepare();
638cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks            player.start();
648cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks            if (mPlayer != null) {
658cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks                mPlayer.release();
668cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks            }
678cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks            mPlayer = player;
688cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks            long delay = SystemClock.uptimeMillis() - cmd.requestTime;
698cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks            if (delay > 1000) {
708cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks                Log.w(mTag, "Notification sound delayed by " + delay + "msecs");
718cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks            }
728cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks        }
734ba297f3ed2def2845edb18723e43379984bc9ffMarco Nelissen        catch (Exception e) {
748cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks            Log.w(mTag, "error loading sound for " + cmd.uri, e);
758cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks        }
768cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks    }
778cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final class Thread extends java.lang.Thread {
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Thread() {
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super("AsyncPlayer-" + mTag);
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void run() {
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (true) {
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Command cmd = null;
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
878cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks                synchronized (mCmdQueue) {
888cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks                    if (mDebug) Log.d(mTag, "RemoveFirst");
898cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks                    cmd = mCmdQueue.removeFirst();
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                switch (cmd.code) {
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case PLAY:
948cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks                    if (mDebug) Log.d(mTag, "PLAY");
958cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks                    startSound(cmd);
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case STOP:
988cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks                    if (mDebug) Log.d(mTag, "STOP");
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (mPlayer != null) {
1008cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks                        long delay = SystemClock.uptimeMillis() - cmd.requestTime;
1018cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks                        if (delay > 1000) {
1028cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks                            Log.w(mTag, "Notification stop delayed by " + delay + "msecs");
1038cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks                        }
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mPlayer.stop();
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mPlayer.release();
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mPlayer = null;
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        Log.w(mTag, "STOP command without a player");
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1138cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks                synchronized (mCmdQueue) {
1148cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks                    if (mCmdQueue.size() == 0) {
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // nothing left to do, quit
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // doing this check after we're done prevents the case where they
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // added it during the operation from spawning two threads and
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // trying to do them in parallel.
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mThread = null;
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        releaseWakeLock();
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return;
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mTag;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Thread mThread;
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private MediaPlayer mPlayer;
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private PowerManager.WakeLock mWakeLock;
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // The current state according to the caller.  Reality lags behind
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // because of the asynchronous nature of this class.
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mState = STOP;
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Construct an AsyncPlayer object.
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param tag a string to use for debugging
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AsyncPlayer(String tag) {
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (tag != null) {
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mTag = tag;
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mTag = "AsyncPlayer";
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Start playing the sound.  It will actually start playing at some
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * point in the future.  There are no guarantees about latency here.
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Calling this before another audio file is done playing will stop
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that one and start the new one.
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context Your application's context.
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param uri The URI to play.  (see {@link MediaPlayer#setDataSource(Context, Uri)})
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param looping Whether the audio should loop forever.
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *          (see {@link MediaPlayer#setLooping(boolean)})
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param stream the AudioStream to use.
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *          (see {@link MediaPlayer#setAudioStreamType(int)})
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void play(Context context, Uri uri, boolean looping, int stream) {
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Command cmd = new Command();
1658cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks        cmd.requestTime = SystemClock.uptimeMillis();
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cmd.code = PLAY;
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cmd.context = context;
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cmd.uri = uri;
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cmd.looping = looping;
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cmd.stream = stream;
1718cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks        synchronized (mCmdQueue) {
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            enqueueLocked(cmd);
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mState = PLAY;
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Stop a previously played sound.  It can't be played again or unpaused
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * at this point.  Calling this multiple times has no ill effects.
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void stop() {
1828cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks        synchronized (mCmdQueue) {
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // This check allows stop to be called multiple times without starting
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // a thread that ends up doing nothing.
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mState != STOP) {
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Command cmd = new Command();
1878cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks                cmd.requestTime = SystemClock.uptimeMillis();
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cmd.code = STOP;
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                enqueueLocked(cmd);
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mState = STOP;
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void enqueueLocked(Command cmd) {
1968cc42c5230eb02db8c28391dd15f83851df4f948Dave Sparks        mCmdQueue.add(cmd);
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mThread == null) {
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            acquireWakeLock();
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mThread = new Thread();
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mThread.start();
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * We want to hold a wake lock while we do the prepare and play.  The stop probably is
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * optional, but it won't hurt to have it too.  The problem is that if you start a sound
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * while you're holding a wake lock (e.g. an alarm starting a notification), you want the
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * sound to play, but if the CPU turns off before mThread gets to work, it won't.  The
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * simplest way to deal with this is to make it so there is a wake lock held while the
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * thread is starting or running.  You're going to need the WAKE_LOCK permission if you're
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * going to call this.
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This must be called before the first time play is called.
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setUsesWakeLock(Context context) {
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mWakeLock != null || mThread != null) {
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // if either of these has happened, we've already played something.
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // and our releases will be out of sync.
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException("assertion failed mWakeLock=" + mWakeLock
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " mThread=" + mThread);
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, mTag);
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void acquireWakeLock() {
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mWakeLock != null) {
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWakeLock.acquire();
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void releaseWakeLock() {
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mWakeLock != null) {
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWakeLock.release();
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
241