merge in jb-mr1-factory-release history after reset to jb-mr1-dev
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index da4645a..49e1afc 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -70,6 +70,8 @@
     // returns true in *state if tracks are active on the specified stream or has been active
     // in the past inPastMs milliseconds
     static status_t isStreamActive(audio_stream_type_t stream, bool *state, uint32_t inPastMs = 0);
+    // returns true in *state if a recorder is currently recording with the specified source
+    static status_t isSourceActive(audio_source_t source, bool *state);
 
     // set/get audio hardware parameters. The function accepts a list of parameters
     // key value pairs in the form: key1=value1;key2=value2;...
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index fb556af..cc2e069 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -88,6 +88,7 @@
     virtual status_t unregisterEffect(int id) = 0;
     virtual status_t setEffectEnabled(int id, bool enabled) = 0;
     virtual bool     isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const = 0;
+    virtual bool     isSourceActive(audio_source_t source) const = 0;
     virtual status_t queryDefaultPreProcessing(int audioSession,
                                               effect_descriptor_t *descriptors,
                                               uint32_t *count) = 0;
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 5624df4..207f96f 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -735,6 +735,15 @@
     return NO_ERROR;
 }
 
+status_t AudioSystem::isSourceActive(audio_source_t stream, bool* state)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    if (state == NULL) return BAD_VALUE;
+    *state = aps->isSourceActive(stream);
+    return NO_ERROR;
+}
+
 int32_t AudioSystem::getPrimaryOutputSamplingRate()
 {
     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 31c5d27..401437c 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -52,6 +52,7 @@
     REGISTER_EFFECT,
     UNREGISTER_EFFECT,
     IS_STREAM_ACTIVE,
+    IS_SOURCE_ACTIVE,
     GET_DEVICES_FOR_STREAM,
     QUERY_DEFAULT_PRE_PROCESSING,
     SET_EFFECT_ENABLED
@@ -329,6 +330,15 @@
         return reply.readInt32();
     }
 
+    virtual bool isSourceActive(audio_source_t source) const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.writeInt32((int32_t) source);
+        remote()->transact(IS_SOURCE_ACTIVE, data, &reply);
+        return reply.readInt32();
+    }
+
     virtual status_t queryDefaultPreProcessing(int audioSession,
                                                effect_descriptor_t *descriptors,
                                                uint32_t *count)
@@ -592,6 +602,13 @@
             return NO_ERROR;
         } break;
 
+        case IS_SOURCE_ACTIVE: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            audio_source_t source = (audio_source_t) data.readInt32();
+            reply->writeInt32( isSourceActive(source));
+            return NO_ERROR;
+        }
+
         case QUERY_DEFAULT_PRE_PROCESSING: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
             int audioSession = data.readInt32();
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index 155a0b8..8b99bd2 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -483,6 +483,18 @@
     return mpAudioPolicy->is_stream_active(mpAudioPolicy, stream, inPastMs);
 }
 
+bool AudioPolicyService::isSourceActive(audio_source_t source) const
+{
+    if (mpAudioPolicy == NULL) {
+        return false;
+    }
+    if (mpAudioPolicy->is_source_active == 0) {
+        return false;
+    }
+    Mutex::Autolock _l(mLock);
+    return mpAudioPolicy->is_source_active(mpAudioPolicy, source);
+}
+
 status_t AudioPolicyService::queryDefaultPreProcessing(int audioSession,
                                                        effect_descriptor_t *descriptors,
                                                        uint32_t *count)
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index a086734..63f9549 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -104,6 +104,7 @@
     virtual status_t unregisterEffect(int id);
     virtual status_t setEffectEnabled(int id, bool enabled);
     virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
+    virtual bool isSourceActive(audio_source_t source) const;
 
     virtual status_t queryDefaultPreProcessing(int audioSession,
                                               effect_descriptor_t *descriptors,
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp
index 7a6e344..7290663 100644
--- a/services/camera/libcameraservice/Camera2Client.cpp
+++ b/services/camera/libcameraservice/Camera2Client.cpp
@@ -65,10 +65,10 @@
 
 status_t Camera2Client::checkPid(const char* checkLocation) const {
     int callingPid = getCallingPid();
-    if (callingPid == mClientPid || callingPid == mServicePid) return NO_ERROR;
+    if (callingPid == mClientPid) return NO_ERROR;
 
     ALOGE("%s: attempt to use a locked camera from a different process"
-            " (old pid %d, new pid %d, servicePid %d)", checkLocation, mClientPid, callingPid, mServicePid);
+            " (old pid %d, new pid %d)", checkLocation, mClientPid, callingPid);
     return PERMISSION_DENIED;
 }
 
@@ -139,19 +139,7 @@
 
     mDestructionStarted = true;
 
-    Parameters::State state;
-    // warning:
-    //   holding on to locks more than necessary may be hazardous to your health
-    {
-        SharedParameters::Lock l(mParameters);
-        state = l.mParameters.state;
-    }
-
-    if (state != Parameters::DISCONNECTED) {
-        // Rewrite mClientPid to allow shutdown by CameraService
-        mClientPid = getCallingPid();
-        disconnect();
-    }
+    disconnect();
 
     ALOGI("Camera %d: Closed", mCameraId);
 }
@@ -372,7 +360,10 @@
     ATRACE_CALL();
     Mutex::Autolock icl(mICameraLock);
     status_t res;
-    if ( (res = checkPid(__FUNCTION__) ) != OK) return;
+
+    // Allow both client and the media server to disconnect at all times
+    int callingPid = getCallingPid();
+    if (callingPid != mClientPid && callingPid != mServicePid) return;
 
     if (mDevice == 0) return;
 
@@ -382,6 +373,7 @@
 
     {
         SharedParameters::Lock l(mParameters);
+        if (l.mParameters.state == Parameters::DISCONNECTED) return;
         l.mParameters.state = Parameters::DISCONNECTED;
     }
 
@@ -462,9 +454,13 @@
     ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
             __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
 
-    // TODO: Check for uninterruptable conditions
-
     if (mClientPid == getCallingPid()) {
+        SharedParameters::Lock l(mParameters);
+        if (l.mParameters.state == Parameters::RECORD ||
+                l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
+            ALOGD("Not allowed to unlock camera during recording.");
+            return INVALID_OPERATION;
+        }
         mClientPid = 0;
         mCameraClient.clear();
         mSharedCameraClient.clear();
@@ -615,10 +611,13 @@
 
     ALOGV("%s: state == %d, restart = %d", __FUNCTION__, params.state, restart);
 
-    if (params.state == Parameters::PREVIEW && !restart) {
-        // Succeed attempt to re-enter preview state
-        ALOGI("%s: Not starting preview; already in preview state.",
-              __FUNCTION__);
+    if ( (params.state == Parameters::PREVIEW ||
+                    params.state == Parameters::RECORD ||
+                    params.state == Parameters::VIDEO_SNAPSHOT)
+            && !restart) {
+        // Succeed attempt to re-enter a streaming state
+        ALOGI("%s: Camera %d: Preview already active, ignoring restart",
+                __FUNCTION__, mCameraId);
         return OK;
     }
     if (params.state > Parameters::PREVIEW && !restart) {
diff --git a/services/camera/libcameraservice/CameraClient.cpp b/services/camera/libcameraservice/CameraClient.cpp
index 7e199fa..b930c02 100644
--- a/services/camera/libcameraservice/CameraClient.cpp
+++ b/services/camera/libcameraservice/CameraClient.cpp
@@ -102,8 +102,6 @@
     int callingPid = getCallingPid();
     LOG1("CameraClient::~CameraClient E (pid %d, this %p)", callingPid, this);
 
-    // set mClientPid to let disconnet() tear down the hardware
-    mClientPid = callingPid;
     disconnect();
     LOG1("CameraClient::~CameraClient X (pid %d, this %p)", callingPid, this);
 }
@@ -125,7 +123,7 @@
 
 status_t CameraClient::checkPid() const {
     int callingPid = getCallingPid();
-    if (callingPid == mClientPid || callingPid == mServicePid) return NO_ERROR;
+    if (callingPid == mClientPid) return NO_ERROR;
 
     ALOGW("attempt to use a locked camera from a different process"
          " (old pid %d, new pid %d)", mClientPid, callingPid);
@@ -219,7 +217,8 @@
     LOG1("disconnect E (pid %d)", callingPid);
     Mutex::Autolock lock(mLock);
 
-    if (checkPid() != NO_ERROR) {
+    // Allow both client and the media server to disconnect at all times
+    if (callingPid != mClientPid && callingPid != mServicePid) {
         ALOGW("different client - don't disconnect");
         return;
     }
diff --git a/services/camera/libcameraservice/camera2/Parameters.cpp b/services/camera/libcameraservice/camera2/Parameters.cpp
index 05494d3..3c679da 100644
--- a/services/camera/libcameraservice/camera2/Parameters.cpp
+++ b/services/camera/libcameraservice/camera2/Parameters.cpp
@@ -1739,9 +1739,6 @@
             reqMeteringAreas, reqMeteringAreasSize);
     if (res != OK) return res;
 
-    res = request->update(ANDROID_CONTROL_AWB_REGIONS,
-            reqMeteringAreas, reqMeteringAreasSize);
-    if (res != OK) return res;
     delete[] reqMeteringAreas;
 
     /* don't include jpeg thumbnail size - it's valid for