summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/jni/soundpool/SoundPool.cpp41
-rw-r--r--media/jni/soundpool/SoundPool.h4
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/Recents.java45
3 files changed, 74 insertions, 16 deletions
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index a705bcc..d4b54c3 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -187,6 +187,17 @@ bool SoundPool::startThreads()
return mDecodeThread != NULL;
}
+sp<Sample> SoundPool::findSample(int sampleID)
+{
+ Mutex::Autolock lock(&mLock);
+ return findSample_l(sampleID);
+}
+
+sp<Sample> SoundPool::findSample_l(int sampleID)
+{
+ return mSamples.valueFor(sampleID);
+}
+
SoundChannel* SoundPool::findChannel(int channelID)
{
for (int i = 0; i < mMaxChannels; ++i) {
@@ -211,18 +222,21 @@ int SoundPool::load(int fd, int64_t offset, int64_t length, int priority __unuse
{
ALOGV("load: fd=%d, offset=%" PRId64 ", length=%" PRId64 ", priority=%d",
fd, offset, length, priority);
- Mutex::Autolock lock(&mLock);
- sp<Sample> sample = new Sample(++mNextSampleID, fd, offset, length);
- mSamples.add(sample->sampleID(), sample);
- doLoad(sample);
- return sample->sampleID();
-}
-
-void SoundPool::doLoad(sp<Sample>& sample)
-{
- ALOGV("doLoad: loading sample sampleID=%d", sample->sampleID());
- sample->startLoad();
- mDecodeThread->loadSample(sample->sampleID());
+ int sampleID;
+ {
+ Mutex::Autolock lock(&mLock);
+ sampleID = ++mNextSampleID;
+ sp<Sample> sample = new Sample(sampleID, fd, offset, length);
+ mSamples.add(sampleID, sample);
+ sample->startLoad();
+ }
+ // mDecodeThread->loadSample() must be called outside of mLock.
+ // mDecodeThread->loadSample() may block on mDecodeThread message queue space;
+ // the message queue emptying may block on SoundPool::findSample().
+ //
+ // It theoretically possible that sample loads might decode out-of-order.
+ mDecodeThread->loadSample(sampleID);
+ return sampleID;
}
bool SoundPool::unload(int sampleID)
@@ -237,7 +251,6 @@ int SoundPool::play(int sampleID, float leftVolume, float rightVolume,
{
ALOGV("play sampleID=%d, leftVolume=%f, rightVolume=%f, priority=%d, loop=%d, rate=%f",
sampleID, leftVolume, rightVolume, priority, loop, rate);
- sp<Sample> sample;
SoundChannel* channel;
int channelID;
@@ -247,7 +260,7 @@ int SoundPool::play(int sampleID, float leftVolume, float rightVolume,
return 0;
}
// is sample ready?
- sample = findSample(sampleID);
+ sp<Sample> sample(findSample_l(sampleID));
if ((sample == 0) || (sample->state() != Sample::READY)) {
ALOGW(" sample %d not READY", sampleID);
return 0;
diff --git a/media/jni/soundpool/SoundPool.h b/media/jni/soundpool/SoundPool.h
index 4aacf53..98d2fa2 100644
--- a/media/jni/soundpool/SoundPool.h
+++ b/media/jni/soundpool/SoundPool.h
@@ -180,6 +180,7 @@ public:
// called from SoundPoolThread
void sampleLoaded(int sampleID);
+ sp<Sample> findSample(int sampleID);
// called from AudioTrack thread
void done_l(SoundChannel* channel);
@@ -191,8 +192,7 @@ public:
private:
SoundPool() {} // no default constructor
bool startThreads();
- void doLoad(sp<Sample>& sample);
- sp<Sample> findSample(int sampleID) { return mSamples.valueFor(sampleID); }
+ sp<Sample> findSample_l(int sampleID);
SoundChannel* findChannel (int channelID);
SoundChannel* findNextChannel (int channelID);
SoundChannel* allocateChannel_l(int priority, int sampleID);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index f1550a0..3917bab 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -34,6 +34,7 @@ import android.os.AsyncTask;
import android.os.Handler;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.provider.Settings;
import android.util.MutableBoolean;
import android.view.Display;
import android.view.LayoutInflater;
@@ -280,6 +281,12 @@ public class Recents extends SystemUI
@ProxyFromPrimaryToCurrentUser
@Override
public void showRecents(boolean triggeredFromAltTab, View statusBarView) {
+ // Ensure the device has been provisioned before allowing the user to interact with
+ // recents
+ if (!isDeviceProvisioned()) {
+ return;
+ }
+
if (mSystemServicesProxy.isForegroundUserOwner()) {
showRecentsInternal(triggeredFromAltTab);
} else {
@@ -304,6 +311,12 @@ public class Recents extends SystemUI
@ProxyFromPrimaryToCurrentUser
@Override
public void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
+ // Ensure the device has been provisioned before allowing the user to interact with
+ // recents
+ if (!isDeviceProvisioned()) {
+ return;
+ }
+
if (mSystemServicesProxy.isForegroundUserOwner()) {
hideRecentsInternal(triggeredFromAltTab, triggeredFromHomeKey);
} else {
@@ -330,6 +343,12 @@ public class Recents extends SystemUI
@ProxyFromPrimaryToCurrentUser
@Override
public void toggleRecents(Display display, int layoutDirection, View statusBarView) {
+ // Ensure the device has been provisioned before allowing the user to interact with
+ // recents
+ if (!isDeviceProvisioned()) {
+ return;
+ }
+
if (mSystemServicesProxy.isForegroundUserOwner()) {
toggleRecentsInternal();
} else {
@@ -353,6 +372,12 @@ public class Recents extends SystemUI
@ProxyFromPrimaryToCurrentUser
@Override
public void preloadRecents() {
+ // Ensure the device has been provisioned before allowing the user to interact with
+ // recents
+ if (!isDeviceProvisioned()) {
+ return;
+ }
+
if (mSystemServicesProxy.isForegroundUserOwner()) {
preloadRecentsInternal();
} else {
@@ -469,6 +494,12 @@ public class Recents extends SystemUI
@Override
public void showNextAffiliatedTask() {
+ // Ensure the device has been provisioned before allowing the user to interact with
+ // recents
+ if (!isDeviceProvisioned()) {
+ return;
+ }
+
// Keep track of when the affiliated task is triggered
MetricsLogger.count(mContext, "overview_affiliated_task_next", 1);
showRelativeAffiliatedTask(true);
@@ -476,6 +507,12 @@ public class Recents extends SystemUI
@Override
public void showPrevAffiliatedTask() {
+ // Ensure the device has been provisioned before allowing the user to interact with
+ // recents
+ if (!isDeviceProvisioned()) {
+ return;
+ }
+
// Keep track of when the affiliated task is triggered
MetricsLogger.count(mContext, "overview_affiliated_task_prev", 1);
showRelativeAffiliatedTask(false);
@@ -888,6 +925,14 @@ public class Recents extends SystemUI
}
/**
+ * @return whether this device is provisioned.
+ */
+ private boolean isDeviceProvisioned() {
+ return Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+ }
+
+ /**
* Returns the preloaded load plan and invalidates it.
*/
public static RecentsTaskLoadPlan consumeInstanceLoadPlan() {