Merge "Look up Connection by token"
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 91e89ae..861401c 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -50,7 +50,7 @@
             vintf::VintfObject::GetDeviceHalManifest(),
             vintf::VintfObject::GetFrameworkHalManifest()
         }) {
-        if (manifest->hasAidlInstance(package, iface, instance)) {
+        if (manifest != nullptr && manifest->hasAidlInstance(package, iface, instance)) {
             return true;
         }
     }
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 7219b47..a9f8ae6 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -1449,41 +1449,38 @@
     return err;
 }
 
-status_t Parcel::readByteVectorInternal(int8_t* data, size_t size) const {
-    if (size_t(size) > dataAvail()) {
-      return BAD_VALUE;
-    }
-    return read(data, size);
-}
-
 status_t Parcel::readByteVector(std::vector<int8_t>* val) const {
-    if (status_t status = resizeOutVector(val); status != OK) return status;
-    return readByteVectorInternal(val->data(), val->size());
+    size_t size;
+    if (status_t status = reserveOutVector(val, &size); status != OK) return status;
+    return readByteVectorInternal(val, size);
 }
 
 status_t Parcel::readByteVector(std::vector<uint8_t>* val) const {
-    if (status_t status = resizeOutVector(val); status != OK) return status;
-    return readByteVectorInternal(reinterpret_cast<int8_t*>(val->data()), val->size());
+    size_t size;
+    if (status_t status = reserveOutVector(val, &size); status != OK) return status;
+    return readByteVectorInternal(val, size);
 }
 
 status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const {
-    if (status_t status = resizeOutVector(val); status != OK) return status;
+    size_t size;
+    if (status_t status = reserveOutVector(val, &size); status != OK) return status;
     if (val->get() == nullptr) {
-        // resizeOutVector does not create the out vector if size is < 0.
+        // reserveOutVector does not create the out vector if size is < 0.
         // This occurs when writing a null byte vector.
         return OK;
     }
-    return readByteVectorInternal((*val)->data(), (*val)->size());
+    return readByteVectorInternal(val->get(), size);
 }
 
 status_t Parcel::readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const {
-    if (status_t status = resizeOutVector(val); status != OK) return status;
+    size_t size;
+    if (status_t status = reserveOutVector(val, &size); status != OK) return status;
     if (val->get() == nullptr) {
-        // resizeOutVector does not create the out vector if size is < 0.
+        // reserveOutVector does not create the out vector if size is < 0.
         // This occurs when writing a null byte vector.
         return OK;
     }
-    return readByteVectorInternal(reinterpret_cast<int8_t*>((*val)->data()), (*val)->size());
+    return readByteVectorInternal(val->get(), size);
 }
 
 status_t Parcel::readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const {
diff --git a/libs/binder/fuzzer/Android.bp b/libs/binder/fuzzer/Android.bp
index a9d2b75..521d36f 100644
--- a/libs/binder/fuzzer/Android.bp
+++ b/libs/binder/fuzzer/Android.bp
@@ -2,6 +2,11 @@
     name: "binder_parcel_fuzzer",
     defaults: ["libbinder_ndk_host_user"],
     host_supported: true,
+
+    fuzz_config: {
+        cc: ["smoreland@google.com"],
+    },
+
     srcs: [
         "binder.cpp",
         "binder_ndk.cpp",
diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h
index 4a44c5a..bd77567 100644
--- a/libs/binder/include/binder/IServiceManager.h
+++ b/libs/binder/include/binder/IServiceManager.h
@@ -114,6 +114,13 @@
 }
 
 template<typename INTERFACE>
+sp<INTERFACE> waitForVintfService(
+        const String16& instance = String16("default")) {
+    return waitForDeclaredService<INTERFACE>(
+        INTERFACE::descriptor + String16("/") + instance);
+}
+
+template<typename INTERFACE>
 status_t getService(const String16& name, sp<INTERFACE>* outService)
 {
     const sp<IServiceManager> sm = defaultServiceManager();
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index 0f8abab..d4bb85b 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -356,6 +356,11 @@
     status_t            resizeOutVector(std::vector<T>* val) const;
     template<typename T>
     status_t            resizeOutVector(std::unique_ptr<std::vector<T>>* val) const;
+    template<typename T>
+    status_t            reserveOutVector(std::vector<T>* val, size_t* size) const;
+    template<typename T>
+    status_t            reserveOutVector(std::unique_ptr<std::vector<T>>* val,
+                                         size_t* size) const;
 
     // Like Parcel.java's readExceptionCode().  Reads the first int32
     // off of a Parcel's header, returning 0 or the negative error
@@ -475,7 +480,8 @@
     status_t            readEnum(T* pArg) const;
 
     status_t writeByteVectorInternal(const int8_t* data, size_t size);
-    status_t readByteVectorInternal(int8_t* data, size_t size) const;
+    template<typename T>
+    status_t readByteVectorInternal(std::vector<T>* val, size_t size) const;
 
     template<typename T, typename U>
     status_t            unsafeReadTypedVector(std::vector<T>* val,
@@ -720,6 +726,42 @@
 }
 
 template<typename T>
+status_t Parcel::reserveOutVector(std::vector<T>* val, size_t* size) const {
+    int32_t read_size;
+    status_t err = readInt32(&read_size);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    if (read_size < 0) {
+        return UNEXPECTED_NULL;
+    }
+    *size = static_cast<size_t>(read_size);
+    val->reserve(*size);
+    return OK;
+}
+
+template<typename T>
+status_t Parcel::reserveOutVector(std::unique_ptr<std::vector<T>>* val,
+                                  size_t* size) const {
+    int32_t read_size;
+    status_t err = readInt32(&read_size);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    if (read_size >= 0) {
+        *size = static_cast<size_t>(read_size);
+        val->reset(new std::vector<T>());
+        (*val)->reserve(*size);
+    } else {
+        val->reset();
+    }
+
+    return OK;
+}
+
+template<typename T>
 status_t Parcel::readStrongBinder(sp<T>* val) const {
     sp<IBinder> tmp;
     status_t ret = readStrongBinder(&tmp);
@@ -988,20 +1030,33 @@
     return readInt64(reinterpret_cast<int64_t *>(pArg));
 }
 
+template<typename T>
+inline status_t Parcel::readByteVectorInternal(std::vector<T>* val, size_t size) const {
+  // readByteVectorInternal expects a vector that has been reserved (but not
+  // resized) to have the provided size.
+  const T* data = reinterpret_cast<const T*>(readInplace(size));
+  if (!data) return BAD_VALUE;
+  val->clear();
+  val->insert(val->begin(), data, data+size);
+  return NO_ERROR;
+}
+
 template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
 status_t Parcel::readEnumVector(std::vector<T>* val) const {
-    if (status_t status = resizeOutVector(val); status != OK) return status;
-    return readByteVectorInternal(reinterpret_cast<int8_t*>(val->data()), val->size());
+    size_t size;
+    if (status_t status = reserveOutVector(val, &size); status != OK) return status;
+    return readByteVectorInternal(val, size);
 }
 template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
 status_t Parcel::readEnumVector(std::unique_ptr<std::vector<T>>* val) const {
-    if (status_t status = resizeOutVector(val); status != OK) return status;
+    size_t size;
+    if (status_t status = reserveOutVector(val, &size); status != OK) return status;
     if (val->get() == nullptr) {
-        // resizeOutVector does not create the out vector if size is < 0.
+        // reserveOutVector does not create the out vector if size is < 0.
         // This occurs when writing a null Enum vector.
         return OK;
     }
-    return readByteVectorInternal(reinterpret_cast<int8_t*>((*val)->data()), (*val)->size());
+    return readByteVectorInternal(val->get(), size);
 }
 template<typename T, std::enable_if_t<std::is_enum_v<T> && !std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool>>
 status_t Parcel::readEnumVector(std::vector<T>* val) const {