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