diff --git a/AccessControl.cpp b/AccessControl.cpp
index 985feb7..0c73dc6 100644
--- a/AccessControl.cpp
+++ b/AccessControl.cpp
@@ -22,7 +22,7 @@
 
 AccessControl::AccessControl() {
     mSeHandle = selinux_android_hw_service_context_handle();
-    LOG_ALWAYS_FATAL_IF(mSeHandle == NULL, "Failed to acquire SELinux handle.");
+    LOG_ALWAYS_FATAL_IF(mSeHandle == nullptr, "Failed to acquire SELinux handle.");
 
     if (getcon(&mSeContext) != 0) {
         LOG_ALWAYS_FATAL("Failed to acquire hwservicemanager context.");
@@ -38,9 +38,9 @@
 }
 
 bool AccessControl::canAdd(const std::string& fqName, const Context &context, pid_t pid) {
-    FQName fqIface(fqName);
+    FQName fqIface;
 
-    if (!fqIface.isValid()) {
+    if (!FQName::parse(fqName, &fqIface)) {
         return false;
     }
     const std::string checkName = fqIface.package() + "::" + fqIface.name();
@@ -49,9 +49,9 @@
 }
 
 bool AccessControl::canGet(const std::string& fqName, pid_t pid) {
-    FQName fqIface(fqName);
+    FQName fqIface;
 
-    if (!fqIface.isValid()) {
+    if (!FQName::parse(fqName, &fqIface)) {
         return false;
     }
     const std::string checkName = fqIface.package() + "::" + fqIface.name();
@@ -64,7 +64,7 @@
 }
 
 Context AccessControl::getContext(pid_t sourcePid) {
-    char *sourceContext = NULL;
+    char *sourceContext = nullptr;
 
     if (getpidcon(sourcePid, &sourceContext) < 0) {
         ALOGE("SELinux: failed to retrieve process context for pid %d", sourcePid);
@@ -92,7 +92,7 @@
 }
 
 bool AccessControl::checkPermission(const Context &context, pid_t sourceAuditPid, const char *perm, const char *interface) {
-    char *targetContext = NULL;
+    char *targetContext = nullptr;
     bool allowed = false;
 
     // Lookup service in hwservice_contexts
diff --git a/HidlService.cpp b/HidlService.cpp
index a0f2cab..56463aa 100644
--- a/HidlService.cpp
+++ b/HidlService.cpp
@@ -3,8 +3,11 @@
 
 #include <android-base/logging.h>
 #include <hidl/HidlTransportSupport.h>
+#include <hwbinder/BpHwBinder.h>
 #include <sstream>
 
+using ::android::hardware::interfacesEqual;
+
 namespace android {
 namespace hidl {
 namespace manager {
@@ -28,6 +31,8 @@
     mService = service;
     mPid = pid;
 
+    mClientCallbacks.clear();
+
     sendRegistrationNotifications();
 }
 
@@ -56,8 +61,6 @@
 }
 
 bool HidlService::removeListener(const wp<IBase>& listener) {
-    using ::android::hardware::interfacesEqual;
-
     bool found = false;
 
     for (auto it = mListeners.begin(); it != mListeners.end();) {
@@ -80,6 +83,61 @@
     return mPassthroughClients;
 }
 
+void HidlService::addClientCallback(const sp<IClientCallback>& callback) {
+    mClientCallbacks.push_back(callback);
+}
+
+bool HidlService::removeClientCallback(const sp<IClientCallback>& callback) {
+    bool found = false;
+
+    for (auto it = mClientCallbacks.begin(); it != mClientCallbacks.end();) {
+        if (interfacesEqual(*it, callback)) {
+            it = mClientCallbacks.erase(it);
+            found = true;
+        } else {
+            ++it;
+        }
+    }
+
+    return found;
+}
+
+void HidlService::handleClientCallbacks() {
+    using ::android::hardware::toBinder;
+    using ::android::hardware::BpHwBinder;
+    using ::android::hardware::IBinder;
+
+    if (mClientCallbacks.empty()) return;
+    if (mService == nullptr) return;
+
+    // this justifies the bp cast below, no in-process HALs need this
+    if (!mService->isRemote()) return;
+
+    sp<IBinder> binder = toBinder(mService);
+    if (binder == nullptr) return;
+
+    sp<BpHwBinder> bpBinder = static_cast<BpHwBinder*>(binder.get());
+    ssize_t count = bpBinder->getNodeStrongRefCount();
+
+    // binder driver doesn't support this feature
+    if (count == -1) return;
+
+    bool hasClients = count > 1; // this process holds a strong count
+
+    if (hasClients != mHasClients) {
+        LOG(INFO) << "Notifying " << string() << " they have clients: " << hasClients;
+
+        for (const auto& cb : mClientCallbacks) {
+            Return<void> ret = cb->onClients(getService(), hasClients);
+            if (!ret.isOk()) {
+                LOG(WARNING) << "onClients callback failed for " << string() << ": " << ret.description();
+            }
+        }
+    }
+
+    mHasClients = hasClients;
+}
+
 std::string HidlService::string() const {
     std::stringstream ss;
     ss << mInterfaceName << "/" << mInstanceName;
diff --git a/HidlService.h b/HidlService.h
index 2fcb0d6..96a8aa9 100644
--- a/HidlService.h
+++ b/HidlService.h
@@ -3,7 +3,7 @@
 
 #include <set>
 
-#include <android/hidl/manager/1.1/IServiceManager.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
 #include <hidl/Status.h>
 #include <hidl/MQDescriptor.h>
 
@@ -19,6 +19,7 @@
 using ::android::hidl::base::V1_0::IBase;
 using ::android::hidl::manager::V1_0::IServiceNotification;
 using ::android::hidl::manager::V1_1::IServiceManager;
+using ::android::hidl::manager::V1_2::IClientCallback;
 using ::android::sp;
 
 struct HidlService {
@@ -49,6 +50,10 @@
     bool removeListener(const wp<IBase> &listener);
     void registerPassthroughClient(pid_t pid);
 
+    void addClientCallback(const sp<IClientCallback>& callback);
+    bool removeClientCallback(const sp<IClientCallback>& callback);
+    void handleClientCallbacks();
+
     std::string string() const; // e.x. "android.hidl.manager@1.0::IServiceManager/manager"
     const std::set<pid_t> &getPassthroughClients() const;
 
@@ -62,6 +67,9 @@
     std::vector<sp<IServiceNotification>> mListeners{};
     std::set<pid_t>                       mPassthroughClients{};
     pid_t                                 mPid = static_cast<pid_t>(IServiceManager::PidConstant::NO_PID);
+
+    std::vector<sp<IClientCallback>>      mClientCallbacks{};
+    bool                                  mHasClients = false; // notifications sent on true -> false.
 };
 
 }  // namespace implementation
diff --git a/ServiceManager.cpp b/ServiceManager.cpp
index 3e2353e..94bb7c6 100644
--- a/ServiceManager.cpp
+++ b/ServiceManager.cpp
@@ -13,6 +13,7 @@
 #include <thread>
 
 using android::hardware::IPCThreadState;
+using ::android::hardware::interfacesEqual;
 
 namespace android {
 namespace hidl {
@@ -22,45 +23,82 @@
 static constexpr uint64_t kServiceDiedCookie = 0;
 static constexpr uint64_t kPackageListenerDiedCookie = 1;
 static constexpr uint64_t kServiceListenerDiedCookie = 2;
+static constexpr uint64_t kClientCallbackDiedCookie = 3;
 
 size_t ServiceManager::countExistingService() const {
     size_t total = 0;
     forEachExistingService([&] (const HidlService *) {
         ++total;
+        return true;  // continue
     });
     return total;
 }
 
-void ServiceManager::forEachExistingService(std::function<void(const HidlService *)> f) const {
-    forEachServiceEntry([f] (const HidlService *service) {
+void ServiceManager::forEachExistingService(std::function<bool(const HidlService *)> f) const {
+    forEachServiceEntry([&] (const HidlService *service) {
         if (service->getService() == nullptr) {
-            return;
+            return true;  // continue
         }
-        f(service);
+        return f(service);
     });
 }
 
-void ServiceManager::forEachServiceEntry(std::function<void(const HidlService *)> f) const {
-    for (const auto &interfaceMapping : mServiceMap) {
-        const auto &instanceMap = interfaceMapping.second.getInstanceMap();
+void ServiceManager::forEachExistingService(std::function<bool(HidlService *)> f) {
+    forEachServiceEntry([&] (HidlService *service) {
+        if (service->getService() == nullptr) {
+            return true;  // continue
+        }
+        return f(service);
+    });
+}
 
-        for (const auto &instanceMapping : instanceMap) {
-            f(instanceMapping.second.get());
+void ServiceManager::forEachServiceEntry(std::function<bool(const HidlService *)> f) const {
+    for (const auto& interfaceMapping : mServiceMap) {
+        const auto& instanceMap = interfaceMapping.second.getInstanceMap();
+
+        for (const auto& instanceMapping : instanceMap) {
+            if (!f(instanceMapping.second.get())) {
+                return;
+            }
+        }
+    }
+}
+
+void ServiceManager::forEachServiceEntry(std::function<bool(HidlService *)> f) {
+    for (auto& interfaceMapping : mServiceMap) {
+        auto& instanceMap = interfaceMapping.second.getInstanceMap();
+
+        for (auto& instanceMapping : instanceMap) {
+            if (!f(instanceMapping.second.get())) {
+                return;
+            }
         }
     }
 }
 
 void ServiceManager::serviceDied(uint64_t cookie, const wp<IBase>& who) {
+    bool serviceRemoved = false;
     switch (cookie) {
         case kServiceDiedCookie:
-            removeService(who, nullptr /* restrictToInstanceName */);
+            serviceRemoved = removeService(who, nullptr /* restrictToInstanceName */);
             break;
         case kPackageListenerDiedCookie:
-            removePackageListener(who);
+            serviceRemoved = removePackageListener(who);
             break;
         case kServiceListenerDiedCookie:
-            removeServiceListener(who);
+            serviceRemoved = removeServiceListener(who);
             break;
+        case kClientCallbackDiedCookie: {
+            sp<IBase> base = who.promote();
+            IClientCallback* callback = static_cast<IClientCallback*>(base.get());
+            serviceRemoved = unregisterClientCallback(nullptr /*service*/,
+                                                      sp<IClientCallback>(callback));
+        } break;
+    }
+
+    if (!serviceRemoved) {
+        LOG(ERROR) << "Received death notification but interface instance not removed. Cookie: "
+                   << cookie << " Service pointer: " << who.promote().get();
     }
 }
 
@@ -134,8 +172,6 @@
 }
 
 bool ServiceManager::PackageInterfaceMap::removePackageListener(const wp<IBase>& who) {
-    using ::android::hardware::interfacesEqual;
-
     bool found = false;
 
     for (auto it = mPackageListeners.begin(); it != mPackageListeners.end();) {
@@ -151,8 +187,6 @@
 }
 
 bool ServiceManager::PackageInterfaceMap::removeServiceListener(const wp<IBase>& who) {
-    using ::android::hardware::interfacesEqual;
-
     bool found = false;
 
     for (auto &servicePair : getInstanceMap()) {
@@ -192,8 +226,10 @@
         return nullptr;
     }
 
-    const PackageInterfaceMap &ifaceMap = ifaceIt->second;
-    const HidlService *hidlService = ifaceMap.lookup(name);
+    PackageInterfaceMap &ifaceMap = ifaceIt->second;
+
+    // may be modified in post-command task
+    HidlService *hidlService = ifaceMap.lookup(name);
 
     if (hidlService == nullptr) {
         tryStartService(fqName, hidlName);
@@ -206,85 +242,101 @@
         return nullptr;
     }
 
+    // This is executed immediately after the binder driver confirms the transaction. The driver
+    // will update the appropriate data structures to reflect the fact that the client now has the
+    // service this function is returning. Nothing else can update the HidlService at the same
+    // time. This will run before anything else can modify the HidlService which is owned by this
+    // object, so it will be in the same state that it was when this function returns.
+    hardware::addPostCommandTask([hidlService] {
+        hidlService->handleClientCallbacks();
+    });
+
     return service;
 }
 
 Return<bool> ServiceManager::add(const hidl_string& name, const sp<IBase>& service) {
-    bool isValidService = false;
+    bool addSuccess = false;
 
     if (service == nullptr) {
         return false;
     }
 
-    // TODO(b/34235311): use HIDL way to determine this
-    // also, this assumes that the PID that is registering is the pid that is the service
     pid_t pid = IPCThreadState::self()->getCallingPid();
     auto context = mAcl.getContext(pid);
 
     auto ret = service->interfaceChain([&](const auto &interfaceChain) {
-        if (interfaceChain.size() == 0) {
-            return;
-        }
-
-        // First, verify you're allowed to add() the whole interface hierarchy
-        for(size_t i = 0; i < interfaceChain.size(); i++) {
-            const std::string fqName = interfaceChain[i];
-
-            if (!mAcl.canAdd(fqName, context, pid)) {
-                return;
-            }
-        }
-
-        {
-            // For IBar extends IFoo if IFoo/default is being registered, remove
-            // IBar/default. This makes sure the following two things are equivalent
-            // 1). IBar::castFrom(IFoo::getService(X))
-            // 2). IBar::getService(X)
-            // assuming that IBar is declared in the device manifest and there
-            // is also not an IBaz extends IFoo.
-            const std::string childFqName = interfaceChain[0];
-            const PackageInterfaceMap &ifaceMap = mServiceMap[childFqName];
-            const HidlService *hidlService = ifaceMap.lookup(name);
-            if (hidlService != nullptr) {
-                const sp<IBase> remove = hidlService->getService();
-
-                if (remove != nullptr) {
-                    const std::string instanceName = name;
-                    removeService(remove, &instanceName /* restrictToInstanceName */);
-                }
-            }
-        }
-
-        for(size_t i = 0; i < interfaceChain.size(); i++) {
-            const std::string fqName = interfaceChain[i];
-
-            PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
-            HidlService *hidlService = ifaceMap.lookup(name);
-
-            if (hidlService == nullptr) {
-                ifaceMap.insertService(
-                    std::make_unique<HidlService>(fqName, name, service, pid));
-            } else {
-                hidlService->setService(service, pid);
-            }
-
-            ifaceMap.sendPackageRegistrationNotification(fqName, name);
-        }
-
-        bool linkRet = service->linkToDeath(this, kServiceDiedCookie).withDefault(false);
-        if (!linkRet) {
-            LOG(ERROR) << "Could not link to death for " << interfaceChain[0] << "/" << name;
-        }
-
-        isValidService = true;
+        addSuccess = addImpl(name, service, interfaceChain, context, pid);
     });
 
     if (!ret.isOk()) {
-        LOG(ERROR) << "Failed to retrieve interface chain.";
+        LOG(ERROR) << "Failed to retrieve interface chain: " << ret.description();
         return false;
     }
 
-    return isValidService;
+    return addSuccess;
+}
+
+bool ServiceManager::addImpl(const hidl_string& name,
+                             const sp<IBase>& service,
+                             const hidl_vec<hidl_string>& interfaceChain,
+                             const AccessControl::Context &context,
+                             pid_t pid) {
+    if (interfaceChain.size() == 0) {
+        LOG(WARNING) << "Empty interface chain for " << name;
+        return false;
+    }
+
+    // First, verify you're allowed to add() the whole interface hierarchy
+    for(size_t i = 0; i < interfaceChain.size(); i++) {
+        const std::string fqName = interfaceChain[i];
+
+        if (!mAcl.canAdd(fqName, context, pid)) {
+            return false;
+        }
+    }
+
+    {
+        // For IBar extends IFoo if IFoo/default is being registered, remove
+        // IBar/default. This makes sure the following two things are equivalent
+        // 1). IBar::castFrom(IFoo::getService(X))
+        // 2). IBar::getService(X)
+        // assuming that IBar is declared in the device manifest and there
+        // is also not an IBaz extends IFoo.
+        const std::string childFqName = interfaceChain[0];
+        const PackageInterfaceMap &ifaceMap = mServiceMap[childFqName];
+        const HidlService *hidlService = ifaceMap.lookup(name);
+        if (hidlService != nullptr) {
+            const sp<IBase> remove = hidlService->getService();
+
+            if (remove != nullptr) {
+                const std::string instanceName = name;
+                removeService(remove, &instanceName /* restrictToInstanceName */);
+            }
+        }
+    }
+
+    for(size_t i = 0; i < interfaceChain.size(); i++) {
+        const std::string fqName = interfaceChain[i];
+
+        PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
+        HidlService *hidlService = ifaceMap.lookup(name);
+
+        if (hidlService == nullptr) {
+            ifaceMap.insertService(
+                std::make_unique<HidlService>(fqName, name, service, pid));
+        } else {
+            hidlService->setService(service, pid);
+        }
+
+        ifaceMap.sendPackageRegistrationNotification(fqName, name);
+    }
+
+    bool linkRet = service->linkToDeath(this, kServiceDiedCookie).withDefault(false);
+    if (!linkRet) {
+        LOG(ERROR) << "Could not link to death for " << interfaceChain[0] << "/" << name;
+    }
+
+    return true;
 }
 
 Return<ServiceManager::Transport> ServiceManager::getTransport(const hidl_string& fqName,
@@ -321,6 +373,7 @@
     size_t idx = 0;
     forEachExistingService([&] (const HidlService *service) {
         list[idx++] = service->string();
+        return true;  // continue
     });
 
     _hidl_cb(list);
@@ -381,8 +434,8 @@
     PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
 
     if (name.empty()) {
-        auto ret = callback->linkToDeath(this, kPackageListenerDiedCookie);
-        if (!ret.isOk()) {
+        bool ret = callback->linkToDeath(this, kPackageListenerDiedCookie).withDefault(false);
+        if (!ret) {
             LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name;
             return false;
         }
@@ -392,8 +445,8 @@
 
     HidlService *service = ifaceMap.lookup(name);
 
-    auto ret = callback->linkToDeath(this, kServiceListenerDiedCookie);
-    if (!ret.isOk()) {
+    bool ret = callback->linkToDeath(this, kServiceListenerDiedCookie).withDefault(false);
+    if (!ret) {
         LOG(ERROR) << "Failed to register death recipient for " << fqName << "/" << name;
         return false;
     }
@@ -445,6 +498,80 @@
     return service->removeListener(callback);
 }
 
+Return<bool> ServiceManager::registerClientCallback(const sp<IBase>& server,
+                                                    const sp<IClientCallback>& cb) {
+    if (server == nullptr || cb == nullptr) return false;
+
+    // only the server of the interface can register a client callback
+    pid_t pid = IPCThreadState::self()->getCallingPid();
+
+    HidlService* registered = nullptr;
+
+    forEachExistingService([&] (HidlService *service) {
+        if (service->getPid() != pid) {
+            return true;  // continue
+        }
+
+        if (interfacesEqual(service->getService(), server)) {
+            service->addClientCallback(cb);
+            registered = service;
+            return false;  // break
+        }
+        return true;  // continue
+    });
+
+    if (registered != nullptr) {
+        bool linkRet = cb->linkToDeath(this, kClientCallbackDiedCookie).withDefault(false);
+        if (!linkRet) {
+            LOG(ERROR) << "Could not link to death for registerClientCallback";
+            unregisterClientCallback(server, cb);
+            registered = nullptr;
+        }
+    }
+
+    if (registered != nullptr) {
+        registered->handleClientCallbacks();
+    }
+
+    return registered != nullptr;
+}
+
+Return<bool> ServiceManager::unregisterClientCallback(const sp<IBase>& server,
+                                                      const sp<IClientCallback>& cb) {
+    if (cb == nullptr) return false;
+
+    bool removed = false;
+
+    forEachExistingService([&] (HidlService *service) {
+        if (server == nullptr || interfacesEqual(service->getService(), server)) {
+            removed |= service->removeClientCallback(cb);
+        }
+        return true;  // continue
+    });
+
+    return removed;
+}
+
+void ServiceManager::handleClientCallbacks() {
+    forEachServiceEntry([&] (HidlService *service) {
+        service->handleClientCallbacks();
+        return true;  // continue
+    });
+}
+
+Return<bool> ServiceManager::addWithChain(const hidl_string& name,
+                                          const sp<IBase>& service,
+                                          const hidl_vec<hidl_string>& chain) {
+    if (service == nullptr) {
+        return false;
+    }
+
+    pid_t pid = IPCThreadState::self()->getCallingPid();
+    auto context = mAcl.getContext(pid);
+
+    return addImpl(name, service, chain, context, pid);
+}
+
 Return<void> ServiceManager::debugDump(debugDump_cb _cb) {
     pid_t pid = IPCThreadState::self()->getCallingPid();
     if (!mAcl.canList(pid)) {
@@ -469,6 +596,8 @@
             .clientPids = clientPids,
             .arch = ::android::hidl::base::V1_0::DebugInfo::Architecture::UNKNOWN
         });
+
+        return true;  // continue
     });
 
     _cb(list);
@@ -508,8 +637,6 @@
 }
 
 bool ServiceManager::removeService(const wp<IBase>& who, const std::string* restrictToInstanceName) {
-    using ::android::hardware::interfacesEqual;
-
     bool keepInstance = false;
     bool removed = false;
     for (auto &interfaceMapping : mServiceMap) {
diff --git a/ServiceManager.h b/ServiceManager.h
index 54ecb37..44936d5 100644
--- a/ServiceManager.h
+++ b/ServiceManager.h
@@ -1,7 +1,7 @@
 #ifndef ANDROID_HARDWARE_MANAGER_SERVICEMANAGER_H
 #define ANDROID_HARDWARE_MANAGER_SERVICEMANAGER_H
 
-#include <android/hidl/manager/1.1/IServiceManager.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
 #include <hidl/Status.h>
 #include <hidl/MQDescriptor.h>
 #include <map>
@@ -20,12 +20,12 @@
 using ::android::hardware::Return;
 using ::android::hardware::Void;
 using ::android::hidl::base::V1_0::IBase;
-using ::android::hidl::manager::V1_1::IServiceManager;
 using ::android::hidl::manager::V1_0::IServiceNotification;
+using ::android::hidl::manager::V1_2::IClientCallback;
 using ::android::sp;
 using ::android::wp;
 
-struct ServiceManager : public IServiceManager, hidl_death_recipient {
+struct ServiceManager : public V1_2::IServiceManager, hidl_death_recipient {
     // Methods from ::android::hidl::manager::V1_0::IServiceManager follow.
     Return<sp<IBase>> get(const hidl_string& fqName,
                           const hidl_string& name) override;
@@ -52,16 +52,37 @@
                                             const hidl_string& name,
                                             const sp<IServiceNotification>& callback) override;
 
+    // Methods from ::android::hidl::manager::V1_2::IServiceManager follow.
+    Return<bool> registerClientCallback(const sp<IBase>& server,
+                                        const sp<IClientCallback>& cb) override;
+    Return<bool> unregisterClientCallback(const sp<IBase>& server,
+                                          const sp<IClientCallback>& cb) override;
+    Return<bool> addWithChain(const hidl_string& name,
+                              const sp<IBase>& service,
+                              const hidl_vec<hidl_string>& chain) override;
+
+    void handleClientCallbacks();
+
     virtual void serviceDied(uint64_t cookie, const wp<IBase>& who);
 private:
+    bool addImpl(const hidl_string& name,
+                 const sp<IBase>& service,
+                 const hidl_vec<hidl_string>& interfaceChain,
+                 const AccessControl::Context &context,
+                 pid_t pid);
+
     // if restrictToInstanceName is nullptr, remove all, otherwise only those services
     // which match this instance name. Returns whether all instances were removed.
     bool removeService(const wp<IBase>& who, const std::string* restrictToInstanceName);
     bool removePackageListener(const wp<IBase>& who);
     bool removeServiceListener(const wp<IBase>& who);
     size_t countExistingService() const;
-    void forEachExistingService(std::function<void(const HidlService *)> f) const;
-    void forEachServiceEntry(std::function<void(const HidlService *)> f) const;
+
+    // true = continue, false = break
+    void forEachExistingService(std::function<bool(const HidlService *)> f) const;
+    void forEachExistingService(std::function<bool(HidlService *)> f);
+    void forEachServiceEntry(std::function<bool(const HidlService *)> f) const;
+    void forEachServiceEntry(std::function<bool(HidlService *)> f);
 
     using InstanceMap = std::map<
             std::string, // instance name e.x. "manager"
diff --git a/Vintf.cpp b/Vintf.cpp
index d2d2f00..989adc0 100644
--- a/Vintf.cpp
+++ b/Vintf.cpp
@@ -23,8 +23,9 @@
 }
 
 vintf::Transport getTransport(const std::string &interfaceName, const std::string &instanceName) {
-    FQName fqName(interfaceName);
-    if (!fqName.isValid()) {
+    FQName fqName;
+
+    if (!FQName::parse(interfaceName, &fqName)) {
         LOG(ERROR) << __FUNCTION__ << ": " << interfaceName
                    << " is not a valid fully-qualified name ";
         return vintf::Transport::EMPTY;
diff --git a/service.cpp b/service.cpp
index 17db6bc..5b595b8 100644
--- a/service.cpp
+++ b/service.cpp
@@ -4,10 +4,12 @@
 
 #include <inttypes.h>
 #include <unistd.h>
+#include <sys/timerfd.h>
 
-#include <android/hidl/manager/1.1/BnHwServiceManager.h>
 #include <android/hidl/token/1.0/ITokenManager.h>
 #include <cutils/properties.h>
+#include <hidl/HidlBinderSupport.h>
+#include <hidl/HidlTransportSupport.h>
 #include <hidl/Status.h>
 #include <hwbinder/IPCThreadState.h>
 #include <hwbinder/ProcessState.h>
@@ -20,45 +22,117 @@
 
 // libutils:
 using android::sp;
-using android::status_t;
+using android::Looper;
+using android::LooperCallback;
 
 // libhwbinder:
+using android::hardware::BHwBinder;
+using android::hardware::IBinder;
 using android::hardware::IPCThreadState;
 using android::hardware::ProcessState;
 
 // libhidl
-using android::hardware::configureRpcThreadpool;
-using android::hardware::hidl_string;
-using android::hardware::hidl_vec;
-using android::hardware::joinRpcThreadpool;
-
-// hidl types
-using android::hidl::manager::V1_1::BnHwServiceManager;
-using android::hidl::token::V1_0::ITokenManager;
+using android::hardware::handleTransportPoll;
+using android::hardware::setupTransportPolling;
+using android::hardware::toBinder;
 
 // implementations
 using android::hidl::manager::implementation::ServiceManager;
+using android::hidl::manager::V1_0::IServiceManager;
 using android::hidl::token::V1_0::implementation::TokenManager;
 
 static std::string serviceName = "default";
 
+class HwBinderCallback : public LooperCallback {
+public:
+    static sp<HwBinderCallback> setupTo(const sp<Looper>& looper) {
+        sp<HwBinderCallback> cb = new HwBinderCallback;
+
+        int fdHwBinder = setupTransportPolling();
+        LOG_ALWAYS_FATAL_IF(fdHwBinder < 0, "Failed to setupTransportPolling: %d", fdHwBinder);
+
+        // Flush after setupPolling(), to make sure the binder driver
+        // knows about this thread handling commands.
+        IPCThreadState::self()->flushCommands();
+
+        int ret = looper->addFd(fdHwBinder,
+                                Looper::POLL_CALLBACK,
+                                Looper::EVENT_INPUT,
+                                cb,
+                                nullptr /*data*/);
+        LOG_ALWAYS_FATAL_IF(ret != 1, "Failed to add binder FD to Looper");
+
+        return cb;
+    }
+
+    int handleEvent(int fd, int /*events*/, void* /*data*/) override {
+        handleTransportPoll(fd);
+        return 1;  // Continue receiving callbacks.
+    }
+};
+
+// LooperCallback for IClientCallback
+class ClientCallbackCallback : public LooperCallback {
+public:
+    static sp<ClientCallbackCallback> setupTo(const sp<Looper>& looper, const sp<ServiceManager>& manager) {
+        sp<ClientCallbackCallback> cb = new ClientCallbackCallback(manager);
+
+        int fdTimer = timerfd_create(CLOCK_MONOTONIC, 0 /*flags*/);
+        LOG_ALWAYS_FATAL_IF(fdTimer < 0, "Failed to timerfd_create: fd: %d err: %d", fdTimer, errno);
+
+        itimerspec timespec {
+            .it_interval = {
+                .tv_sec = 5,
+                .tv_nsec = 0,
+            },
+            .it_value = {
+                .tv_sec = 5,
+                .tv_nsec = 0,
+            },
+        };
+
+        int timeRes = timerfd_settime(fdTimer, 0 /*flags*/, &timespec, nullptr);
+        LOG_ALWAYS_FATAL_IF(timeRes < 0, "Failed to timerfd_settime: res: %d err: %d", timeRes, errno);
+
+        int addRes = looper->addFd(fdTimer,
+                                   Looper::POLL_CALLBACK,
+                                   Looper::EVENT_INPUT,
+                                   cb,
+                                   nullptr);
+        LOG_ALWAYS_FATAL_IF(addRes != 1, "Failed to add client callback FD to Looper");
+
+        return cb;
+    }
+
+    int handleEvent(int fd, int /*events*/, void* /*data*/) override {
+        uint64_t expirations;
+        int ret = read(fd, &expirations, sizeof(expirations));
+        if (ret != sizeof(expirations)) {
+            ALOGE("Read failed to callback FD: ret: %d err: %d", ret, errno);
+        }
+
+        mManager->handleClientCallbacks();
+        return 1;  // Continue receiving callbacks.
+    }
+private:
+    ClientCallbackCallback(const sp<ServiceManager>& manager) : mManager(manager) {}
+    sp<ServiceManager> mManager;
+};
+
 int main() {
-    configureRpcThreadpool(1, true /* callerWillJoin */);
-
-    ServiceManager *manager = new ServiceManager();
-
+    sp<ServiceManager> manager = new ServiceManager();
     if (!manager->add(serviceName, manager)) {
         ALOGE("Failed to register hwservicemanager with itself.");
     }
 
-    TokenManager *tokenManager = new TokenManager();
-
+    sp<TokenManager> tokenManager = new TokenManager();
     if (!manager->add(serviceName, tokenManager)) {
         ALOGE("Failed to register ITokenManager with hwservicemanager.");
     }
 
     // Tell IPCThreadState we're the service manager
-    sp<BnHwServiceManager> service = new BnHwServiceManager(manager);
+    sp<IBinder> binder = toBinder<IServiceManager>(manager);
+    sp<BHwBinder> service = static_cast<BHwBinder*>(binder.get()); // local binder object
     IPCThreadState::self()->setTheContextObject(service);
     // Then tell the kernel
     ProcessState::self()->becomeContextManager(nullptr, nullptr);
@@ -69,8 +143,16 @@
               "HAL services will not start!\n", rc);
     }
 
+    sp<Looper> looper = Looper::prepare(0 /* opts */);
+
+    (void)HwBinderCallback::setupTo(looper);
+    (void)ClientCallbackCallback::setupTo(looper, manager);
+
     ALOGI("hwservicemanager is ready now.");
-    joinRpcThreadpool();
+
+    while (true) {
+        looper->pollAll(-1 /* timeoutMillis */);
+    }
 
     return 0;
 }
