Implement host service manager

On the host, after

  setDefaultServiceManager(createRpcDelegateServiceManager())

is called, defaultServiceManager() will return
a service manager delegate that calls into the service
manager on the device.

Test: binderHostDeviceTest with servicedispatcher installed
Bug: 190233850

Change-Id: I44f9d2e2419883e242fea0472d702f559dd0b283
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index d421060..2175fd4 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -35,6 +35,8 @@
 
 #ifdef __ANDROID__
 #include <cutils/properties.h>
+#else
+#include "ServiceManagerHost.h"
 #endif
 
 #include "Static.h"
@@ -84,8 +86,19 @@
     IBinder* onAsBinder() override {
         return IInterface::asBinder(mTheRealServiceManager).get();
     }
-private:
+
+protected:
     sp<AidlServiceManager> mTheRealServiceManager;
+
+    // Directly get the service in a way that, for lazy services, requests the service to be started
+    // if it is not currently started. This way, calls directly to ServiceManagerShim::getService
+    // will still have the 5s delay that is expected by a large amount of Android code.
+    //
+    // When implementing ServiceManagerShim, use realGetService instead of
+    // mTheRealServiceManager->getService so that it can be overridden in ServiceManagerHostShim.
+    virtual Status realGetService(const std::string& name, sp<IBinder>* _aidl_return) {
+        return mTheRealServiceManager->getService(name, _aidl_return);
+    }
 };
 
 [[clang::no_destroy]] static std::once_flag gSmOnce;
@@ -319,7 +332,7 @@
     const std::string name = String8(name16).c_str();
 
     sp<IBinder> out;
-    if (Status status = mTheRealServiceManager->getService(name, &out); !status.isOk()) {
+    if (Status status = realGetService(name, &out); !status.isOk()) {
         ALOGW("Failed to getService in waitForService for %s: %s", name.c_str(),
               status.toString8().c_str());
         return nullptr;
@@ -363,7 +376,7 @@
         // - init gets death signal, but doesn't know it needs to restart
         //   the service
         // - we need to request service again to get it to start
-        if (Status status = mTheRealServiceManager->getService(name, &out); !status.isOk()) {
+        if (Status status = realGetService(name, &out); !status.isOk()) {
             ALOGW("Failed to getService in waitForService on later try for %s: %s", name.c_str(),
                   status.toString8().c_str());
             return nullptr;
@@ -412,4 +425,38 @@
     return declared ? std::optional<String16>(String16(declared.value().c_str())) : std::nullopt;
 }
 
+#ifndef __ANDROID__
+// ServiceManagerShim for host. Implements the old libbinder android::IServiceManager API.
+// The internal implementation of the AIDL interface android::os::IServiceManager calls into
+// on-device service manager.
+class ServiceManagerHostShim : public ServiceManagerShim {
+public:
+    using ServiceManagerShim::ServiceManagerShim;
+    // ServiceManagerShim::getService is based on checkService, so no need to override it.
+    sp<IBinder> checkService(const String16& name) const override {
+        return getDeviceService({String8(name).c_str()});
+    }
+
+protected:
+    // Override realGetService for ServiceManagerShim::waitForService.
+    Status realGetService(const std::string& name, sp<IBinder>* _aidl_return) {
+        *_aidl_return = getDeviceService({"-g", name});
+        return Status::ok();
+    }
+};
+sp<IServiceManager> createRpcDelegateServiceManager() {
+    auto binder = getDeviceService({"manager"});
+    if (binder == nullptr) {
+        ALOGE("getDeviceService(\"manager\") returns null");
+        return nullptr;
+    }
+    auto interface = AidlServiceManager::asInterface(binder);
+    if (interface == nullptr) {
+        ALOGE("getDeviceService(\"manager\") returns non service manager");
+        return nullptr;
+    }
+    return sp<ServiceManagerHostShim>::make(interface);
+}
+#endif
+
 } // namespace android