Merge "Access AVCDEC context after create fail check" into mnc-dr-dev am: eba5ad1a07 am: ba9840c1ce am: 6fd437edf7 am: b334ac03d9 am: a61eab4354
am: 193030ccf0

Change-Id: Ie2176c35fa1a7b9192c01b1a00e5de27afe8678f
diff --git a/camera/CameraBase.cpp b/camera/CameraBase.cpp
index 72951fc..8a18d2f 100644
--- a/camera/CameraBase.cpp
+++ b/camera/CameraBase.cpp
@@ -20,6 +20,7 @@
 #include <utils/Log.h>
 #include <utils/threads.h>
 #include <utils/Mutex.h>
+#include <cutils/properties.h>
 
 #include <android/hardware/ICameraService.h>
 
@@ -90,6 +91,12 @@
 {
     Mutex::Autolock _l(gLock);
     if (gCameraService.get() == 0) {
+        char value[PROPERTY_VALUE_MAX];
+        property_get("config.disable_cameraservice", value, "0");
+        if (strncmp(value, "0", 2) != 0 && strncasecmp(value, "false", 6) != 0) {
+            return gCameraService;
+        }
+
         sp<IServiceManager> sm = defaultServiceManager();
         sp<IBinder> binder;
         do {
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index 26d6679..35555ff 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -22,6 +22,7 @@
 #include "ACameraMetadata.h"
 #include "ACameraDevice.h"
 #include <utils/Vector.h>
+#include <cutils/properties.h>
 #include <stdlib.h>
 #include <camera/VendorTagDescriptor.h>
 
@@ -71,9 +72,19 @@
     mCameraService.clear();
 }
 
+static bool isCameraServiceDisabled() {
+    char value[PROPERTY_VALUE_MAX];
+    property_get("config.disable_cameraservice", value, "0");
+    return (strncmp(value, "0", 2) != 0 && strncasecmp(value, "false", 6) != 0);
+}
+
 sp<hardware::ICameraService> CameraManagerGlobal::getCameraService() {
     Mutex::Autolock _l(mLock);
     if (mCameraService.get() == nullptr) {
+        if (isCameraServiceDisabled()) {
+            return mCameraService;
+        }
+
         sp<IServiceManager> sm = defaultServiceManager();
         sp<IBinder> binder;
         do {
@@ -302,6 +313,13 @@
 camera_status_t
 ACameraManager::getOrCreateCameraIdListLocked(ACameraIdList** cameraIdList) {
     if (mCachedCameraIdList.numCameras == kCameraIdListNotInit) {
+        if (isCameraServiceDisabled()) {
+            mCachedCameraIdList.numCameras = 0;
+            mCachedCameraIdList.cameraIds = new const char*[0];
+            *cameraIdList = &mCachedCameraIdList;
+            return ACAMERA_OK;
+        }
+
         int numCameras = 0;
         Vector<char *> cameraIds;
         sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index d011d70..609b00d 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -368,10 +368,21 @@
     mRecorder->setListener(listener);
 
     sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->getService(String16("media.camera"));
-    mCameraDeathListener = new ServiceDeathNotifier(binder, listener,
-            MediaPlayerService::CAMERA_PROCESS_DEATH);
-    binder->linkToDeath(mCameraDeathListener);
+
+    // WORKAROUND: We don't know if camera exists here and getService might block for 5 seconds.
+    // Use checkService for camera if we don't know it exists.
+    static std::atomic<bool> sCameraChecked(false);  // once true never becomes false.
+    static std::atomic<bool> sCameraVerified(false); // once true never becomes false.
+    sp<IBinder> binder = (sCameraVerified || !sCameraChecked)
+        ? sm->getService(String16("media.camera")) : sm->checkService(String16("media.camera"));
+    // If the device does not have a camera, do not create a death listener for it.
+    if (binder != NULL) {
+        sCameraVerified = true;
+        mCameraDeathListener = new ServiceDeathNotifier(binder, listener,
+                MediaPlayerService::CAMERA_PROCESS_DEATH);
+        binder->linkToDeath(mCameraDeathListener);
+    }
+    sCameraChecked = true;
 
     binder = sm->getService(String16("media.codec"));
     mCodecDeathListener = new ServiceDeathNotifier(binder, listener,
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index af2d0f3..f0f44e6 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -876,10 +876,6 @@
 
 status_t NuPlayer::GenericSource::dequeueAccessUnit(
         bool audio, sp<ABuffer> *accessUnit) {
-    if (audio && !mStarted) {
-        return -EWOULDBLOCK;
-    }
-
     Track *track = audio ? &mAudioTrack : &mVideoTrack;
 
     if (track->mSource == NULL) {
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 968b80f..d265f11 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -330,7 +330,7 @@
     DeviceVector deviceList;
     uint32_t muteWaitMs = 0;
 
-    if(!hasPrimaryOutput()) {
+    if(!hasPrimaryOutput() || mPrimaryOutput->device() == AUDIO_DEVICE_OUT_STUB) {
         return muteWaitMs;
     }
     audio_devices_t txDevice = getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);