Update for hidlized service manager.

Test: end to end (runs on device, nfc registers with it and runs)
Test: hidl_test
Bug: 32313592
Change-Id: I8a98e8f46c2f2216a097018599c7ac81701b008b
diff --git a/Android.bp b/Android.bp
index 46c33b0..6bfa6c5 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,20 +1,28 @@
 cc_binary {
     name: "hwservicemanager",
-    srcs: ["hw_service_manager.cpp"],
+    init_rc: [
+        "hwservicemanager.rc",
+    ],
+    srcs: [
+        "ServiceManager.cpp",
+        "service.cpp",
+    ],
     cflags: [
         "-Wall",
         "-Wextra",
         "-Werror",
     ],
     shared_libs: [
+        "libhidl",
         "liblog",
         "libselinux",
-        "libhidl",
         "libhwbinder",
         "libcutils",
         "libutils",
     ],
-    export_shared_lib_headers: ["libhwbinder"],
+    export_shared_lib_headers: [
+        "libhwbinder"
+    ],
     product_variables: {
         binder32bit: {
             cflags: ["-DBINDER_IPC_32BIT=1"],
diff --git a/ServiceManager.cpp b/ServiceManager.cpp
new file mode 100644
index 0000000..ff0e9c5
--- /dev/null
+++ b/ServiceManager.cpp
@@ -0,0 +1,64 @@
+#include "ServiceManager.h"
+
+#include <hidl/HidlSupport.h>
+
+namespace android {
+namespace hidl {
+namespace manager {
+namespace V1_0 {
+namespace implementation {
+
+// Methods from ::android::hidl::manager::V1_0::IServiceManager follow.
+Return<void> ServiceManager::get(const hidl_string& name, const Version& version, get_cb _hidl_cb)  {
+    const std::string name_str = name.c_str();
+    auto numEntries = mServiceMap.count(name_str);
+    auto it = mServiceMap.find(name_str);
+
+    hidl_version hidlVersion (version.major, version.minor);
+
+    while (numEntries > 0) {
+        if (it->second->supportsVersion(hidlVersion)) {
+            _hidl_cb(it->second->getService());
+            return Void();
+        }
+        --numEntries;
+        ++it;
+    }
+
+    _hidl_cb(nullptr);
+    return Void();
+}
+
+Return<bool> ServiceManager::add(const hidl_string& name, const sp<IBinder>& service, const Version& version)  {
+    const std::string name_str = name.c_str();
+    size_t numEntries = mServiceMap.count(name_str);
+    auto service_iter = mServiceMap.find(name_str);
+    bool replaced = false;
+
+    const hidl_version hidlVersion (version.major, version.minor);
+
+    while (numEntries > 0) {
+        if (service_iter->second->getVersion() == hidlVersion) {
+            // Just update service reference
+            service_iter->second->setService(service);
+            replaced = true;
+            break;
+        }
+        --numEntries;
+        ++service_iter;
+    }
+    if (!replaced) {
+        mServiceMap.insert({name_str, std::unique_ptr<HidlService>(
+                new HidlService(name_str, service, version, ""))});
+    }
+
+    // TODO link to death so we know when it dies
+
+    return true;
+}
+
+} // namespace implementation
+}  // namespace V1_0
+}  // namespace manager
+}  // namespace hidl
+}  // namespace android
diff --git a/ServiceManager.h b/ServiceManager.h
new file mode 100644
index 0000000..185425e
--- /dev/null
+++ b/ServiceManager.h
@@ -0,0 +1,83 @@
+#ifndef HIDL_GENERATED_android_hardware_manager_V1_0_ServiceManager_H_
+#define HIDL_GENERATED_android_hardware_manager_V1_0_ServiceManager_H_
+
+#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <hidl/Status.h>
+#include <hidl/MQDescriptor.h>
+#include <map>
+
+namespace android {
+namespace hidl {
+namespace manager {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_version;
+using ::android::hardware::IBinder;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hidl::manager::V1_0::IServiceManager;
+using ::android::sp;
+
+using Version = ::android::hidl::manager::V1_0::IServiceManager::Version;
+
+struct HidlService {
+      HidlService(const std::string &name,
+                  const sp<IBinder>& service,
+                  const Version& version,
+                  const std::string &metaVersion)
+      : mName(name),
+        mVersion(version.major, version.minor),
+        mMetaVersion(metaVersion),
+        mService(service) {}
+
+      sp<IBinder> getService() const {
+          return mService;
+      }
+
+      void setService(const sp<IBinder>& service) {
+          mService = service;
+      }
+
+      const hidl_version& getVersion() const {
+          return mVersion;
+      }
+
+      bool supportsVersion(hidl_version version) {
+          if (version.get_major() == mVersion.get_major() &&
+                  version.get_minor() <= mVersion.get_minor()) {
+              return true;
+          }
+          // TODO remove log
+          ALOGE("Service doesn't support version %u.%u", version.get_major(), version.get_minor());
+          return false;
+      }
+
+private:
+      const std::string                     mName;
+      const hidl_version                    mVersion;
+      const std::string                     mMetaVersion;
+      sp<IBinder>                           mService;
+};
+
+struct ServiceManager : public IServiceManager {
+    // Methods from ::android::hidl::manager::V1_0::IServiceManager follow.
+    Return<void> get(const hidl_string& name, const Version& version, get_cb _hidl_cb)  override;
+    Return<bool> add(const hidl_string& name, const sp<IBinder>& service, const Version& version)  override;
+
+private:
+
+    // Access to this map doesn't need to be locked, since hwservicemanager
+    // is single-threaded.
+    std::multimap<std::string, std::unique_ptr<HidlService>> mServiceMap;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace manager
+}  // namespace hidl
+}  // namespace android
+
+#endif  // HIDL_GENERATED_android_hardware_manager_V1_0_ServiceManager_H_
diff --git a/hw_service_manager.cpp b/hw_service_manager.cpp
deleted file mode 100644
index 98a8a20..0000000
--- a/hw_service_manager.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "hwservicemanager"
-#include <utils/Log.h>
-
-#include <map>
-
-#include <inttypes.h>
-#include <unistd.h>
-
-#include <cutils/properties.h>
-#include <hidl/IServiceManager.h>
-#include <hidl/Status.h>
-#include <hwbinder/IInterface.h>
-#include <hwbinder/IPCThreadState.h>
-#include <hwbinder/ProcessState.h>
-#include <utils/Errors.h>
-#include <utils/Looper.h>
-#include <utils/StrongPointer.h>
-
-// libutils:
-using android::BAD_TYPE;
-using android::Looper;
-using android::LooperCallback;
-using android::OK;
-using android::sp;
-using android::status_t;
-using android::String16;
-
-// libbinder:
-using android::hardware::BBinder;
-using android::hardware::BnInterface;
-using android::hardware::defaultServiceManager;
-using android::hardware::IBinder;
-using android::hardware::IInterface;
-using android::hardware::IPCThreadState;
-using android::hardware::Parcel;
-using android::hardware::ProcessState;
-using android::hardware::Status;
-using android::hardware::hidl_version;
-
-// Standard library
-using std::multimap;
-using std::string;
-using std::unique_ptr;
-using std::vector;
-
-// Service manager definition
-using android::hardware::IServiceManager;
-using android::hardware::IHwServiceManager;
-
-namespace {
-
-class BinderCallback : public LooperCallback {
- public:
-  BinderCallback() {}
-  ~BinderCallback() override {}
-
-  int handleEvent(int /* fd */, int /* events */, void* /* data */) override {
-    IPCThreadState::self()->handlePolledCommands();
-    return 1;  // Continue receiving callbacks.
-  }
-};
-
-class HidlService {
-  public:
-      HidlService(const string &name, const sp<IBinder>& service, const hidl_version& version,
-                  const string &metaVersion) : mName(name), mVersion(version),
-                                                 mMetaVersion(metaVersion), mService(service) {
-      }
-      sp<IBinder> getService() {
-          return mService;
-      }
-      void setService(const sp<IBinder>& service) {
-          mService = service;
-      }
-
-      hidl_version& getVersion() {
-          return mVersion;
-      }
-
-      bool supportsVersion(hidl_version version) {
-          if (version.get_major() == mVersion.get_major() &&
-                  version.get_minor() <= mVersion.get_minor()) {
-              return true;
-          }
-          ALOGE("Service doesn't support version %u.%u", version.get_major(), version.get_minor());
-          return false;
-      }
-  private:
-      string                           mName;        // Service name
-      hidl_version                     mVersion;     // Supported interface version
-      string                           mMetaVersion; // Meta-version of the HIDL interface
-      sp<IBinder>                      mService;     // Binder handle to service
-
-};
-
-class HwServiceManager : public BnInterface<IServiceManager, IHwServiceManager> {
-  public:
-    // Access to this map doesn't need to be locked, since hwservicemanager
-    // is single-threaded.
-    multimap<string, unique_ptr<HidlService>> mServiceMap;
-
-    HwServiceManager() : BnInterface<IServiceManager, IHwServiceManager>(
-            sp<IServiceManager>(this)) {
-
-    }
-
-    /*
-     **************************************************************************
-     IServiceManager methods
-     **************************************************************************
-    */
-
-    /**
-     * getService() is an interface not used on the server-side; it's used
-     * on the client-side to block on calling checkService().
-     */
-    virtual sp<IBinder>         getService( const String16& name,
-                                            const hidl_version& version) const {
-        return checkService(name, version);
-    }
-
-    virtual sp<IBinder>         checkService( const String16& name,
-                                              const hidl_version& version) const {
-        const string name_str = String16::std_string(name);
-        auto numEntries = mServiceMap.count(name_str);
-        auto service_iter = mServiceMap.find(name_str);
-
-        while (numEntries > 0) {
-            if (service_iter->second->supportsVersion(version)) {
-                return service_iter->second->getService();
-            }
-            --numEntries;
-            ++service_iter;
-        }
-        return nullptr;
-    }
-
-    /**
-     * Register a service.
-     */
-    virtual status_t            addService( const String16& name,
-                                            const sp<IBinder>& service,
-                                            const hidl_version& version,
-                                            bool /*allowIsolated = false*/) {
-        const string name_str = String16::std_string(name);
-        auto numEntries = mServiceMap.count(name_str);
-        auto service_iter = mServiceMap.find(name_str);
-        bool replaced = false;
-        while (numEntries > 0) {
-            if (service_iter->second->getVersion() == version) {
-                // Just update service reference
-                service_iter->second->setService(service);
-                replaced = true;
-                break;
-            }
-            --numEntries;
-            ++service_iter;
-        }
-        if (!replaced) {
-            mServiceMap.insert({name_str, unique_ptr<HidlService>(
-                    new HidlService(name_str, service, version, ""))});
-        }
-
-        // TODO link to death so we know when it dies
-        return OK;
-    }
-    /*
-     **************************************************************************
-     BnInterface methods
-     **************************************************************************
-    */
-
-    virtual status_t onTransact(uint32_t code, const Parcel& parcel_in, Parcel* parcel_out,
-                                uint32_t flags, TransactCallback callback) {
-        status_t ret_status = OK;
-        switch (code) {
-            case GET_SERVICE_TRANSACTION:
-            {
-                String16 serviceName;
-                hidl_version *version;
-                if (!(parcel_in.checkInterface(this))) {
-                    ret_status = BAD_TYPE;
-                    break;
-                }
-                ret_status = parcel_in.readString16(&serviceName);
-                if (ret_status != OK) {
-                    break;
-                }
-                version = hidl_version::readFromParcel(parcel_in);
-                if (version == nullptr) {
-                    break;
-                }
-                // TODO SELinux access control
-                sp<IBinder> service = getService(serviceName, *version);
-                ret_status = parcel_out->writeStrongBinder(service);
-                if (ret_status != OK) {
-                    break;
-                } else if (callback != nullptr) {
-                    callback(*parcel_out);
-                }
-                break;
-            }
-            case CHECK_SERVICE_TRANSACTION:
-            {
-                String16 serviceName;
-                hidl_version *version;
-                if (!(parcel_in.checkInterface(this))) {
-                    ret_status = BAD_TYPE;
-                    break;
-                }
-                ret_status = parcel_in.readString16(&serviceName);
-                if (ret_status != OK) {
-                    break;
-                }
-                version = hidl_version::readFromParcel(parcel_in);
-                if (version == nullptr) {
-                    break;
-                }
-                // TODO SELinux access control
-                sp<IBinder> service = getService(serviceName, *version);
-                ret_status = parcel_out->writeStrongBinder(service);
-                if (ret_status != OK) {
-                    break;
-                } else if (callback != nullptr) {
-                    callback(*parcel_out);
-                }
-                break;
-            }
-            case ADD_SERVICE_TRANSACTION:
-            {
-                String16 serviceName;
-                sp<IBinder> service;
-                hidl_version *version;
-                if (!(parcel_in.checkInterface(this))) {
-                    ret_status = BAD_TYPE;
-                    break;
-                }
-                ret_status = parcel_in.readString16(&serviceName);
-                if (ret_status != OK) {
-                    break;
-                }
-                ret_status = parcel_in.readStrongBinder(&service);
-                if (ret_status != OK) {
-                    break;
-                }
-                version = hidl_version::readFromParcel(parcel_in);
-                if (version == nullptr) {
-                    break;
-                }
-                // TODO need isolation param?
-                // TODO SELinux access control
-                ret_status = addService(serviceName, service, *version, false);
-                parcel_out->writeInt32(ret_status);
-                if (ret_status != OK) {
-                    break;
-                } else if (callback != nullptr) {
-                    callback(*parcel_out);
-                }
-                break;
-            }
-            default:
-            {
-                ret_status = BBinder::onTransact(code, parcel_in, parcel_out, flags, callback);
-                break;
-            }
-        }
-
-        return ret_status;
-    }
-};
-
-int Run() {
-  android::sp<HwServiceManager> service = new HwServiceManager();
-  sp<Looper> looper(Looper::prepare(0 /* opts */));
-
-  int binder_fd = -1;
-
-  IPCThreadState::self()->setupPolling(&binder_fd);
-  if (binder_fd < 0) {
-    ALOGE("Failed to aquire binder FD; staying around but doing nothing");
-    // hwservicemanager is a critical service; until support for /dev/hwbinder
-    // is checked in for all devices, prevent it from exiting; if it were to
-    // exit, it would get restarted again and fail again several times,
-    // eventually causing the device to boot into recovery mode.
-    // TODO: revert
-    while (true) {
-      sleep(UINT_MAX);
-    }
-    return -1;
-  }
-
-  sp<BinderCallback> cb(new BinderCallback);
-  if (looper->addFd(binder_fd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, cb,
-                    nullptr) != 1) {
-    ALOGE("Failed to add binder FD to Looper");
-    return -1;
-  }
-
-  // Tell IPCThreadState we're the service manager
-  IPCThreadState::self()->setTheContextObject(service);
-  // Then tell binder kernel
-  ioctl(binder_fd, BINDER_SET_CONTEXT_MGR, 0);
-
-  int rc = property_set("hwservicemanager.ready", "true");
-  if (rc) {
-    ALOGE("Failed to set \"hwservicemanager.ready\" (error %d). "\
-          "HAL services will not launch!\n", rc);
-  }
-
-  while (true) {
-    looper->pollAll(-1 /* timeoutMillis */);
-  }
-
-  return 0;
-}
-
-} // namespace
-
-int main(int /* argc */, char* /* argv */ []) {
-    return Run();
-}
diff --git a/hwservicemanager.rc b/hwservicemanager.rc
new file mode 100644
index 0000000..60af172
--- /dev/null
+++ b/hwservicemanager.rc
@@ -0,0 +1,9 @@
+service hwservicemanager /system/bin/hwservicemanager
+    user system
+    disabled
+    group system readproc
+    critical
+    writepid /dev/cpuset/system-background/tasks
+
+on property:hwservicemanager.ready=true
+    class_start hal
\ No newline at end of file
diff --git a/service.cpp b/service.cpp
new file mode 100644
index 0000000..b03353e
--- /dev/null
+++ b/service.cpp
@@ -0,0 +1,109 @@
+#define LOG_TAG "android.hardware.manager@1.0-service"
+
+#include <utils/Log.h>
+
+#include <inttypes.h>
+#include <unistd.h>
+
+#include <android/hidl/manager/1.0/BnServiceManager.h>
+#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <cutils/properties.h>
+#include <hidl/Status.h>
+#include <hwbinder/IPCThreadState.h>
+#include <hwbinder/ProcessState.h>
+#include <utils/Errors.h>
+#include <utils/Looper.h>
+#include <utils/StrongPointer.h>
+
+#include "ServiceManager.h"
+
+// libutils:
+using android::BAD_TYPE;
+using android::Looper;
+using android::LooperCallback;
+using android::OK;
+using android::sp;
+using android::status_t;
+
+// libhwbinder:
+using android::hardware::IPCThreadState;
+using android::hardware::ProcessState;
+
+// libhidl
+using android::hardware::hidl_string;
+
+// android.hardware.manager@1.0
+using android::hidl::manager::V1_0::BnServiceManager;
+using android::hidl::manager::V1_0::IServiceManager;
+using Version = android::hidl::manager::V1_0::IServiceManager::Version;
+
+// android.hardware.manager@1.0-service
+using android::hidl::manager::V1_0::implementation::ServiceManager;
+
+static std::string serviceName = "manager";
+
+class BinderCallback : public LooperCallback {
+public:
+    BinderCallback() {}
+    ~BinderCallback() override {}
+
+    int handleEvent(int /* fd */, int /* events */, void* /* data */) override {
+        IPCThreadState::self()->handlePolledCommands();
+        return 1;  // Continue receiving callbacks.
+    }
+};
+
+int main() {
+    ServiceManager *manager = new ServiceManager();
+    sp<BnServiceManager> service = new BnServiceManager(manager);
+
+    hidl_string name;
+    name.setToExternal(serviceName.c_str(), serviceName.size());
+    Version version {
+        .major = IServiceManager::version.get_major(),
+        .minor = IServiceManager::version.get_minor(),
+    };
+    manager->add(name, service, version);
+
+    sp<Looper> looper(Looper::prepare(0 /* opts */));
+
+    int binder_fd = -1;
+
+    IPCThreadState::self()->setupPolling(&binder_fd);
+    if (binder_fd < 0) {
+        ALOGE("Failed to aquire binder FD; staying around but doing nothing");
+        // hwservicemanager is a critical service; until support for /dev/hwbinder
+        // is checked in for all devices, prevent it from exiting; if it were to
+        // exit, it would get restarted again and fail again several times,
+        // eventually causing the device to boot into recovery mode.
+        // TODO: revert
+        while (true) {
+          sleep(UINT_MAX);
+        }
+        return -1;
+    }
+
+    sp<BinderCallback> cb(new BinderCallback);
+    if (looper->addFd(binder_fd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, cb,
+                    nullptr) != 1) {
+    ALOGE("Failed to add binder FD to Looper");
+    return -1;
+    }
+
+    // Tell IPCThreadState we're the service manager
+    IPCThreadState::self()->setTheContextObject(service);
+    // Then tell binder kernel
+    ioctl(binder_fd, BINDER_SET_CONTEXT_MGR, 0);
+
+    int rc = property_set("hwservicemanager.ready", "true");
+    if (rc) {
+    ALOGE("Failed to set \"hwservicemanager.ready\" (error %d). "\
+          "HAL services will not launch!\n", rc);
+    }
+
+    while (true) {
+        looper->pollAll(-1 /* timeoutMillis */);
+    }
+
+    return 0;
+}
\ No newline at end of file