Merge "libbinder_ndk: clearer error on host misconfigured"
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 616c3b2..f95e445 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -339,6 +339,10 @@
                 ? "dalvik.vm.dex2oat-threads"
                 : "dalvik.vm.boot-dex2oat-threads";
         std::string dex2oat_threads_arg = MapPropertyToArg(threads_property, "-j%s");
+        const char* cpu_set_property = post_bootcomplete
+                ? "dalvik.vm.dex2oat-cpu-set"
+                : "dalvik.vm.boot-dex2oat-cpu-set";
+        std::string dex2oat_cpu_set_arg = MapPropertyToArg(cpu_set_property, "--cpu-set=%s");
 
         std::string bootclasspath;
         char* dex2oat_bootclasspath = getenv("DEX2OATBOOTCLASSPATH");
@@ -518,6 +522,7 @@
         AddArg(image_block_size_arg);
         AddArg(dex2oat_compiler_filter_arg);
         AddArg(dex2oat_threads_arg);
+        AddArg(dex2oat_cpu_set_arg);
         AddArg(dex2oat_swap_fd);
         AddArg(dex2oat_image_fd);
 
diff --git a/cmds/installd/migrate_legacy_obb_data.sh b/cmds/installd/migrate_legacy_obb_data.sh
index 0e6d7b9..7399681 100644
--- a/cmds/installd/migrate_legacy_obb_data.sh
+++ b/cmds/installd/migrate_legacy_obb_data.sh
@@ -15,17 +15,17 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-rm -rf /data/media/Android/obb/test_probe
-mkdir -p /data/media/Android/obb/
-touch /data/media/Android/obb/test_probe
+rm -rf /data/media/0/Android/obb/test_probe
+mkdir -p /data/media/0/Android/obb/
+touch /data/media/0/Android/obb/test_probe
 if ! test -f /data/media/0/Android/obb/test_probe ; then
   log -p i -t migrate_legacy_obb_data "No support for 'unshared_obb'. Not migrating"
-  rm -rf /data/media/Android/obb/test_probe
+  rm -rf /data/media/0/Android/obb/test_probe
   exit 0
 fi
 
 # Delete the test file, and remove the obb folder if it is empty
-rm -rf /data/media/Android/obb/test_probe
+rm -rf /data/media/0/Android/obb/test_probe
 rmdir /data/media/obb
 
 if ! test -d /data/media/obb ; then
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index db36ce3..eefbe4f 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -480,6 +480,10 @@
                 "-j",
                 false,
                 cmd);
+        AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-cpu-set",
+                "--cpu-set=",
+                false,
+                cmd);
         AddCompilerOptionFromSystemProperty(
                 StringPrintf("dalvik.vm.isa.%s.variant", isa).c_str(),
                 "--instruction-set-variant=",
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 861401c..141171b 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -68,7 +68,15 @@
 }
 #endif  // !VENDORSERVICEMANAGER
 
-ServiceManager::ServiceManager(std::unique_ptr<Access>&& access) : mAccess(std::move(access)) {}
+ServiceManager::ServiceManager(std::unique_ptr<Access>&& access) : mAccess(std::move(access)) {
+#ifndef VENDORSERVICEMANAGER
+    // can process these at any times, don't want to delay first VINTF client
+    std::thread([] {
+        vintf::VintfObject::GetDeviceHalManifest();
+        vintf::VintfObject::GetFrameworkHalManifest();
+    }).detach();
+#endif  // !VENDORSERVICEMANAGER
+}
 ServiceManager::~ServiceManager() {
     // this should only happen in tests
 
@@ -306,7 +314,7 @@
     if (listeners.empty()) {
         *it = mNameToCallback.erase(*it);
     } else {
-        it++;
+        (*it)++;
     }
 }
 
diff --git a/libs/binder/Status.cpp b/libs/binder/Status.cpp
index 0ad99ce..674f065 100644
--- a/libs/binder/Status.cpp
+++ b/libs/binder/Status.cpp
@@ -232,9 +232,10 @@
         ret.append("No error");
     } else {
         ret.appendFormat("Status(%d, %s): '", mException, exceptionToString(mException).c_str());
-        if (mException == EX_SERVICE_SPECIFIC ||
-            mException == EX_TRANSACTION_FAILED) {
+        if (mException == EX_SERVICE_SPECIFIC) {
             ret.appendFormat("%d: ", mErrorCode);
+        } else if (mException == EX_TRANSACTION_FAILED) {
+            ret.appendFormat("%s: ", statusToString(mErrorCode).c_str());
         }
         ret.append(String8(mMessage));
         ret.append("'");
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
index f3bc31b..7871667 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
@@ -441,6 +441,42 @@
 }
 
 /**
+ * Writes a ScopedFileDescriptor object inside a std::vector<ScopedFileDescriptor> at index 'index'
+ * to 'parcel'.
+ */
+template <>
+inline binder_status_t AParcel_writeStdVectorParcelableElement<ScopedFileDescriptor>(
+        AParcel* parcel, const void* vectorData, size_t index) {
+    const std::vector<ScopedFileDescriptor>* vector =
+            static_cast<const std::vector<ScopedFileDescriptor>*>(vectorData);
+    int writeFd = vector->at(index).get();
+    if (writeFd < 0) {
+        return STATUS_UNEXPECTED_NULL;
+    }
+    return AParcel_writeParcelFileDescriptor(parcel, writeFd);
+}
+
+/**
+ * Reads a ScopedFileDescriptor object inside a std::vector<ScopedFileDescriptor> at index 'index'
+ * from 'parcel'.
+ */
+template <>
+inline binder_status_t AParcel_readStdVectorParcelableElement<ScopedFileDescriptor>(
+        const AParcel* parcel, void* vectorData, size_t index) {
+    std::vector<ScopedFileDescriptor>* vector =
+            static_cast<std::vector<ScopedFileDescriptor>*>(vectorData);
+    int readFd;
+    binder_status_t status = AParcel_readParcelFileDescriptor(parcel, &readFd);
+    if (status == STATUS_OK) {
+        if (readFd < 0) {
+            return STATUS_UNEXPECTED_NULL;
+        }
+        vector->at(index).set(readFd);
+    }
+    return status;
+}
+
+/**
  * Convenience API for writing a std::vector<P>
  */
 template <typename P>