Merge change Id301a47f into eclair
* changes:
Fix bug 2253204: MapView resources for hdpi devices.
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index e548524..df59dcf 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -683,22 +683,30 @@
{
LOGD("stopPreview (pid %d)", getCallingPid());
- Mutex::Autolock lock(mLock);
- if (checkPid() != NO_ERROR) return;
+ // hold main lock during state transition
+ {
+ Mutex::Autolock lock(mLock);
+ if (checkPid() != NO_ERROR) return;
- if (mHardware == 0) {
- LOGE("mHardware is NULL, returning.");
- return;
+ if (mHardware == 0) {
+ LOGE("mHardware is NULL, returning.");
+ return;
+ }
+
+ mHardware->stopPreview();
+ mHardware->disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
+ LOGD("stopPreview(), hardware stopped OK");
+
+ if (mSurface != 0 && !mUseOverlay) {
+ mSurface->unregisterBuffers();
+ }
}
- mHardware->stopPreview();
- mHardware->disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
- LOGD("stopPreview(), hardware stopped OK");
-
- if (mSurface != 0 && !mUseOverlay) {
- mSurface->unregisterBuffers();
+ // hold preview buffer lock
+ {
+ Mutex::Autolock lock(mPreviewLock);
+ mPreviewBuffer.clear();
}
- mPreviewBuffer.clear();
}
// stop recording mode
@@ -706,24 +714,31 @@
{
LOGD("stopRecording (pid %d)", getCallingPid());
- Mutex::Autolock lock(mLock);
- if (checkPid() != NO_ERROR) return;
+ // hold main lock during state transition
+ {
+ Mutex::Autolock lock(mLock);
+ if (checkPid() != NO_ERROR) return;
- if (mHardware == 0) {
- LOGE("mHardware is NULL, returning.");
- return;
+ if (mHardware == 0) {
+ LOGE("mHardware is NULL, returning.");
+ return;
+ }
+
+ if (mMediaPlayerBeep.get() != NULL) {
+ mMediaPlayerBeep->seekTo(0);
+ mMediaPlayerBeep->start();
+ }
+
+ mHardware->stopRecording();
+ mHardware->disableMsgType(CAMERA_MSG_VIDEO_FRAME);
+ LOGD("stopRecording(), hardware stopped OK");
}
- if (mMediaPlayerBeep.get() != NULL) {
- mMediaPlayerBeep->seekTo(0);
- mMediaPlayerBeep->start();
+ // hold preview buffer lock
+ {
+ Mutex::Autolock lock(mPreviewLock);
+ mPreviewBuffer.clear();
}
-
- mHardware->stopRecording();
- mHardware->disableMsgType(CAMERA_MSG_VIDEO_FRAME);
- LOGD("stopRecording(), hardware stopped OK");
-
- mPreviewBuffer.clear();
}
// release a recording frame
@@ -1216,10 +1231,10 @@
// provided it's big enough. Don't allocate the memory or
// perform the copy if there's no callback.
- // hold the lock while we grab a reference to the preview buffer
+ // hold the preview lock while we grab a reference to the preview buffer
sp<MemoryHeapBase> previewBuffer;
{
- Mutex::Autolock lock(mLock);
+ Mutex::Autolock lock(mPreviewLock);
if (mPreviewBuffer == 0) {
mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
} else if (size > mPreviewBuffer->virtualSize()) {
diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h
index 41c5d99..3e3e54f 100644
--- a/camera/libcameraservice/CameraService.h
+++ b/camera/libcameraservice/CameraService.h
@@ -181,7 +181,6 @@
mutable Condition mReady;
sp<CameraService> mCameraService;
sp<ISurface> mSurface;
- sp<MemoryHeapBase> mPreviewBuffer;
int mPreviewCallbackFlag;
sp<MediaPlayer> mMediaPlayerClick;
@@ -197,6 +196,9 @@
sp<OverlayRef> mOverlayRef;
int mOverlayW;
int mOverlayH;
+
+ mutable Mutex mPreviewLock;
+ sp<MemoryHeapBase> mPreviewBuffer;
};
// ----------------------------------------------------------------------------
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 9c0c850..ebd470f 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -815,6 +815,58 @@
mLock.unlock();
}
+status_t AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args)
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+
+ bool locked = tryLock(mLock);
+ if (!locked) {
+ snprintf(buffer, SIZE, "thread %p maybe dead locked\n", this);
+ write(fd, buffer, strlen(buffer));
+ }
+
+ snprintf(buffer, SIZE, "standby: %d\n", mStandby);
+ result.append(buffer);
+ snprintf(buffer, SIZE, "Sample rate: %d\n", mSampleRate);
+ result.append(buffer);
+ snprintf(buffer, SIZE, "Frame count: %d\n", mFrameCount);
+ result.append(buffer);
+ snprintf(buffer, SIZE, "Channel Count: %d\n", mChannelCount);
+ result.append(buffer);
+ snprintf(buffer, SIZE, "Format: %d\n", mFormat);
+ result.append(buffer);
+ snprintf(buffer, SIZE, "Frame size: %d\n", mFrameSize);
+ result.append(buffer);
+
+ snprintf(buffer, SIZE, "\nPending setParameters commands: \n");
+ result.append(buffer);
+ result.append(" Index Command");
+ for (size_t i = 0; i < mNewParameters.size(); ++i) {
+ snprintf(buffer, SIZE, "\n %02d ", i);
+ result.append(buffer);
+ result.append(mNewParameters[i]);
+ }
+
+ snprintf(buffer, SIZE, "\n\nPending config events: \n");
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Index event param\n");
+ result.append(buffer);
+ for (size_t i = 0; i < mConfigEvents.size(); i++) {
+ snprintf(buffer, SIZE, " %02d %02d %d\n", i, mConfigEvents[i]->mEvent, mConfigEvents[i]->mParam);
+ result.append(buffer);
+ }
+ result.append("\n");
+
+ write(fd, result.string(), result.size());
+
+ if (locked) {
+ mLock.unlock();
+ }
+ return NO_ERROR;
+}
+
// ----------------------------------------------------------------------------
@@ -856,7 +908,7 @@
snprintf(buffer, SIZE, "Output thread %p tracks\n", this);
result.append(buffer);
- result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
+ result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
for (size_t i = 0; i < mTracks.size(); ++i) {
sp<Track> track = mTracks[i];
if (track != 0) {
@@ -867,7 +919,7 @@
snprintf(buffer, SIZE, "Output thread %p active tracks\n", this);
result.append(buffer);
- result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
+ result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
for (size_t i = 0; i < mActiveTracks.size(); ++i) {
wp<Track> wTrack = mActiveTracks[i];
if (wTrack != 0) {
@@ -888,7 +940,7 @@
char buffer[SIZE];
String8 result;
- snprintf(buffer, SIZE, "Output thread %p internals\n", this);
+ snprintf(buffer, SIZE, "\nOutput thread %p internals\n", this);
result.append(buffer);
snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
result.append(buffer);
@@ -898,9 +950,10 @@
result.append(buffer);
snprintf(buffer, SIZE, "blocked in write: %d\n", mInWrite);
result.append(buffer);
- snprintf(buffer, SIZE, "standby: %d\n", mStandby);
- result.append(buffer);
write(fd, result.string(), result.size());
+
+ dumpBase(fd, args);
+
return NO_ERROR;
}
@@ -965,7 +1018,7 @@
Mutex::Autolock _l(mLock);
track = new Track(this, client, streamType, sampleRate, format,
channelCount, frameCount, sharedBuffer);
- if (track->getCblk() == NULL) {
+ if (track->getCblk() == NULL || track->name() < 0) {
lStatus = NO_MEMORY;
goto Exit;
}
@@ -1493,8 +1546,6 @@
AudioParameter param = AudioParameter(keyValuePair);
int value;
- mNewParameters.removeAt(0);
-
if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) {
reconfig = true;
}
@@ -1546,6 +1597,9 @@
sendConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED);
}
}
+
+ mNewParameters.removeAt(0);
+
mParamStatus = status;
mParamCond.signal();
mWaitWorkCV.wait(mLock);
@@ -1818,8 +1872,6 @@
AudioParameter param = AudioParameter(keyValuePair);
int value;
- mNewParameters.removeAt(0);
-
if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
// do not accept frame count changes if tracks are open as the track buffer
// size depends on frame count and correct behavior would not be garantied
@@ -1843,6 +1895,9 @@
sendConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED);
}
}
+
+ mNewParameters.removeAt(0);
+
mParamStatus = status;
mParamCond.signal();
mWaitWorkCV.wait(mLock);
@@ -2253,7 +2308,7 @@
void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size)
{
- snprintf(buffer, size, " %5d %5d %3u %3u %3u %3u %1d %1d %1d %5u %5u %5u %04x %04x\n",
+ snprintf(buffer, size, " %5d %5d %3u %3u %3u %04u %1d %1d %1d %5u %5u %5u %08x %08x\n",
mName - AudioMixer::TRACK0,
(mClient == NULL) ? getpid() : mClient->pid(),
mStreamType,
@@ -2509,6 +2564,19 @@
}
}
+void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size)
+{
+ snprintf(buffer, size, " %05d %03u %03u %04u %01d %05u %08x %08x\n",
+ (mClient == NULL) ? getpid() : mClient->pid(),
+ mFormat,
+ mCblk->channels,
+ mFrameCount,
+ mState,
+ mCblk->sampleRate,
+ mCblk->server,
+ mCblk->user);
+}
+
// ----------------------------------------------------------------------------
@@ -3136,13 +3204,34 @@
String8 result;
pid_t pid = 0;
- if (mActiveTrack != 0 && mActiveTrack->mClient != 0) {
- snprintf(buffer, SIZE, "Record client pid: %d\n", mActiveTrack->mClient->pid());
+ snprintf(buffer, SIZE, "\nInput thread %p internals\n", this);
+ result.append(buffer);
+
+ if (mActiveTrack != 0) {
+ result.append("Active Track:\n");
+ result.append(" Clien Fmt Chn Buf S SRate Serv User\n");
+ mActiveTrack->dump(buffer, SIZE);
result.append(buffer);
+
+ snprintf(buffer, SIZE, "In index: %d\n", mRsmpInIndex);
+ result.append(buffer);
+ snprintf(buffer, SIZE, "In size: %d\n", mInputBytes);
+ result.append(buffer);
+ snprintf(buffer, SIZE, "Resampling: %d\n", (mResampler != 0));
+ result.append(buffer);
+ snprintf(buffer, SIZE, "Out channel count: %d\n", mReqChannelCount);
+ result.append(buffer);
+ snprintf(buffer, SIZE, "Out sample rate: %d\n", mReqSampleRate);
+ result.append(buffer);
+
+
} else {
result.append("No record client\n");
}
write(fd, result.string(), result.size());
+
+ dumpBase(fd, args);
+
return NO_ERROR;
}
@@ -3198,8 +3287,6 @@
int reqSamplingRate = mReqSampleRate;
int reqChannelCount = mReqChannelCount;
- mNewParameters.removeAt(0);
-
if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) {
reqSamplingRate = value;
reconfig = true;
@@ -3241,6 +3328,9 @@
}
}
}
+
+ mNewParameters.removeAt(0);
+
mParamStatus = status;
mParamCond.signal();
mWaitWorkCV.wait(mLock);
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 56599f6..22d15c9 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -216,6 +216,8 @@
ThreadBase (const sp<AudioFlinger>& audioFlinger);
virtual ~ThreadBase();
+ status_t dumpBase(int fd, const Vector<String16>& args);
+
// base for record and playback
class TrackBase : public AudioBufferProvider, public RefBase {
@@ -678,6 +680,7 @@
bool overflow() { bool tmp = mOverflow; mOverflow = false; return tmp; }
bool setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; }
+ void dump(char* buffer, size_t size);
private:
friend class AudioFlinger;
friend class RecordThread;
diff --git a/libs/audioflinger/AudioPolicyService.cpp b/libs/audioflinger/AudioPolicyService.cpp
index 9723697..aa48019 100644
--- a/libs/audioflinger/AudioPolicyService.cpp
+++ b/libs/audioflinger/AudioPolicyService.cpp
@@ -592,6 +592,8 @@
if (mAudioCommands[0]->mTime <= curTime) {
AudioCommand *command = mAudioCommands[0];
mAudioCommands.removeAt(0);
+ mLastCommand = *command;
+
switch (command->mCommand) {
case START_TONE: {
mLock.unlock();
@@ -681,11 +683,15 @@
snprintf(buffer, SIZE, "- Commands:\n");
result = String8(buffer);
- result.append(" Command Time Status Wait pParam\n");
+ result.append(" Command Time Wait pParam\n");
for (int i = 0; i < (int)mAudioCommands.size(); i++) {
mAudioCommands[i]->dump(buffer, SIZE);
result.append(buffer);
}
+ result.append(" Last Command\n");
+ mLastCommand.dump(buffer, SIZE);
+ result.append(buffer);
+
write(fd, result.string(), result.size());
if (locked) mLock.unlock();
@@ -894,11 +900,10 @@
void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
{
- snprintf(buffer, size, " %02d %06d.%03d %03d %01u %p\n",
+ snprintf(buffer, size, " %02d %06d.%03d %01u %p\n",
mCommand,
(int)ns2s(mTime),
(int)ns2ms(mTime)%1000,
- mStatus,
mWaitStatus,
mParam);
}
diff --git a/libs/audioflinger/AudioPolicyService.h b/libs/audioflinger/AudioPolicyService.h
index 7c1bb85..b9234ec 100644
--- a/libs/audioflinger/AudioPolicyService.h
+++ b/libs/audioflinger/AudioPolicyService.h
@@ -152,7 +152,11 @@
private:
// descriptor for requested tone playback event
class AudioCommand {
+
public:
+ AudioCommand()
+ : mCommand(-1) {}
+
void dump(char* buffer, size_t size);
int mCommand; // START_TONE, STOP_TONE ...
@@ -191,6 +195,7 @@
Condition mWaitWorkCV;
Vector <AudioCommand *> mAudioCommands; // list of pending commands
ToneGenerator *mpToneGenerator; // the tone generator
+ AudioCommand mLastCommand;
};
// Internal dump utilities.
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index e04b2bf..b2a7db8 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -426,6 +426,21 @@
result = executeCommand(cmd);
}
+ // After executing the command, ensure that the thread is returned to the
+ // default cgroup and priority before rejoining the pool. This is a failsafe
+ // in case the command implementation failed to properly restore the thread's
+ // scheduling parameters upon completion.
+ int my_id;
+#ifdef HAVE_GETTID
+ my_id = gettid();
+#else
+ my_id = getpid();
+#endif
+ if (!set_sched_policy(my_id, SP_FOREGROUND)) {
+ // success; reset the priority as well
+ setpriority(PRIO_PROCESS, my_id, ANDROID_PRIORITY_NORMAL);
+ }
+
// Let this thread exit the thread pool if it is no longer
// needed and it is not the main process thread.
if(result == TIMED_OUT && !isMain) {
diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp
index 1bef859..a68750e 100644
--- a/opengl/libagl/copybit.cpp
+++ b/opengl/libagl/copybit.cpp
@@ -388,14 +388,33 @@
copybit_image_t tmpCbImg;
copybit_rect_t tmpCbRect;
+ copybit_rect_t tmpdrect = drect;
tmpCbImg.w = w;
tmpCbImg.h = h;
tmpCbImg.format = tempCb->format;
tmpCbImg.handle = (native_handle_t*)tempCb->getNativeBuffer()->handle;
tmpCbRect.l = 0;
tmpCbRect.t = 0;
- tmpCbRect.r = w;
- tmpCbRect.b = h;
+
+ if (drect.l < 0) {
+ tmpCbRect.l = -tmpdrect.l;
+ tmpdrect.l = 0;
+ }
+ if (drect.t < 0) {
+ tmpCbRect.t = -tmpdrect.t;
+ tmpdrect.t = 0;
+ }
+ if (drect.l + tmpCbImg.w > dst.w) {
+ tmpCbImg.w = dst.w - drect.l;
+ tmpdrect.r = dst.w;
+ }
+ if (drect.t + tmpCbImg.h > dst.h) {
+ tmpCbImg.h = dst.h - drect.t;
+ tmpdrect.b = dst.h;
+ }
+
+ tmpCbRect.r = tmpCbImg.w;
+ tmpCbRect.b = tmpCbImg.h;
if (!err) {
// first make a copy of the destination buffer
@@ -404,7 +423,7 @@
copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
err = copybit->stretch(copybit,
- &tmpCbImg, &dst, &tmpCbRect, &drect, &tmp_it);
+ &tmpCbImg, &dst, &tmpCbRect, &tmpdrect, &tmp_it);
}
if (!err) {
// then proceed as usual, but without the alpha plane
@@ -424,7 +443,7 @@
copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, invPlaneAlpha);
copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
err = copybit->stretch(copybit,
- &dst, &tmpCbImg, &drect, &tmpCbRect, &it);
+ &dst, &tmpCbImg, &tmpdrect, &tmpCbRect, &it);
}
} else {
copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform);