Merge "Fix ordering assumption of argument evaluation."
diff --git a/camera/Camera.cpp b/camera/Camera.cpp
index 3c00db5..7ac3cc1 100644
--- a/camera/Camera.cpp
+++ b/camera/Camera.cpp
@@ -360,7 +360,8 @@
 }
 
 // callback from camera service when frame or image is ready
-void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
+void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
+                          camera_frame_metadata_t *metadata)
 {
     sp<CameraListener> listener;
     {
@@ -368,7 +369,7 @@
         listener = mListener;
     }
     if (listener != NULL) {
-        listener->postData(msgType, dataPtr);
+        listener->postData(msgType, dataPtr, metadata);
     }
 }
 
diff --git a/camera/CameraParameters.cpp b/camera/CameraParameters.cpp
index 9392cf2..251615d 100644
--- a/camera/CameraParameters.cpp
+++ b/camera/CameraParameters.cpp
@@ -84,6 +84,9 @@
 const char CameraParameters::KEY_VIDEO_SIZE[] = "video-size";
 const char CameraParameters::KEY_SUPPORTED_VIDEO_SIZES[] = "video-size-values";
 const char CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[] = "preferred-preview-size-for-video";
+const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW[] = "max-num-detected-faces-hw";
+const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW[] = "max-num-detected-faces-sw";
+const char CameraParameters::KEY_RECORDING_HINT[] = "recording-hint";
 
 const char CameraParameters::TRUE[] = "true";
 const char CameraParameters::FALSE[] = "false";
diff --git a/camera/ICameraClient.cpp b/camera/ICameraClient.cpp
index cb3bd0c..183429a 100644
--- a/camera/ICameraClient.cpp
+++ b/camera/ICameraClient.cpp
@@ -51,13 +51,18 @@
     }
 
     // generic data callback from camera service to app with image data
-    void dataCallback(int32_t msgType, const sp<IMemory>& imageData)
+    void dataCallback(int32_t msgType, const sp<IMemory>& imageData,
+                      camera_frame_metadata_t *metadata)
     {
         LOGV("dataCallback");
         Parcel data, reply;
         data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
         data.writeInt32(msgType);
         data.writeStrongBinder(imageData->asBinder());
+        if (metadata) {
+            data.writeInt32(metadata->number_of_faces);
+            data.write(metadata->faces, sizeof(camera_face_t) * metadata->number_of_faces);
+        }
         remote()->transact(DATA_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
     }
 
@@ -96,7 +101,15 @@
             CHECK_INTERFACE(ICameraClient, data, reply);
             int32_t msgType = data.readInt32();
             sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder());
-            dataCallback(msgType, imageData);
+            camera_frame_metadata_t *metadata = NULL;
+            if (data.dataAvail() > 0) {
+                metadata = new camera_frame_metadata_t;
+                metadata->number_of_faces = data.readInt32();
+                metadata->faces = (camera_face_t *) data.readInplace(
+                        sizeof(camera_face_t) * metadata->number_of_faces);
+            }
+            dataCallback(msgType, imageData, metadata);
+            if (metadata) delete metadata;
             return NO_ERROR;
         } break;
         case DATA_CALLBACK_TIMESTAMP: {
diff --git a/include/camera/Camera.h b/include/camera/Camera.h
index f701280..234e165 100644
--- a/include/camera/Camera.h
+++ b/include/camera/Camera.h
@@ -59,7 +59,8 @@
 {
 public:
     virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
-    virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr) = 0;
+    virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr,
+                          camera_frame_metadata_t *metadata) = 0;
     virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) = 0;
 };
 
@@ -138,7 +139,8 @@
 
     // ICameraClient interface
     virtual void        notifyCallback(int32_t msgType, int32_t ext, int32_t ext2);
-    virtual void        dataCallback(int32_t msgType, const sp<IMemory>& dataPtr);
+    virtual void        dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
+                                     camera_frame_metadata_t *metadata);
     virtual void        dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
 
     sp<ICamera>         remote();
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index 83d4f6d..48483fd 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -455,6 +455,16 @@
     // Example: "176x144,1280x720". Read only.
     static const char KEY_SUPPORTED_VIDEO_SIZES[];
 
+    // The maximum number of detected faces supported by hardware face
+    // detection. If the value is 0, hardware face detection is not supported.
+    // Example: "5". Read only
+    static const char KEY_MAX_NUM_DETECTED_FACES_HW[];
+
+    // The maximum number of detected faces supported by software face
+    // detection. If the value is 0, software face detection is not supported.
+    // Example: "5". Read only
+    static const char KEY_MAX_NUM_DETECTED_FACES_SW[];
+
     // Preferred preview frame size in pixels for video recording.
     // The width and height must be one of the supported sizes retrieved
     // via KEY_SUPPORTED_PREVIEW_SIZES. This key can be used only when
@@ -474,6 +484,17 @@
     // Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read only.
     static const char KEY_VIDEO_FRAME_FORMAT[];
 
+    // Sets the hint of the recording mode. If this is true, MediaRecorder.start
+    // may be faster or has less glitches. This should be called before starting
+    // the preview for the best result. But it is allowed to change the hint
+    // while the preview is active. The default value is false.
+    //
+    // The apps can still call Camera.takePicture when the hint is true. The
+    // apps can call MediaRecorder.start when the hint is false. But the
+    // performance may be worse.
+    // Example value: "true" or "false". Read/write.
+    static const char KEY_RECORDING_HINT[];
+
     // Value for KEY_ZOOM_SUPPORTED or KEY_SMOOTH_ZOOM_SUPPORTED.
     static const char TRUE[];
     static const char FALSE[];
diff --git a/include/camera/ICameraClient.h b/include/camera/ICameraClient.h
index 236d0f6..b30aa7a 100644
--- a/include/camera/ICameraClient.h
+++ b/include/camera/ICameraClient.h
@@ -22,6 +22,7 @@
 #include <binder/Parcel.h>
 #include <binder/IMemory.h>
 #include <utils/Timers.h>
+#include <system/camera.h>
 
 namespace android {
 
@@ -31,7 +32,8 @@
     DECLARE_META_INTERFACE(CameraClient);
 
     virtual void            notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
-    virtual void            dataCallback(int32_t msgType, const sp<IMemory>& data) = 0;
+    virtual void            dataCallback(int32_t msgType, const sp<IMemory>& data,
+                                         camera_frame_metadata_t *metadata) = 0;
     virtual void            dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& data) = 0;
 };
 
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index 1136f6c..1a67671 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -130,13 +130,22 @@
     MEDIA_PLAYER_PLAYBACK_COMPLETE  = 1 << 7
 };
 
-enum media_set_parameter_keys {
-    KEY_PARAMETER_TIMED_TEXT_TRACK_INDEX = 1000,
-    KEY_PARAMETER_TIMED_TEXT_ADD_OUT_OF_BAND_SOURCE = 1001,
+// Keep KEY_PARAMETER_* in sync with MediaPlayer.java.
+// The same enum space is used for both set and get, in case there are future keys that
+// can be both set and get.  But as of now, all parameters are either set only or get only.
+enum media_parameter_keys {
+    KEY_PARAMETER_TIMED_TEXT_TRACK_INDEX = 1000,                // set only
+    KEY_PARAMETER_TIMED_TEXT_ADD_OUT_OF_BAND_SOURCE = 1001,     // set only
 
     // Streaming/buffering parameters
-    KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS = 1100,
+    KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS = 1100,            // set only
+
+    // Return a Parcel containing a single int, which is the channel count of the
+    // audio track, or zero for error (e.g. no audio track) or unknown.
+    KEY_PARAMETER_AUDIO_CHANNEL_COUNT = 1200,                   // get only
+
 };
+
 // ----------------------------------------------------------------------------
 // ref-counted object for callbacks
 class MediaPlayerListener: virtual public RefBase
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 1ec596e..16554c2 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -590,7 +590,7 @@
 audio_io_handle_t AudioRecord::getInput()
 {
     AutoMutex lock(mLock);
-    return getInput_l();
+    return mInput;
 }
 
 // must be called with mLock held
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index a11fb80..3dd9249 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -201,11 +201,11 @@
 
 void MediaPlayer::disconnectNativeWindow() {
     if (mConnectedWindow != NULL) {
-        status_t err = native_window_disconnect(mConnectedWindow.get(),
+        status_t err = native_window_api_disconnect(mConnectedWindow.get(),
                 NATIVE_WINDOW_API_MEDIA);
 
         if (err != OK) {
-            LOGW("native_window_disconnect returned an error: %s (%d)",
+            LOGW("native_window_api_disconnect returned an error: %s (%d)",
                     strerror(-err), err);
         }
     }
@@ -224,7 +224,7 @@
     }
 
     if (surface != NULL) {
-        status_t err = native_window_connect(surface.get(),
+        status_t err = native_window_api_connect(surface.get(),
                 NATIVE_WINDOW_API_MEDIA);
 
         if (err != OK) {
@@ -274,7 +274,7 @@
     sp<ANativeWindow> anw;
     if (surfaceTexture != NULL) {
         anw = new SurfaceTextureClient(surfaceTexture);
-        status_t err = native_window_connect(anw.get(),
+        status_t err = native_window_api_connect(anw.get(),
                 NATIVE_WINDOW_API_MEDIA);
 
         if (err != OK) {
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 3a3c082..3f4dace 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -132,10 +132,9 @@
 
 LOCAL_STATIC_LIBRARIES += \
         libstagefright_chromium_http \
-        libchromium_net         \
         libwebcore              \
 
-LOCAL_SHARED_LIBRARIES += libstlport
+LOCAL_SHARED_LIBRARIES += libstlport libchromium_net
 include external/stlport/libstlport.mk
 
 LOCAL_CPPFLAGS += -DCHROMIUM_AVAILABLE=1
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 0098537..67f6c79 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -2238,7 +2238,22 @@
 }
 
 status_t AwesomePlayer::getParameter(int key, Parcel *reply) {
-    return OK;
+    switch (key) {
+    case KEY_PARAMETER_AUDIO_CHANNEL_COUNT:
+        {
+            int32_t channelCount;
+            if (mAudioTrack == 0 ||
+                    !mAudioTrack->getFormat()->findInt32(kKeyChannelCount, &channelCount)) {
+                channelCount = 0;
+            }
+            reply->writeInt32(channelCount);
+        }
+        return OK;
+    default:
+        {
+            return ERROR_UNSUPPORTED;
+        }
+    }
 }
 
 bool AwesomePlayer::isStreamingHTTP() const {
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index de66d99..ea8eaa4 100755
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -37,7 +37,8 @@
     CameraSourceListener(const sp<CameraSource> &source);
 
     virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2);
-    virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr);
+    virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr,
+                          camera_frame_metadata_t *metadata);
 
     virtual void postDataTimestamp(
             nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
@@ -63,7 +64,8 @@
     LOGV("notify(%d, %d, %d)", msgType, ext1, ext2);
 }
 
-void CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr) {
+void CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr,
+                                    camera_frame_metadata_t *metadata) {
     LOGV("postData(%d, ptr:%p, size:%d)",
          msgType, dataPtr->pointer(), dataPtr->size());
 
diff --git a/media/libstagefright/avc_utils.cpp b/media/libstagefright/avc_utils.cpp
index 020e947..8a42e8b 100644
--- a/media/libstagefright/avc_utils.cpp
+++ b/media/libstagefright/avc_utils.cpp
@@ -188,7 +188,7 @@
     }
 
     size_t endOffset = offset - 2;
-    while (data[endOffset - 1] == 0x00) {
+    while (endOffset > startOffset + 1 && data[endOffset - 1] == 0x00) {
         --endOffset;
     }
 
diff --git a/media/libstagefright/chromium_http/support.cpp b/media/libstagefright/chromium_http/support.cpp
index f4b3668..eb10ab7 100644
--- a/media/libstagefright/chromium_http/support.cpp
+++ b/media/libstagefright/chromium_http/support.cpp
@@ -25,6 +25,7 @@
 #include "android/net/android_network_library_impl.h"
 #include "base/threading/thread.h"
 #include "net/base/cert_verifier.h"
+#include "net/base/cookie_monster.h"
 #include "net/base/host_resolver.h"
 #include "net/base/ssl_config_service.h"
 #include "net/http/http_auth_handler_factory.h"
@@ -140,6 +141,8 @@
             network_delegate(),
             net_log(),
             NULL));  // backend_factory
+
+    set_cookie_store(new net::CookieMonster(NULL, NULL));
 }
 
 const std::string &SfRequestContext::GetUserAgent(const GURL &url) const {
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 90d64ba..2578d2d 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -544,6 +544,7 @@
         firstSeqNumberInPlaylist = 0;
     }
 
+    bool seekDiscontinuity = false;
     bool explicitDiscontinuity = false;
     bool bandwidthChanged = false;
 
@@ -580,10 +581,10 @@
                     // reseting the data source will have had the
                     // side effect of discarding any previously queued
                     // bandwidth change discontinuity.
-                    // Therefore we'll need to treat these explicit
+                    // Therefore we'll need to treat these seek
                     // discontinuities as involving a bandwidth change
                     // even if they aren't directly.
-                    explicitDiscontinuity = true;
+                    seekDiscontinuity = true;
                     bandwidthChanged = true;
                 }
             }
@@ -597,11 +598,7 @@
     }
 
     if (mSeqNumber < 0) {
-        if (mPlaylist->isComplete()) {
-            mSeqNumber = firstSeqNumberInPlaylist;
-        } else {
-            mSeqNumber = firstSeqNumberInPlaylist + mPlaylist->size() / 2;
-        }
+        mSeqNumber = firstSeqNumberInPlaylist;
     }
 
     int32_t lastSeqNumberInPlaylist =
@@ -704,15 +701,17 @@
         bandwidthChanged = false;
     }
 
-    if (explicitDiscontinuity || bandwidthChanged) {
+    if (seekDiscontinuity || explicitDiscontinuity || bandwidthChanged) {
         // Signal discontinuity.
 
-        LOGI("queueing discontinuity (explicit=%d, bandwidthChanged=%d)",
-             explicitDiscontinuity, bandwidthChanged);
+        LOGI("queueing discontinuity (seek=%d, explicit=%d, bandwidthChanged=%d)",
+             seekDiscontinuity, explicitDiscontinuity, bandwidthChanged);
 
         sp<ABuffer> tmp = new ABuffer(188);
         memset(tmp->data(), 0, tmp->size());
-        tmp->data()[1] = bandwidthChanged;
+
+        // signal a 'hard' discontinuity for explicit or bandwidthChanged.
+        tmp->data()[1] = (explicitDiscontinuity || bandwidthChanged) ? 1 : 0;
 
         mDataSource->queueBuffer(tmp);
     }
diff --git a/media/libstagefright/omx/OMXMaster.cpp b/media/libstagefright/omx/OMXMaster.cpp
index 504d470..c8278ab 100644
--- a/media/libstagefright/omx/OMXMaster.cpp
+++ b/media/libstagefright/omx/OMXMaster.cpp
@@ -57,6 +57,9 @@
     typedef OMXPluginBase *(*CreateOMXPluginFunc)();
     CreateOMXPluginFunc createOMXPlugin =
         (CreateOMXPluginFunc)dlsym(
+                mVendorLibHandle, "createOMXPlugin");
+    if (!createOMXPlugin)
+        createOMXPlugin = (CreateOMXPluginFunc)dlsym(
                 mVendorLibHandle, "_ZN7android15createOMXPluginEv");
 
     if (createOMXPlugin) {
@@ -96,11 +99,19 @@
 void OMXMaster::clearPlugins() {
     Mutex::Autolock autoLock(mLock);
 
+    typedef void (*DestroyOMXPluginFunc)(OMXPluginBase*);
+    DestroyOMXPluginFunc destroyOMXPlugin =
+        (DestroyOMXPluginFunc)dlsym(
+                mVendorLibHandle, "destroyOMXPlugin");
+
     mPluginByComponentName.clear();
 
     for (List<OMXPluginBase *>::iterator it = mPlugins.begin();
-         it != mPlugins.end(); ++it) {
-        delete *it;
+            it != mPlugins.end(); ++it) {
+        if (destroyOMXPlugin)
+            destroyOMXPlugin(*it);
+        else
+            delete *it;
         *it = NULL;
     }
 
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index a0407b9..fa49592 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -21,7 +21,8 @@
     libhardware \
     libhardware_legacy \
     libeffects \
-    libdl
+    libdl \
+    libpowermanager
 
 LOCAL_STATIC_LIBRARIES := \
     libcpustats \
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index cb1f921..ec45530 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -53,6 +53,7 @@
 #include <audio_effects/effect_visualizer.h>
 
 #include <cpustats/ThreadCpuUsage.h>
+#include <powermanager/PowerManager.h>
 // #define DEBUG_CPU_USAGE 10  // log statistics every n wall clock seconds
 
 // ----------------------------------------------------------------------------
@@ -887,14 +888,18 @@
 AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id, uint32_t device)
     :   Thread(false),
         mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mChannelCount(0),
-        mFrameSize(1), mFormat(0), mStandby(false), mId(id), mExiting(false), mDevice(device)
+        mFrameSize(1), mFormat(0), mStandby(false), mId(id), mExiting(false),
+        mDevice(device)
 {
+    mDeathRecipient = new PMDeathRecipient(this);
 }
 
 AudioFlinger::ThreadBase::~ThreadBase()
 {
     mParamCond.broadcast();
     mNewParameters.clear();
+    // do not lock the mutex in destructor
+    releaseWakeLock_l();
 }
 
 void AudioFlinger::ThreadBase::exit()
@@ -1061,6 +1066,69 @@
     return NO_ERROR;
 }
 
+void AudioFlinger::ThreadBase::acquireWakeLock()
+{
+    Mutex::Autolock _l(mLock);
+    acquireWakeLock_l();
+}
+
+void AudioFlinger::ThreadBase::acquireWakeLock_l()
+{
+    if (mPowerManager == 0) {
+        // use checkService() to avoid blocking if power service is not up yet
+        sp<IBinder> binder =
+            defaultServiceManager()->checkService(String16("power"));
+        if (binder == 0) {
+            LOGW("Thread %s cannot connect to the power manager service", mName);
+        } else {
+            mPowerManager = interface_cast<IPowerManager>(binder);
+            binder->linkToDeath(mDeathRecipient);
+        }
+    }
+    if (mPowerManager != 0) {
+        sp<IBinder> binder = new BBinder();
+        status_t status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK,
+                                                         binder,
+                                                         String16(mName));
+        if (status == NO_ERROR) {
+            mWakeLockToken = binder;
+        }
+        LOGV("acquireWakeLock_l() %s status %d", mName, status);
+    }
+}
+
+void AudioFlinger::ThreadBase::releaseWakeLock()
+{
+    Mutex::Autolock _l(mLock);
+    releaseWakeLock_l();
+}
+
+void AudioFlinger::ThreadBase::releaseWakeLock_l()
+{
+    if (mWakeLockToken != 0) {
+        LOGV("releaseWakeLock_l() %s", mName);
+        if (mPowerManager != 0) {
+            mPowerManager->releaseWakeLock(mWakeLockToken, 0);
+        }
+        mWakeLockToken.clear();
+    }
+}
+
+void AudioFlinger::ThreadBase::clearPowerManager()
+{
+    Mutex::Autolock _l(mLock);
+    releaseWakeLock_l();
+    mPowerManager.clear();
+}
+
+void AudioFlinger::ThreadBase::PMDeathRecipient::binderDied(const wp<IBinder>& who)
+{
+    sp<ThreadBase> thread = mThread.promote();
+    if (thread != 0) {
+        thread->clearPowerManager();
+    }
+    LOGW("power manager service died !!!");
+}
 
 // ----------------------------------------------------------------------------
 
@@ -1072,6 +1140,8 @@
         mMixBuffer(0), mSuspended(0), mBytesWritten(0), mOutput(output),
         mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false)
 {
+    snprintf(mName, kNameLength, "AudioOut_%d", id);
+
     readOutputParameters();
 
     mMasterVolume = mAudioFlinger->masterVolume();
@@ -1170,12 +1240,7 @@
 
 void AudioFlinger::PlaybackThread::onFirstRef()
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "Playback Thread %p", this);
-
-    run(buffer, ANDROID_PRIORITY_URGENT_AUDIO);
+    run(mName, ANDROID_PRIORITY_URGENT_AUDIO);
 }
 
 // PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held
@@ -1522,6 +1587,8 @@
     const CentralTendencyStatistics& stats = cpu.statistics();
 #endif
 
+    acquireWakeLock();
+
     while (!exitPending())
     {
 #ifdef DEBUG_CPU_USAGE
@@ -1585,10 +1652,12 @@
 
                     if (exitPending()) break;
 
+                    releaseWakeLock_l();
                     // wait until we have something to do...
                     LOGV("MixerThread %p TID %d going to sleep\n", this, gettid());
                     mWaitWorkCV.wait(mLock);
                     LOGV("MixerThread %p TID %d waking up\n", this, gettid());
+                    acquireWakeLock_l();
 
                     if (mMasterMute == false) {
                         char value[PROPERTY_VALUE_MAX];
@@ -1689,6 +1758,8 @@
         mOutput->stream->common.standby(&mOutput->stream->common);
     }
 
+    releaseWakeLock();
+
     LOGV("MixerThread %p exiting", this);
     return false;
 }
@@ -2176,6 +2247,8 @@
     // hardware resources as soon as possible
     nsecs_t standbyDelay = microseconds(activeSleepTime*2);
 
+    acquireWakeLock();
+
     while (!exitPending())
     {
         bool rampVolume;
@@ -2215,9 +2288,11 @@
 
                     if (exitPending()) break;
 
+                    releaseWakeLock_l();
                     LOGV("DirectOutputThread %p TID %d going to sleep\n", this, gettid());
                     mWaitWorkCV.wait(mLock);
                     LOGV("DirectOutputThread %p TID %d waking up in active mode\n", this, gettid());
+                    acquireWakeLock_l();
 
                     if (mMasterMute == false) {
                         char value[PROPERTY_VALUE_MAX];
@@ -2436,6 +2511,8 @@
         mOutput->stream->common.standby(&mOutput->stream->common);
     }
 
+    releaseWakeLock();
+
     LOGV("DirectOutputThread %p exiting", this);
     return false;
 }
@@ -2561,6 +2638,8 @@
     uint32_t sleepTime = idleSleepTime;
     Vector< sp<EffectChain> > effectChains;
 
+    acquireWakeLock();
+
     while (!exitPending())
     {
         processConfigEvents();
@@ -2601,9 +2680,12 @@
 
                     if (exitPending()) break;
 
+                    releaseWakeLock_l();
                     LOGV("DuplicatingThread %p TID %d going to sleep\n", this, gettid());
                     mWaitWorkCV.wait(mLock);
                     LOGV("DuplicatingThread %p TID %d waking up\n", this, gettid());
+                    acquireWakeLock_l();
+
                     if (mMasterMute == false) {
                         char value[PROPERTY_VALUE_MAX];
                         property_get("ro.audio.silent", value, "0");
@@ -2690,6 +2772,8 @@
         effectChains.clear();
     }
 
+    releaseWakeLock();
+
     return false;
 }
 
@@ -3814,6 +3898,9 @@
     mInput(input), mTrack(NULL), mResampler(0), mRsmpOutBuffer(0), mRsmpInBuffer(0)
 {
     mType = ThreadBase::RECORD;
+
+    snprintf(mName, kNameLength, "AudioIn_%d", id);
+
     mReqChannelCount = popcount(channels);
     mReqSampleRate = sampleRate;
     readInputParameters();
@@ -3831,12 +3918,7 @@
 
 void AudioFlinger::RecordThread::onFirstRef()
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "Record Thread %p", this);
-
-    run(buffer, PRIORITY_URGENT_AUDIO);
+    run(mName, PRIORITY_URGENT_AUDIO);
 }
 
 bool AudioFlinger::RecordThread::threadLoop()
@@ -3847,6 +3929,8 @@
 
     nsecs_t lastWarning = 0;
 
+    acquireWakeLock();
+
     // start recording
     while (!exitPending()) {
 
@@ -3863,10 +3947,12 @@
 
                 if (exitPending()) break;
 
+                releaseWakeLock_l();
                 LOGV("RecordThread: loop stopping");
                 // go to sleep
                 mWaitWorkCV.wait(mLock);
                 LOGV("RecordThread: loop starting");
+                acquireWakeLock_l();
                 continue;
             }
             if (mActiveTrack != 0) {
@@ -3907,8 +3993,6 @@
             for (size_t i = 0; i < effectChains.size(); i ++) {
                 effectChains[i]->process_l();
             }
-            // enable changes in effect chain
-            unlockEffectChains(effectChains);
 
             buffer.frameCount = mFrameCount;
             if (LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) {
@@ -4008,9 +4092,9 @@
                 // clear the overflow.
                 usleep(kRecordThreadSleepUs);
             }
-        } else {
-            unlockEffectChains(effectChains);
         }
+        // enable changes in effect chain
+        unlockEffectChains(effectChains);
         effectChains.clear();
     }
 
@@ -4021,6 +4105,8 @@
 
     mStartStopCond.broadcast();
 
+    releaseWakeLock();
+
     LOGV("RecordThread %p exiting", this);
     return false;
 }
@@ -5581,13 +5667,11 @@
         }
     }
 
-    // Release effect engine here so that it is done immediately. Otherwise it will be released
-    // by the destructor when the last strong reference on the this object is released which can
-    // happen after next process is called on this effect.
-    if (size == 0 && mEffectInterface != NULL) {
-        // release effect engine
-        EffectRelease(mEffectInterface);
-        mEffectInterface = NULL;
+    // Prevent calls to process() and other functions on effect interface from now on.
+    // The effect engine will be released by the destructor when the last strong reference on
+    // this object is released which can happen after next process is called.
+    if (size == 0) {
+        mState = DESTROYED;
     }
 
     return size;
@@ -5637,7 +5721,7 @@
             mState = IDLE;
         }
         break;
-    default: //IDLE , ACTIVE
+    default: //IDLE , ACTIVE, DESTROYED
         break;
     }
 }
@@ -5646,7 +5730,7 @@
 {
     Mutex::Autolock _l(mLock);
 
-    if (mEffectInterface == NULL ||
+    if (mState == DESTROYED || mEffectInterface == NULL ||
             mConfig.inputCfg.buffer.raw == NULL ||
             mConfig.outputCfg.buffer.raw == NULL) {
         return;
@@ -5822,6 +5906,12 @@
     return status;
 }
 
+status_t AudioFlinger::EffectModule::stop()
+{
+    Mutex::Autolock _l(mLock);
+    return stop_l();
+}
+
 status_t AudioFlinger::EffectModule::stop_l()
 {
     if (mEffectInterface == NULL) {
@@ -5858,7 +5948,7 @@
     Mutex::Autolock _l(mLock);
 //    LOGV("command(), cmdCode: %d, mEffectInterface: %p", cmdCode, mEffectInterface);
 
-    if (mEffectInterface == NULL) {
+    if (mState == DESTROYED || mEffectInterface == NULL) {
         return NO_INIT;
     }
     status_t status = (*mEffectInterface)->command(mEffectInterface,
@@ -5907,6 +5997,8 @@
         case ACTIVE:
             mState = STOPPING;
             break;
+        case DESTROYED:
+            return NO_ERROR; // simply ignore as we are being destroyed
         }
         for (size_t i = 1; i < mHandles.size(); i++) {
             sp<EffectHandle> h = mHandles[i].promote();
@@ -5928,6 +6020,7 @@
     case IDLE:
     case STOPPING:
     case STOPPED:
+    case DESTROYED:
     default:
         return false;
     }
@@ -5943,6 +6036,7 @@
         return true;
     case IDLE:
     case STARTING:
+    case DESTROYED:
     default:
         return false;
     }
@@ -6544,6 +6638,10 @@
 
     for (i = 0; i < size; i++) {
         if (effect == mEffects[i]) {
+            // calling stop here will remove pre-processing effect from the audio HAL.
+            // This is safe as we hold the EffectChain mutex which guarantees that we are not in
+            // the middle of a read from audio HAL
+            mEffects[i]->stop();
             if (type == EFFECT_FLAG_TYPE_AUXILIARY) {
                 delete[] effect->inBuffer();
             } else {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index e2cf946..7b6215f 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -43,6 +43,8 @@
 
 #include "AudioBufferProvider.h"
 
+#include <powermanager/IPowerManager.h>
+
 namespace android {
 
 class audio_track_cblk_t;
@@ -287,6 +289,8 @@
         status_t dumpBase(int fd, const Vector<String16>& args);
         status_t dumpEffectChains(int fd, const Vector<String16>& args);
 
+        void clearPowerManager();
+
         // base for record and playback
         class TrackBase : public AudioBufferProvider, public RefBase {
 
@@ -386,6 +390,21 @@
             int mParam;
         };
 
+        class PMDeathRecipient : public IBinder::DeathRecipient {
+        public:
+                        PMDeathRecipient(const wp<ThreadBase>& thread) : mThread(thread) {}
+            virtual     ~PMDeathRecipient() {}
+
+            // IBinder::DeathRecipient
+            virtual     void        binderDied(const wp<IBinder>& who);
+
+        private:
+                        PMDeathRecipient(const PMDeathRecipient&);
+                        PMDeathRecipient& operator = (const PMDeathRecipient&);
+
+            wp<ThreadBase> mThread;
+        };
+
         virtual     status_t    initCheck() const = 0;
                     int         type() const { return mType; }
                     uint32_t    sampleRate() const;
@@ -462,6 +481,11 @@
 
     protected:
 
+                    void        acquireWakeLock();
+                    void        acquireWakeLock_l();
+                    void        releaseWakeLock();
+                    void        releaseWakeLock_l();
+
         friend class Track;
         friend class TrackBase;
         friend class PlaybackThread;
@@ -490,6 +514,11 @@
                     Vector< sp<EffectChain> > mEffectChains;
                     uint32_t                mDevice;    // output device for PlaybackThread
                                                         // input + output devices for RecordThread
+                    static const int        kNameLength = 32;
+                    char                    mName[kNameLength];
+                    sp<IPowerManager>       mPowerManager;
+                    sp<IBinder>             mWakeLockToken;
+                    sp<PMDeathRecipient>    mDeathRecipient;
     };
 
     // --- PlaybackThread ---
@@ -995,7 +1024,8 @@
             STARTING,
             ACTIVE,
             STOPPING,
-            STOPPED
+            STOPPED,
+            DESTROYED
         };
 
         int         id() { return mId; }
@@ -1040,6 +1070,7 @@
         status_t         setDevice(uint32_t device);
         status_t         setVolume(uint32_t *left, uint32_t *right, bool controller);
         status_t         setMode(uint32_t mode);
+        status_t         stop();
 
         status_t         dump(int fd, const Vector<String16>& args);
 
diff --git a/services/camera/libcameraservice/CameraHardwareInterface.h b/services/camera/libcameraservice/CameraHardwareInterface.h
index a583aad..31544b3 100644
--- a/services/camera/libcameraservice/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/CameraHardwareInterface.h
@@ -38,6 +38,7 @@
 
 typedef void (*data_callback)(int32_t msgType,
                             const sp<IMemory> &dataPtr,
+                            camera_frame_metadata_t *metadata,
                             void* user);
 
 typedef void (*data_callback_timestamp)(nsecs_t timestamp,
@@ -386,7 +387,10 @@
         if (mDevice->ops->get_parameters) {
             char *temp = mDevice->ops->get_parameters(mDevice);
             String8 str_parms(temp);
-            free(temp);
+            if (mDevice->ops->put_parameters)
+                mDevice->ops->put_parameters(mDevice, temp);
+            else
+                free(temp);
             parms.unflatten(str_parms);
         }
         return parms;
@@ -439,6 +443,7 @@
 
     static void __data_cb(int32_t msg_type,
                           const camera_memory_t *data, unsigned int index,
+                          camera_frame_metadata_t *metadata,
                           void *user)
     {
         LOGV("%s", __FUNCTION__);
@@ -450,7 +455,7 @@
                  index, mem->mNumBufs);
             return;
         }
-        __this->mDataCb(msg_type, mem->mBuffers[index], __this->mCbUser);
+        __this->mDataCb(msg_type, mem->mBuffers[index], metadata, __this->mCbUser);
     }
 
     static void __data_cb_timestamp(nsecs_t timestamp, int32_t msg_type,
diff --git a/services/camera/libcameraservice/CameraHardwareStub.cpp b/services/camera/libcameraservice/CameraHardwareStub.cpp
index 07b5a37..863f19e 100644
--- a/services/camera/libcameraservice/CameraHardwareStub.cpp
+++ b/services/camera/libcameraservice/CameraHardwareStub.cpp
@@ -180,7 +180,7 @@
 
         // Notify the client of a new frame.
         if (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)
-            mDataCb(CAMERA_MSG_PREVIEW_FRAME, buffer, mCallbackCookie);
+            mDataCb(CAMERA_MSG_PREVIEW_FRAME, buffer, NULL, mCallbackCookie);
 
         // Advance the buffer pointer.
         mCurrentPreviewFrame = (mCurrentPreviewFrame + 1) % kBufferCount;
@@ -290,14 +290,14 @@
         sp<MemoryBase> mem = new MemoryBase(mRawHeap, 0, w * h * 3 / 2);
         FakeCamera cam(w, h);
         cam.getNextFrameAsYuv420((uint8_t *)mRawHeap->base());
-        mDataCb(CAMERA_MSG_RAW_IMAGE, mem, mCallbackCookie);
+        mDataCb(CAMERA_MSG_RAW_IMAGE, mem, NULL, mCallbackCookie);
     }
 
     if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) {
         sp<MemoryHeapBase> heap = new MemoryHeapBase(kCannedJpegSize);
         sp<MemoryBase> mem = new MemoryBase(heap, 0, kCannedJpegSize);
         memcpy(heap->base(), kCannedJpeg, kCannedJpegSize);
-        mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, mCallbackCookie);
+        mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL, mCallbackCookie);
     }
     return NO_ERROR;
 }
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 96b26e7..e193be0 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -350,10 +350,9 @@
                             dataCallbackTimestamp,
                             (void *)cameraId);
 
-    // Enable zoom, error, and focus messages by default
-    enableMsgType(CAMERA_MSG_ERROR |
-                  CAMERA_MSG_ZOOM |
-                  CAMERA_MSG_FOCUS);
+    // Enable zoom, error, focus, and metadata messages by default
+    enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |
+                  CAMERA_MSG_PREVIEW_METADATA);
 
     // Callback is disabled by default
     mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
@@ -460,10 +459,10 @@
 
 static void disconnectWindow(const sp<ANativeWindow>& window) {
     if (window != 0) {
-        status_t result = native_window_disconnect(window.get(),
+        status_t result = native_window_api_disconnect(window.get(),
                 NATIVE_WINDOW_API_CAMERA);
         if (result != NO_ERROR) {
-            LOGW("native_window_disconnect failed: %s (%d)", strerror(-result),
+            LOGW("native_window_api_disconnect failed: %s (%d)", strerror(-result),
                     result);
         }
     }
@@ -526,9 +525,9 @@
     }
 
     if (window != 0) {
-        result = native_window_connect(window.get(), NATIVE_WINDOW_API_CAMERA);
+        result = native_window_api_connect(window.get(), NATIVE_WINDOW_API_CAMERA);
         if (result != NO_ERROR) {
-            LOGE("native_window_connect failed: %s (%d)", strerror(-result),
+            LOGE("native_window_api_connect failed: %s (%d)", strerror(-result),
                     result);
             return result;
         }
@@ -988,22 +987,22 @@
 }
 
 void CameraService::Client::dataCallback(int32_t msgType,
-        const sp<IMemory>& dataPtr, void* user) {
+        const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata, void* user) {
     LOG2("dataCallback(%d)", msgType);
 
     sp<Client> client = getClientFromCookie(user);
     if (client == 0) return;
     if (!client->lockIfMessageWanted(msgType)) return;
 
-    if (dataPtr == 0) {
+    if (dataPtr == 0 && metadata == NULL) {
         LOGE("Null data returned in data callback");
         client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
         return;
     }
 
-    switch (msgType) {
+    switch (msgType & ~CAMERA_MSG_PREVIEW_METADATA) {
         case CAMERA_MSG_PREVIEW_FRAME:
-            client->handlePreviewData(dataPtr);
+            client->handlePreviewData(msgType, dataPtr, metadata);
             break;
         case CAMERA_MSG_POSTVIEW_FRAME:
             client->handlePostview(dataPtr);
@@ -1015,7 +1014,7 @@
             client->handleCompressedPicture(dataPtr);
             break;
         default:
-            client->handleGenericData(msgType, dataPtr);
+            client->handleGenericData(msgType, dataPtr, metadata);
             break;
     }
 }
@@ -1055,7 +1054,9 @@
 }
 
 // preview callback - frame buffer update
-void CameraService::Client::handlePreviewData(const sp<IMemory>& mem) {
+void CameraService::Client::handlePreviewData(int32_t msgType,
+                                              const sp<IMemory>& mem,
+                                              camera_frame_metadata_t *metadata) {
     ssize_t offset;
     size_t size;
     sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
@@ -1087,11 +1088,11 @@
         // Is the received frame copied out or not?
         if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
             LOG2("frame is copied");
-            copyFrameAndPostCopiedFrame(c, heap, offset, size);
+            copyFrameAndPostCopiedFrame(msgType, c, heap, offset, size, metadata);
         } else {
             LOG2("frame is forwarded");
             mLock.unlock();
-            c->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mem);
+            c->dataCallback(msgType, mem, metadata);
         }
     } else {
         mLock.unlock();
@@ -1105,7 +1106,7 @@
     sp<ICameraClient> c = mCameraClient;
     mLock.unlock();
     if (c != 0) {
-        c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem);
+        c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem, NULL);
     }
 }
 
@@ -1120,7 +1121,7 @@
     sp<ICameraClient> c = mCameraClient;
     mLock.unlock();
     if (c != 0) {
-        c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem);
+        c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem, NULL);
     }
 }
 
@@ -1131,7 +1132,7 @@
     sp<ICameraClient> c = mCameraClient;
     mLock.unlock();
     if (c != 0) {
-        c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem);
+        c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL);
     }
 }
 
@@ -1146,11 +1147,11 @@
 }
 
 void CameraService::Client::handleGenericData(int32_t msgType,
-    const sp<IMemory>& dataPtr) {
+    const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) {
     sp<ICameraClient> c = mCameraClient;
     mLock.unlock();
     if (c != 0) {
-        c->dataCallback(msgType, dataPtr);
+        c->dataCallback(msgType, dataPtr, metadata);
     }
 }
 
@@ -1164,8 +1165,9 @@
 }
 
 void CameraService::Client::copyFrameAndPostCopiedFrame(
-        const sp<ICameraClient>& client, const sp<IMemoryHeap>& heap,
-        size_t offset, size_t size) {
+        int32_t msgType, const sp<ICameraClient>& client,
+        const sp<IMemoryHeap>& heap, size_t offset, size_t size,
+        camera_frame_metadata_t *metadata) {
     LOG2("copyFrameAndPostCopiedFrame");
     // It is necessary to copy out of pmem before sending this to
     // the callback. For efficiency, reuse the same MemoryHeapBase
@@ -1197,7 +1199,7 @@
     }
 
     mLock.unlock();
-    client->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame);
+    client->dataCallback(msgType, frame, metadata);
 }
 
 int CameraService::Client::getOrientation(int degrees, bool mirror) {
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index c5fefb8..57abf83 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -140,24 +140,29 @@
 
         // these are static callback functions
         static void             notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2, void* user);
-        static void             dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, void* user);
+        static void             dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
+                                             camera_frame_metadata_t *metadata, void* user);
         static void             dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr, void* user);
         // convert client from cookie
         static sp<Client>       getClientFromCookie(void* user);
         // handlers for messages
         void                    handleShutter(void);
-        void                    handlePreviewData(const sp<IMemory>& mem);
+        void                    handlePreviewData(int32_t msgType, const sp<IMemory>& mem,
+                                                  camera_frame_metadata_t *metadata);
         void                    handlePostview(const sp<IMemory>& mem);
         void                    handleRawPicture(const sp<IMemory>& mem);
         void                    handleCompressedPicture(const sp<IMemory>& mem);
         void                    handleGenericNotify(int32_t msgType, int32_t ext1, int32_t ext2);
-        void                    handleGenericData(int32_t msgType, const sp<IMemory>& dataPtr);
+        void                    handleGenericData(int32_t msgType, const sp<IMemory>& dataPtr,
+                                                  camera_frame_metadata_t *metadata);
         void                    handleGenericDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
 
         void                    copyFrameAndPostCopiedFrame(
+                                    int32_t msgType,
                                     const sp<ICameraClient>& client,
                                     const sp<IMemoryHeap>& heap,
-                                    size_t offset, size_t size);
+                                    size_t offset, size_t size,
+                                    camera_frame_metadata_t *metadata);
 
         int                     getOrientation(int orientation, bool mirror);