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