Add lookupOrCreateWeak to ObjectManager

This looks for an attached object on the binder, attempts to promote it,
and returns the object if it could be promoted.
Otherwise, it will create a new object and attach it to the binder.

Test: atest binderUnitTest aidl_integration_test
Bug: 220141324
Change-Id: I2c8baa211300fa3ada50f2b2c93862f8c968be26
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index b6d35ef..d9b7231 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -100,6 +100,36 @@
     return value;
 }
 
+namespace {
+struct Tag {
+    wp<IBinder> binder;
+};
+} // namespace
+
+static void cleanWeak(const void* /* id */, void* obj, void* /* cookie */) {
+    delete static_cast<Tag*>(obj);
+}
+
+sp<IBinder> BpBinder::ObjectManager::lookupOrCreateWeak(const void* objectID, object_make_func make,
+                                                        const void* makeArgs) {
+    entry_t& e = mObjects[objectID];
+    if (e.object != nullptr) {
+        if (auto attached = static_cast<Tag*>(e.object)->binder.promote()) {
+            return attached;
+        }
+    } else {
+        e.object = new Tag;
+        LOG_ALWAYS_FATAL_IF(!e.object, "no more memory");
+    }
+    sp<IBinder> newObj = make(makeArgs);
+
+    static_cast<Tag*>(e.object)->binder = newObj;
+    e.cleanupCookie = nullptr;
+    e.func = cleanWeak;
+
+    return newObj;
+}
+
 void BpBinder::ObjectManager::kill()
 {
     const size_t N = mObjects.size();
@@ -516,6 +546,12 @@
     doWithLock();
 }
 
+sp<IBinder> BpBinder::lookupOrCreateWeak(const void* objectID, object_make_func make,
+                                         const void* makeArgs) {
+    AutoMutex _l(mLock);
+    return mObjects.lookupOrCreateWeak(objectID, make, makeArgs);
+}
+
 BpBinder* BpBinder::remoteBinder()
 {
     return this;