Fix AIDL lazy camera HAL startup.

AServiceManager_getService() won't start a service if it isn't already
running.

Bug: 285546208

Test: Vendor testing
Test: Kill camera provider process, make sure it comes up again and
      cameraserver adds it

Change-Id: I1bfd2c2af29afa795caa074d4de38a8d2119ee12
Signed-off-by: Jayant Chowdhary <jchowdhary@google.com>
diff --git a/camera/camera_platform.aconfig b/camera/camera_platform.aconfig
index 074413f..33eb592 100644
--- a/camera/camera_platform.aconfig
+++ b/camera/camera_platform.aconfig
@@ -20,3 +20,10 @@
      description: "Flash brightness level control in manual flash mode"
      bug: "238348881"
 }
+
+flag {
+     namespace: "camera_platform"
+     name: "lazy_aidl_wait_for_service"
+     description: "Use waitForService instead of getService with lazy AIDL HALs"
+     bug: "285546208"
+}
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 23051ef..b3474e5 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -35,6 +35,7 @@
 #include <android/binder_manager.h>
 #include <android/hidl/manager/1.2/IServiceManager.h>
 #include <hidl/ServiceManagement.h>
+#include <com_android_internal_camera_flags.h>
 #include <functional>
 #include <camera_metadata_hidden.h>
 #include <android-base/parseint.h>
@@ -57,6 +58,8 @@
 using std::literals::chrono_literals::operator""s;
 using hardware::camera2::utils::CameraIdAndSessionConfiguration;
 
+namespace flags = com::android::internal::camera::flags;
+
 namespace {
 const bool kEnableLazyHal(property_get_bool("ro.camera.enableLazyHal", false));
 const std::string kExternalProviderName = "external/0";
@@ -1918,9 +1921,15 @@
 status_t CameraProviderManager::tryToInitializeAidlProviderLocked(
         const std::string& providerName, const sp<ProviderInfo>& providerInfo) {
     using aidl::android::hardware::camera::provider::ICameraProvider;
+
+    AIBinder *binder = nullptr;
+    if (flags::lazy_aidl_wait_for_service()) {
+        binder = AServiceManager_waitForService(providerName.c_str());
+    } else {
+        binder = AServiceManager_getService(providerName.c_str());
+    }
     std::shared_ptr<ICameraProvider> interface =
-            ICameraProvider::fromBinder(ndk::SpAIBinder(
-                    AServiceManager_getService(providerName.c_str())));
+            ICameraProvider::fromBinder(ndk::SpAIBinder(binder));
 
     if (interface == nullptr) {
         ALOGW("%s: AIDL Camera provider HAL '%s' is not actually available", __FUNCTION__,
@@ -1956,15 +1965,18 @@
     bool providerPresent = false;
     bool preexisting =
             (mAidlProviderWithBinders.find(newProvider) != mAidlProviderWithBinders.end());
-
-    // We need to use the extracted provider name here since 'newProvider' has
-    // the fully qualified name of the provider service in case of AIDL. We want
-    // just instance name.
     using aidl::android::hardware::camera::provider::ICameraProvider;
-    std::string extractedProviderName =
+    std::string providerNameUsed  =
             newProvider.substr(std::string(ICameraProvider::descriptor).size() + 1);
+    if (flags::lazy_aidl_wait_for_service()) {
+        // 'newProvider' has the fully qualified name of the provider service in case of AIDL.
+        // ProviderInfo::mProviderName also has the fully qualified name - so we just compare them
+        // here.
+        providerNameUsed = newProvider;
+    }
+
     for (const auto& providerInfo : mProviders) {
-        if (providerInfo->mProviderName == extractedProviderName) {
+        if (providerInfo->mProviderName == providerNameUsed) {
             ALOGW("%s: Camera provider HAL with name '%s' already registered",
                     __FUNCTION__, newProvider.c_str());
             // Do not add new instances for lazy HAL external provider or aidl
@@ -1981,7 +1993,7 @@
     }
 
     sp<AidlProviderInfo> providerInfo =
-            new AidlProviderInfo(extractedProviderName, providerInstance, this);
+            new AidlProviderInfo(providerNameUsed, providerInstance, this);
 
     if (!providerPresent) {
         status_t res = tryToInitializeAidlProviderLocked(newProvider, providerInfo);
@@ -2061,6 +2073,9 @@
             if (providerInfo->mProviderName == removedProviderName) {
                 IPCTransport providerTransport = providerInfo->getIPCTransport();
                 std::string removedAidlProviderName = getFullAidlProviderName(removedProviderName);
+                if (flags::lazy_aidl_wait_for_service()) {
+                    removedAidlProviderName = removedProviderName;
+                }
                 switch(providerTransport) {
                     case IPCTransport::HIDL:
                         return tryToInitializeHidlProviderLocked(removedProviderName, providerInfo);
@@ -2230,7 +2245,13 @@
 }
 
 bool CameraProviderManager::ProviderInfo::isExternalLazyHAL() const {
-    return kEnableLazyHal && (mProviderName == kExternalProviderName);
+    std::string providerName = mProviderName;
+    if (flags::lazy_aidl_wait_for_service() && getIPCTransport() == IPCTransport::AIDL) {
+        using aidl::android::hardware::camera::provider::ICameraProvider;
+        providerName =
+                mProviderName.substr(std::string(ICameraProvider::descriptor).size() + 1);
+    }
+    return kEnableLazyHal && (providerName == kExternalProviderName);
 }
 
 status_t CameraProviderManager::ProviderInfo::dump(int fd, const Vector<String16>&) const {
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 28be652..f1abf91 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -489,7 +489,7 @@
                 CameraProviderManager *manager);
         ~ProviderInfo();
 
-        virtual IPCTransport getIPCTransport() = 0;
+        virtual IPCTransport getIPCTransport() const = 0;
 
         const std::string& getType() const;
 
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
index 9659db8..dd0de95 100644
--- a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
@@ -17,6 +17,7 @@
 #include "common/HalConversionsTemplated.h"
 #include "common/CameraProviderInfoTemplated.h"
 
+#include <com_android_internal_camera_flags.h>
 #include <cutils/properties.h>
 
 #include <aidlcommonsupport/NativeHandle.h>
@@ -34,6 +35,7 @@
 
 namespace android {
 
+namespace flags = com::android::internal::camera::flags;
 namespace SessionConfigurationUtils = ::android::camera3::SessionConfigurationUtils;
 
 using namespace aidl::android::hardware;
@@ -99,7 +101,14 @@
 status_t AidlProviderInfo::initializeAidlProvider(
         std::shared_ptr<ICameraProvider>& interface, int64_t currentDeviceState) {
 
-    status_t res = parseProviderName(mProviderName, &mType, &mId);
+    using aidl::android::hardware::camera::provider::ICameraProvider;
+    std::string parsedProviderName = mProviderName;
+    if (flags::lazy_aidl_wait_for_service()) {
+        parsedProviderName =
+                mProviderName.substr(std::string(ICameraProvider::descriptor).size() + 1);
+    }
+
+    status_t res = parseProviderName(parsedProviderName, &mType, &mId);
     if (res != OK) {
         ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
         return BAD_VALUE;
@@ -274,10 +283,13 @@
         if (interface == nullptr) {
             ALOGV("Camera provider actually needs restart, calling getService(%s)",
                   mProviderName.c_str());
-            interface =
-                            ICameraProvider::fromBinder(
-                                    ndk::SpAIBinder(
-                                                AServiceManager_getService(mProviderName.c_str())));
+            AIBinder * binder = nullptr;
+            if (flags::lazy_aidl_wait_for_service()) {
+                binder = AServiceManager_waitForService(mProviderName.c_str());
+            } else {
+                binder = AServiceManager_getService(mProviderName.c_str());
+            }
+            interface = ICameraProvider::fromBinder(ndk::SpAIBinder(binder));
 
             // Set all devices as ENUMERATING, provider should update status
             // to PRESENT after initializing.
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h
index 97a8fed..90bc627 100644
--- a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h
@@ -49,7 +49,7 @@
 
     static void binderDied(void *cookie);
 
-    virtual IPCTransport getIPCTransport() override {return IPCTransport::AIDL;}
+    virtual IPCTransport getIPCTransport() const override {return IPCTransport::AIDL;}
 
     const std::shared_ptr<aidl::android::hardware::camera::provider::ICameraProvider>
     startProviderInterface();
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
index e0f1646..fa6f4d4 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
@@ -45,7 +45,7 @@
             sp<hardware::camera::provider::V2_4::ICameraProvider>& interface,
             int64_t currentDeviceState);
 
-    IPCTransport getIPCTransport() override {return IPCTransport::HIDL;}
+    IPCTransport getIPCTransport() const override {return IPCTransport::HIDL;}
 
     const sp<hardware::camera::provider::V2_4::ICameraProvider> startProviderInterface();