Merge "More robust createAppData() batching."
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp
index be0c062..17015a4 100644
--- a/cmds/installd/Android.bp
+++ b/cmds/installd/Android.bp
@@ -189,8 +189,7 @@
 filegroup {
     name: "installd_aidl",
     srcs: [
-        "binder/android/os/IInstalld.aidl",
-        "binder/android/os/storage/CrateMetadata.aidl",
+        "binder/**/*.aidl",
     ],
     path: "binder",
 }
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index e7014c8..eb1bbd9 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -420,33 +420,6 @@
     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) {
@@ -528,6 +501,38 @@
     return ok();
 }
 
+
+binder::Status InstalldNativeService::createAppData(
+        const android::os::CreateAppDataArgs& args,
+        android::os::CreateAppDataResult* _aidl_return) {
+    ENFORCE_UID(AID_SYSTEM);
+    std::lock_guard<std::recursive_mutex> lock(mLock);
+
+    int64_t ceDataInode = -1;
+    auto status = createAppData(args.uuid, args.packageName, args.userId, args.flags, args.appId,
+                                args.seInfo, args.targetSdkVersion, &ceDataInode);
+    _aidl_return->ceDataInode = ceDataInode;
+    _aidl_return->exceptionCode = status.exceptionCode();
+    _aidl_return->exceptionMessage = status.exceptionMessage();
+    return ok();
+}
+
+binder::Status InstalldNativeService::createAppDataBatched(
+        const std::vector<android::os::CreateAppDataArgs>& args,
+        std::vector<android::os::CreateAppDataResult>* _aidl_return) {
+    ENFORCE_UID(AID_SYSTEM);
+    std::lock_guard<std::recursive_mutex> lock(mLock);
+
+    std::vector<android::os::CreateAppDataResult> results;
+    for (auto arg : args) {
+        android::os::CreateAppDataResult result;
+        createAppData(arg, &result);
+        results.push_back(result);
+    }
+    *_aidl_return = results;
+    return ok();
+}
+
 binder::Status InstalldNativeService::migrateAppData(const std::optional<std::string>& uuid,
         const std::string& packageName, int32_t userId, int32_t flags) {
     ENFORCE_UID(AID_SYSTEM);
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index 9819327..4966b96 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -44,15 +44,18 @@
             int32_t userSerial, int32_t flags);
     binder::Status destroyUserData(const std::optional<std::string>& uuid, int32_t userId,
             int32_t flags);
-    binder::Status 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);
+
     binder::Status 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);
+
+    binder::Status createAppData(
+            const android::os::CreateAppDataArgs& args,
+            android::os::CreateAppDataResult* _aidl_return);
+    binder::Status createAppDataBatched(
+            const std::vector<android::os::CreateAppDataArgs>& args,
+            std::vector<android::os::CreateAppDataResult>* _aidl_return);
+
     binder::Status restoreconAppData(const std::optional<std::string>& uuid,
             const std::string& packageName, int32_t userId, int32_t flags, int32_t appId,
             const std::string& seInfo);
diff --git a/cmds/installd/binder/android/os/CreateAppDataArgs.aidl b/cmds/installd/binder/android/os/CreateAppDataArgs.aidl
new file mode 100644
index 0000000..96d7faa
--- /dev/null
+++ b/cmds/installd/binder/android/os/CreateAppDataArgs.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+/** {@hide} */
+parcelable CreateAppDataArgs {
+    @nullable @utf8InCpp String uuid;
+    @utf8InCpp String packageName;
+    int userId;
+    int flags;
+    int appId;
+    @utf8InCpp String seInfo;
+    int targetSdkVersion;
+}
diff --git a/cmds/installd/binder/android/os/CreateAppDataResult.aidl b/cmds/installd/binder/android/os/CreateAppDataResult.aidl
new file mode 100644
index 0000000..3b8fa6b
--- /dev/null
+++ b/cmds/installd/binder/android/os/CreateAppDataResult.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+/** {@hide} */
+parcelable CreateAppDataResult {
+    long ceDataInode;
+    int exceptionCode;
+    @utf8InCpp String exceptionMessage;
+}
diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl
index eeda6c5..2538e22 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -21,11 +21,9 @@
     void createUserData(@nullable @utf8InCpp String uuid, int userId, int userSerial, int flags);
     void destroyUserData(@nullable @utf8InCpp String uuid, int userId, int flags);
 
-    long createAppData(@nullable @utf8InCpp String uuid, in @utf8InCpp String packageName,
-            int userId, int flags, int appId, in @utf8InCpp String seInfo, int targetSdkVersion);
-    long createAppDataBatched(in @nullable @utf8InCpp String[] uuids,
-        in @nullable @utf8InCpp String[] packageNames, in int userId, int flags, in int[] appIds,
-        in @utf8InCpp String[] seInfos, in int[] targetSdkVersions);
+    android.os.CreateAppDataResult createAppData(in android.os.CreateAppDataArgs args);
+    android.os.CreateAppDataResult[] createAppDataBatched(in android.os.CreateAppDataArgs[] args);
+
     void restoreconAppData(@nullable @utf8InCpp String uuid, @utf8InCpp String packageName,
             int userId, int flags, int appId, @utf8InCpp String seInfo);
     void migrateAppData(@nullable @utf8InCpp String uuid, @utf8InCpp String packageName,