Merge "Camera: Do not update state at HAL starts up if state already exists"
diff --git a/media/libstagefright/MediaExtractorFactory.cpp b/media/libstagefright/MediaExtractorFactory.cpp
index 06aedb7..b0bf269 100644
--- a/media/libstagefright/MediaExtractorFactory.cpp
+++ b/media/libstagefright/MediaExtractorFactory.cpp
@@ -18,6 +18,8 @@
 #define LOG_TAG "MediaExtractorFactory"
 #include <utils/Log.h>
 
+#include <binder/IPCThreadState.h>
+#include <binder/PermissionCache.h>
 #include <binder/IServiceManager.h>
 #include <media/DataSource.h>
 #include <media/MediaAnalyticsItem.h>
@@ -320,17 +322,28 @@
 status_t MediaExtractorFactory::dump(int fd, const Vector<String16>&) {
     Mutex::Autolock autoLock(gPluginMutex);
     String8 out;
-    out.append("Available extractors:\n");
-    if (gPluginsRegistered) {
-        for (auto it = gPlugins->begin(); it != gPlugins->end(); ++it) {
-            out.appendFormat("  %25s: uuid(%s), version(%u), path(%s)\n",
-                    (*it)->def.extractor_name,
-                    (*it)->uuidString.c_str(),
-                    (*it)->def.extractor_version,
-                    (*it)->libPath.c_str());
-        }
+
+    const IPCThreadState* ipc = IPCThreadState::self();
+    const int pid = ipc->getCallingPid();
+    const int uid = ipc->getCallingUid();
+    if (!PermissionCache::checkPermission(String16("android.permission.DUMP"), pid, uid)) {
+        // dumpExtractors() will append the following string.
+        // out.appendFormat("Permission Denial: "
+        //        "can't dump MediaExtractor from pid=%d, uid=%d\n", pid, uid);
+        ALOGE("Permission Denial: can't dump MediaExtractor from pid=%d, uid=%d", pid, uid);
     } else {
-        out.append("  (no plugins registered)\n");
+        out.append("Available extractors:\n");
+        if (gPluginsRegistered) {
+            for (auto it = gPlugins->begin(); it != gPlugins->end(); ++it) {
+                out.appendFormat("  %25s: uuid(%s), version(%u), path(%s)\n",
+                        (*it)->def.extractor_name,
+                        (*it)->uuidString.c_str(),
+                        (*it)->def.extractor_version,
+                        (*it)->libPath.c_str());
+            }
+        } else {
+            out.append("  (no plugins registered)\n");
+        }
     }
     write(fd, out.string(), out.size());
     return OK;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index b5d9963..c9c806a 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -15,7 +15,12 @@
  */
 
 #define LOG_TAG "APM_AudioPolicyManager"
-//#define LOG_NDEBUG 0
+
+// Need to keep the log statements even in production builds
+// to enable VERBOSE logging dynamically.
+// You can enable VERBOSE logging as follows:
+// adb shell setprop log.tag.APM_AudioPolicyManager V
+#define LOG_NDEBUG 0
 
 //#define VERY_VERBOSE_LOGGING
 #ifdef VERY_VERBOSE_LOGGING
@@ -4168,6 +4173,9 @@
         status = NO_INIT;
     }
 
+    // Silence ALOGV statements
+    property_set("log.tag." LOG_TAG, "D");
+
     updateDevicesAndOutputs();
     return status;
 }
diff --git a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
index 1ee216f..84f0a89 100644
--- a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
+++ b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
@@ -492,7 +492,6 @@
     ATRACE_CALL();
     SharedParameters::Lock l(client->getParameters());
     Vector<int32_t> outputStreams;
-    uint8_t captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
 
     /**
      * Set up output streams in the request
@@ -522,7 +521,6 @@
 
     if (l.mParameters.state == Parameters::VIDEO_SNAPSHOT) {
         outputStreams.push(client->getRecordingStreamId());
-        captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT);
     }
 
     res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
@@ -532,10 +530,6 @@
                 &mCaptureId, 1);
     }
     if (res == OK) {
-        res = mCaptureRequest.update(ANDROID_CONTROL_CAPTURE_INTENT,
-                &captureIntent, 1);
-    }
-    if (res == OK) {
         res = mCaptureRequest.sort();
     }
 
@@ -683,6 +677,8 @@
         sp<Camera2Client> &client) {
     ATRACE_CALL();
     status_t res;
+    uint8_t captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
+
     if (mCaptureRequest.entryCount() == 0) {
         res = client->getCameraDevice()->createDefaultRequest(
                 CAMERA2_TEMPLATE_STILL_CAPTURE,
@@ -695,6 +691,16 @@
         }
     }
 
+    if (params.state == Parameters::VIDEO_SNAPSHOT) {
+        captureIntent = static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT);
+    }
+    res = mCaptureRequest.update(ANDROID_CONTROL_CAPTURE_INTENT, &captureIntent, 1);
+    if (res != OK) {
+        ALOGE("%s: Camera %d: Unable to update capture intent: %s (%d)",
+                __FUNCTION__, client->getCameraId(), strerror(-res), res);
+        return res;
+    }
+
     res = params.updateRequest(&mCaptureRequest);
     if (res != OK) {
         ALOGE("%s: Camera %d: Unable to update common entries of capture "