Add batched createAppData API to installd.

Benchmarking creation of new users shows on a freshly setup device
sees many individual binder calls from system server into installd to
create app data directories. Batching these calls shows a significant
performance improvement.

Bug: 153171028
Test: Manually create guest user, trace performance with Perfetto.

Change-Id: Iea43c058d465be44c0937bf6c353555869fc9fd2
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 6fee11b..c0fb0f8 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -412,6 +412,33 @@
     return true;
 }
 
+binder::Status InstalldNativeService::createAppDataBatched(
+        const std::optional<std::vector<std::optional<std::string>>>& uuids,
+        const std::optional<std::vector<std::optional<std::string>>>& packageNames,
+        int32_t userId, int32_t flags, const std::vector<int32_t>& appIds,
+        const std::vector<std::string>& seInfos, const std::vector<int32_t>& targetSdkVersions,
+        int64_t* _aidl_return) {
+    ENFORCE_UID(AID_SYSTEM);
+    std::lock_guard<std::recursive_mutex> lock(mLock);
+
+    ATRACE_BEGIN("createAppDataBatched");
+    binder::Status ret;
+    for (size_t i = 0; i < uuids->size(); i++) {
+        std::optional<std::string> packageName = packageNames->at(i);
+        if (!packageName) {
+            continue;
+        }
+        ret = createAppData(uuids->at(i), *packageName, userId, flags, appIds[i],
+                seInfos[i], targetSdkVersions[i], _aidl_return);
+        if (!ret.isOk()) {
+            ATRACE_END();
+            return ret;
+        }
+    }
+    ATRACE_END();
+    return ok();
+}
+
 binder::Status InstalldNativeService::createAppData(const std::optional<std::string>& uuid,
         const std::string& packageName, int32_t userId, int32_t flags, int32_t appId,
         const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return) {