Use std::optional for @nullable (AIDL)

Previously, nullable types were mapped to std::unique_ptr for C++
backend. But std::unique_ptr typically involves unnecessary alloc/dealloc.

For example, if nullable string is represented in unique_ptr<string>, we
should do "unique_ptr<string>(new string(value))" to set a value.

To avoid breaking all hand-written parcelables, only new read/write
functions are added to Parcel class and they are used only by
aidl-generated code and their implementations.

Bug: 144773267
Test: build/flash/boot
      atest --test-mapping frameworks/native/libs/binder

Merged-In: I2c801e3b69f2f8ccf44267f15cbf79e1d8fbf19e
Change-Id: I2c801e3b69f2f8ccf44267f15cbf79e1d8fbf19e
(cherry picked from commit 1e1c5fbbbe8a76150fe832c8f974cbd543aa0860)

Exempt-From-Owner-Approval: CP from master
This commit is contained in:
Jooyung Han 2020-01-23 12:45:10 +09:00
parent 61addf0da3
commit 9fcc4ef9bb
11 changed files with 593 additions and 148 deletions

View file

@ -24,6 +24,7 @@
#include <fts.h>
#include <functional>
#include <inttypes.h>
#include <memory>
#include <regex>
#include <stdlib.h>
#include <string.h>
@ -157,7 +158,7 @@ binder::Status checkUid(uid_t expectedUid) {
}
}
binder::Status checkArgumentUuid(const std::unique_ptr<std::string>& uuid) {
binder::Status checkArgumentUuid(const std::optional<std::string>& uuid) {
if (!uuid || is_valid_filename(*uuid)) {
return ok();
} else {
@ -166,7 +167,7 @@ binder::Status checkArgumentUuid(const std::unique_ptr<std::string>& uuid) {
}
}
binder::Status checkArgumentUuidTestOrNull(const std::unique_ptr<std::string>& uuid) {
binder::Status checkArgumentUuidTestOrNull(const std::optional<std::string>& uuid) {
if (!uuid || strcmp(uuid->c_str(), kTestUuid) == 0) {
return ok();
} else {
@ -205,7 +206,7 @@ binder::Status checkArgumentPath(const std::string& path) {
return ok();
}
binder::Status checkArgumentPath(const std::unique_ptr<std::string>& path) {
binder::Status checkArgumentPath(const std::optional<std::string>& path) {
if (path) {
return checkArgumentPath(*path);
} else {
@ -409,7 +410,7 @@ static bool prepare_app_profile_dir(const std::string& packageName, int32_t appI
return true;
}
binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::string>& uuid,
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) {
ENFORCE_UID(AID_SYSTEM);
@ -487,7 +488,7 @@ binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::s
return ok();
}
binder::Status InstalldNativeService::migrateAppData(const std::unique_ptr<std::string>& uuid,
binder::Status InstalldNativeService::migrateAppData(const std::optional<std::string>& uuid,
const std::string& packageName, int32_t userId, int32_t flags) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
@ -548,7 +549,7 @@ binder::Status InstalldNativeService::clearAppProfiles(const std::string& packag
return res;
}
binder::Status InstalldNativeService::clearAppData(const std::unique_ptr<std::string>& uuid,
binder::Status InstalldNativeService::clearAppData(const std::optional<std::string>& uuid,
const std::string& packageName, int32_t userId, int32_t flags, int64_t ceDataInode) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
@ -668,7 +669,7 @@ binder::Status InstalldNativeService::destroyAppProfiles(const std::string& pack
return res;
}
binder::Status InstalldNativeService::destroyAppData(const std::unique_ptr<std::string>& uuid,
binder::Status InstalldNativeService::destroyAppData(const std::optional<std::string>& uuid,
const std::string& packageName, int32_t userId, int32_t flags, int64_t ceDataInode) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
@ -740,7 +741,7 @@ static gid_t get_cache_gid(uid_t uid) {
return (gid != -1) ? gid : uid;
}
binder::Status InstalldNativeService::fixupAppData(const std::unique_ptr<std::string>& uuid,
binder::Status InstalldNativeService::fixupAppData(const std::optional<std::string>& uuid,
int32_t flags) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
@ -860,7 +861,7 @@ static int32_t copy_directory_recursive(const char* from, const char* to) {
}
binder::Status InstalldNativeService::snapshotAppData(
const std::unique_ptr<std::string>& volumeUuid,
const std::optional<std::string>& volumeUuid,
const std::string& packageName, int32_t user, int32_t snapshotId,
int32_t storageFlags, int64_t* _aidl_return) {
ENFORCE_UID(AID_SYSTEM);
@ -987,7 +988,7 @@ binder::Status InstalldNativeService::snapshotAppData(
}
binder::Status InstalldNativeService::restoreAppDataSnapshot(
const std::unique_ptr<std::string>& volumeUuid, const std::string& packageName,
const std::optional<std::string>& volumeUuid, const std::string& packageName,
const int32_t appId, const std::string& seInfo, const int32_t user,
const int32_t snapshotId, int32_t storageFlags) {
ENFORCE_UID(AID_SYSTEM);
@ -1057,7 +1058,7 @@ binder::Status InstalldNativeService::restoreAppDataSnapshot(
}
binder::Status InstalldNativeService::destroyAppDataSnapshot(
const std::unique_ptr<std::string> &volumeUuid, const std::string& packageName,
const std::optional<std::string> &volumeUuid, const std::string& packageName,
const int32_t user, const int64_t ceSnapshotInode, const int32_t snapshotId,
int32_t storageFlags) {
ENFORCE_UID(AID_SYSTEM);
@ -1090,8 +1091,8 @@ binder::Status InstalldNativeService::destroyAppDataSnapshot(
}
binder::Status InstalldNativeService::moveCompleteApp(const std::unique_ptr<std::string>& fromUuid,
const std::unique_ptr<std::string>& toUuid, const std::string& packageName,
binder::Status InstalldNativeService::moveCompleteApp(const std::optional<std::string>& fromUuid,
const std::optional<std::string>& toUuid, const std::string& packageName,
const std::string& dataAppName, int32_t appId, const std::string& seInfo,
int32_t targetSdkVersion) {
ENFORCE_UID(AID_SYSTEM);
@ -1200,7 +1201,7 @@ fail:
return res;
}
binder::Status InstalldNativeService::createUserData(const std::unique_ptr<std::string>& uuid,
binder::Status InstalldNativeService::createUserData(const std::optional<std::string>& uuid,
int32_t userId, int32_t userSerial ATTRIBUTE_UNUSED, int32_t flags) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
@ -1218,7 +1219,7 @@ binder::Status InstalldNativeService::createUserData(const std::unique_ptr<std::
return ok();
}
binder::Status InstalldNativeService::destroyUserData(const std::unique_ptr<std::string>& uuid,
binder::Status InstalldNativeService::destroyUserData(const std::optional<std::string>& uuid,
int32_t userId, int32_t flags) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
@ -1255,13 +1256,13 @@ binder::Status InstalldNativeService::destroyUserData(const std::unique_ptr<std:
return res;
}
binder::Status InstalldNativeService::freeCache(const std::unique_ptr<std::string>& uuid,
binder::Status InstalldNativeService::freeCache(const std::optional<std::string>& uuid,
int64_t targetFreeBytes, int64_t cacheReservedBytes, int32_t flags) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
std::lock_guard<std::recursive_mutex> lock(mLock);
auto uuidString = uuid ? *uuid : "";
auto uuidString = uuid.value_or("");
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
auto data_path = create_data_path(uuid_);
auto noop = (flags & FLAG_FREE_CACHE_NOOP);
@ -1659,7 +1660,7 @@ static void collectManualExternalStatsForUser(const std::string& path, struct st
fts_close(fts);
}
binder::Status InstalldNativeService::getAppSize(const std::unique_ptr<std::string>& uuid,
binder::Status InstalldNativeService::getAppSize(const std::optional<std::string>& uuid,
const std::vector<std::string>& packageNames, int32_t userId, int32_t flags,
int32_t appId, const std::vector<int64_t>& ceDataInodes,
const std::vector<std::string>& codePaths, std::vector<int64_t>* _aidl_return) {
@ -1699,7 +1700,7 @@ binder::Status InstalldNativeService::getAppSize(const std::unique_ptr<std::stri
memset(&stats, 0, sizeof(stats));
memset(&extStats, 0, sizeof(extStats));
auto uuidString = uuid ? *uuid : "";
auto uuidString = uuid.value_or("");
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
if (!IsQuotaSupported(uuidString)) {
@ -1886,7 +1887,7 @@ static external_sizes getExternalSizesForUserWithQuota(const std::string& uuid,
return sizes;
}
binder::Status InstalldNativeService::getUserSize(const std::unique_ptr<std::string>& uuid,
binder::Status InstalldNativeService::getUserSize(const std::optional<std::string>& uuid,
int32_t userId, int32_t flags, const std::vector<int32_t>& appIds,
std::vector<int64_t>* _aidl_return) {
ENFORCE_UID(AID_SYSTEM);
@ -1906,7 +1907,7 @@ binder::Status InstalldNativeService::getUserSize(const std::unique_ptr<std::str
memset(&stats, 0, sizeof(stats));
memset(&extStats, 0, sizeof(extStats));
auto uuidString = uuid ? *uuid : "";
auto uuidString = uuid.value_or("");
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
if (!IsQuotaSupported(uuidString)) {
@ -2018,7 +2019,7 @@ binder::Status InstalldNativeService::getUserSize(const std::unique_ptr<std::str
return ok();
}
binder::Status InstalldNativeService::getExternalSize(const std::unique_ptr<std::string>& uuid,
binder::Status InstalldNativeService::getExternalSize(const std::optional<std::string>& uuid,
int32_t userId, int32_t flags, const std::vector<int32_t>& appIds,
std::vector<int64_t>* _aidl_return) {
ENFORCE_UID(AID_SYSTEM);
@ -2033,7 +2034,7 @@ binder::Status InstalldNativeService::getExternalSize(const std::unique_ptr<std:
LOG(INFO) << "Measuring external " << userId;
#endif
auto uuidString = uuid ? *uuid : "";
auto uuidString = uuid.value_or("");
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
int64_t totalSize = 0;
@ -2134,7 +2135,7 @@ binder::Status InstalldNativeService::getExternalSize(const std::unique_ptr<std:
return ok();
}
binder::Status InstalldNativeService::setAppQuota(const std::unique_ptr<std::string>& uuid,
binder::Status InstalldNativeService::setAppQuota(const std::optional<std::string>& uuid,
int32_t userId, int32_t appId, int64_t cacheQuota) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
@ -2205,19 +2206,19 @@ binder::Status InstalldNativeService::destroyProfileSnapshot(const std::string&
return ok();
}
static const char* getCStr(const std::unique_ptr<std::string>& data,
static const char* getCStr(const std::optional<std::string>& data,
const char* default_value = nullptr) {
return data == nullptr ? default_value : data->c_str();
return !data ? default_value : data->c_str();
}
binder::Status InstalldNativeService::dexopt(const std::string& apkPath, int32_t uid,
const std::unique_ptr<std::string>& packageName, const std::string& instructionSet,
int32_t dexoptNeeded, const std::unique_ptr<std::string>& outputPath, int32_t dexFlags,
const std::string& compilerFilter, const std::unique_ptr<std::string>& uuid,
const std::unique_ptr<std::string>& classLoaderContext,
const std::unique_ptr<std::string>& seInfo, bool downgrade, int32_t targetSdkVersion,
const std::unique_ptr<std::string>& profileName,
const std::unique_ptr<std::string>& dexMetadataPath,
const std::unique_ptr<std::string>& compilationReason) {
const std::optional<std::string>& packageName, const std::string& instructionSet,
int32_t dexoptNeeded, const std::optional<std::string>& outputPath, int32_t dexFlags,
const std::string& compilerFilter, const std::optional<std::string>& uuid,
const std::optional<std::string>& classLoaderContext,
const std::optional<std::string>& seInfo, bool downgrade, int32_t targetSdkVersion,
const std::optional<std::string>& profileName,
const std::optional<std::string>& dexMetadataPath,
const std::optional<std::string>& compilationReason) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
CHECK_ARGUMENT_PATH(apkPath);
@ -2283,7 +2284,7 @@ binder::Status InstalldNativeService::markBootComplete(const std::string& instru
}
binder::Status InstalldNativeService::linkNativeLibraryDirectory(
const std::unique_ptr<std::string>& uuid, const std::string& packageName,
const std::optional<std::string>& uuid, const std::string& packageName,
const std::string& nativeLibPath32, int32_t userId) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(uuid);
@ -2574,7 +2575,7 @@ binder::Status InstalldNativeService::removeIdmap(const std::string& overlayApkP
return ok();
}
binder::Status InstalldNativeService::restoreconAppData(const std::unique_ptr<std::string>& uuid,
binder::Status InstalldNativeService::restoreconAppData(const std::optional<std::string>& uuid,
const std::string& packageName, int32_t userId, int32_t flags, int32_t appId,
const std::string& seInfo) {
ENFORCE_UID(AID_SYSTEM);
@ -2692,7 +2693,7 @@ binder::Status InstalldNativeService::moveAb(const std::string& apkPath,
}
binder::Status InstalldNativeService::deleteOdex(const std::string& apkPath,
const std::string& instructionSet, const std::unique_ptr<std::string>& outputPath) {
const std::string& instructionSet, const std::optional<std::string>& outputPath) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PATH(apkPath);
CHECK_ARGUMENT_PATH(outputPath);
@ -2844,7 +2845,7 @@ binder::Status InstalldNativeService::assertFsverityRootHashMatches(const std::s
binder::Status InstalldNativeService::reconcileSecondaryDexFile(
const std::string& dexPath, const std::string& packageName, int32_t uid,
const std::vector<std::string>& isas, const std::unique_ptr<std::string>& volumeUuid,
const std::vector<std::string>& isas, const std::optional<std::string>& volumeUuid,
int32_t storage_flag, bool* _aidl_return) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(volumeUuid);
@ -2859,7 +2860,7 @@ binder::Status InstalldNativeService::reconcileSecondaryDexFile(
binder::Status InstalldNativeService::hashSecondaryDexFile(
const std::string& dexPath, const std::string& packageName, int32_t uid,
const std::unique_ptr<std::string>& volumeUuid, int32_t storageFlag,
const std::optional<std::string>& volumeUuid, int32_t storageFlag,
std::vector<uint8_t>* _aidl_return) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_UUID(volumeUuid);
@ -2917,7 +2918,7 @@ binder::Status InstalldNativeService::invalidateMounts() {
}
std::string InstalldNativeService::findDataMediaPath(
const std::unique_ptr<std::string>& uuid, userid_t userid) {
const std::optional<std::string>& uuid, userid_t userid) {
std::lock_guard<std::recursive_mutex> lock(mMountsLock);
const char* uuid_ = uuid ? uuid->c_str() : nullptr;
auto path = StringPrintf("%s/media", create_data_path(uuid_).c_str());
@ -2930,15 +2931,15 @@ std::string InstalldNativeService::findDataMediaPath(
}
binder::Status InstalldNativeService::isQuotaSupported(
const std::unique_ptr<std::string>& uuid, bool* _aidl_return) {
auto uuidString = uuid ? *uuid : "";
const std::optional<std::string>& uuid, bool* _aidl_return) {
auto uuidString = uuid.value_or("");
*_aidl_return = IsQuotaSupported(uuidString);
return ok();
}
binder::Status InstalldNativeService::prepareAppProfile(const std::string& packageName,
int32_t userId, int32_t appId, const std::string& profileName, const std::string& codePath,
const std::unique_ptr<std::string>& dexMetadata, bool* _aidl_return) {
const std::optional<std::string>& dexMetadata, bool* _aidl_return) {
ENFORCE_UID(AID_SYSTEM);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
CHECK_ARGUMENT_PATH(codePath);

View file

@ -40,64 +40,64 @@ public:
static char const* getServiceName() { return "installd"; }
virtual status_t dump(int fd, const Vector<String16> &args) override;
binder::Status createUserData(const std::unique_ptr<std::string>& uuid, int32_t userId,
binder::Status createUserData(const std::optional<std::string>& uuid, int32_t userId,
int32_t userSerial, int32_t flags);
binder::Status destroyUserData(const std::unique_ptr<std::string>& uuid, int32_t userId,
binder::Status destroyUserData(const std::optional<std::string>& uuid, int32_t userId,
int32_t flags);
binder::Status createAppData(const std::unique_ptr<std::string>& uuid,
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 restoreconAppData(const std::unique_ptr<std::string>& uuid,
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);
binder::Status migrateAppData(const std::unique_ptr<std::string>& uuid,
binder::Status migrateAppData(const std::optional<std::string>& uuid,
const std::string& packageName, int32_t userId, int32_t flags);
binder::Status clearAppData(const std::unique_ptr<std::string>& uuid,
binder::Status clearAppData(const std::optional<std::string>& uuid,
const std::string& packageName, int32_t userId, int32_t flags, int64_t ceDataInode);
binder::Status destroyAppData(const std::unique_ptr<std::string>& uuid,
binder::Status destroyAppData(const std::optional<std::string>& uuid,
const std::string& packageName, int32_t userId, int32_t flags, int64_t ceDataInode);
binder::Status fixupAppData(const std::unique_ptr<std::string>& uuid, int32_t flags);
binder::Status fixupAppData(const std::optional<std::string>& uuid, int32_t flags);
binder::Status snapshotAppData(const std::unique_ptr<std::string>& volumeUuid,
binder::Status snapshotAppData(const std::optional<std::string>& volumeUuid,
const std::string& packageName, const int32_t user, const int32_t snapshotId,
int32_t storageFlags, int64_t* _aidl_return);
binder::Status restoreAppDataSnapshot(const std::unique_ptr<std::string>& volumeUuid,
binder::Status restoreAppDataSnapshot(const std::optional<std::string>& volumeUuid,
const std::string& packageName, const int32_t appId, const std::string& seInfo,
const int32_t user, const int32_t snapshotId, int32_t storageFlags);
binder::Status destroyAppDataSnapshot(const std::unique_ptr<std::string> &volumeUuid,
binder::Status destroyAppDataSnapshot(const std::optional<std::string> &volumeUuid,
const std::string& packageName, const int32_t user, const int64_t ceSnapshotInode,
const int32_t snapshotId, int32_t storageFlags);
binder::Status getAppSize(const std::unique_ptr<std::string>& uuid,
binder::Status getAppSize(const std::optional<std::string>& uuid,
const std::vector<std::string>& packageNames, int32_t userId, int32_t flags,
int32_t appId, const std::vector<int64_t>& ceDataInodes,
const std::vector<std::string>& codePaths, std::vector<int64_t>* _aidl_return);
binder::Status getUserSize(const std::unique_ptr<std::string>& uuid,
binder::Status getUserSize(const std::optional<std::string>& uuid,
int32_t userId, int32_t flags, const std::vector<int32_t>& appIds,
std::vector<int64_t>* _aidl_return);
binder::Status getExternalSize(const std::unique_ptr<std::string>& uuid,
binder::Status getExternalSize(const std::optional<std::string>& uuid,
int32_t userId, int32_t flags, const std::vector<int32_t>& appIds,
std::vector<int64_t>* _aidl_return);
binder::Status setAppQuota(const std::unique_ptr<std::string>& uuid,
binder::Status setAppQuota(const std::optional<std::string>& uuid,
int32_t userId, int32_t appId, int64_t cacheQuota);
binder::Status moveCompleteApp(const std::unique_ptr<std::string>& fromUuid,
const std::unique_ptr<std::string>& toUuid, const std::string& packageName,
binder::Status moveCompleteApp(const std::optional<std::string>& fromUuid,
const std::optional<std::string>& toUuid, const std::string& packageName,
const std::string& dataAppName, int32_t appId, const std::string& seInfo,
int32_t targetSdkVersion);
binder::Status dexopt(const std::string& apkPath, int32_t uid,
const std::unique_ptr<std::string>& packageName, const std::string& instructionSet,
int32_t dexoptNeeded, const std::unique_ptr<std::string>& outputPath, int32_t dexFlags,
const std::string& compilerFilter, const std::unique_ptr<std::string>& uuid,
const std::unique_ptr<std::string>& classLoaderContext,
const std::unique_ptr<std::string>& seInfo, bool downgrade,
int32_t targetSdkVersion, const std::unique_ptr<std::string>& profileName,
const std::unique_ptr<std::string>& dexMetadataPath,
const std::unique_ptr<std::string>& compilationReason);
const std::optional<std::string>& packageName, const std::string& instructionSet,
int32_t dexoptNeeded, const std::optional<std::string>& outputPath, int32_t dexFlags,
const std::string& compilerFilter, const std::optional<std::string>& uuid,
const std::optional<std::string>& classLoaderContext,
const std::optional<std::string>& seInfo, bool downgrade,
int32_t targetSdkVersion, const std::optional<std::string>& profileName,
const std::optional<std::string>& dexMetadataPath,
const std::optional<std::string>& compilationReason);
binder::Status compileLayouts(const std::string& apkPath, const std::string& packageName,
const std::string& outDexFile, int uid, bool* _aidl_return);
@ -124,9 +124,9 @@ public:
binder::Status removeIdmap(const std::string& overlayApkPath);
binder::Status rmPackageDir(const std::string& packageDir);
binder::Status markBootComplete(const std::string& instructionSet);
binder::Status freeCache(const std::unique_ptr<std::string>& uuid, int64_t targetFreeBytes,
binder::Status freeCache(const std::optional<std::string>& uuid, int64_t targetFreeBytes,
int64_t cacheReservedBytes, int32_t flags);
binder::Status linkNativeLibraryDirectory(const std::unique_ptr<std::string>& uuid,
binder::Status linkNativeLibraryDirectory(const std::optional<std::string>& uuid,
const std::string& packageName, const std::string& nativeLibPath32, int32_t userId);
binder::Status createOatDir(const std::string& oatDir, const std::string& instructionSet);
binder::Status linkFile(const std::string& relativePath, const std::string& fromBase,
@ -134,25 +134,25 @@ public:
binder::Status moveAb(const std::string& apkPath, const std::string& instructionSet,
const std::string& outputPath);
binder::Status deleteOdex(const std::string& apkPath, const std::string& instructionSet,
const std::unique_ptr<std::string>& outputPath);
const std::optional<std::string>& outputPath);
binder::Status installApkVerity(const std::string& filePath,
android::base::unique_fd verityInput, int32_t contentSize);
binder::Status assertFsverityRootHashMatches(const std::string& filePath,
const std::vector<uint8_t>& expectedHash);
binder::Status reconcileSecondaryDexFile(const std::string& dexPath,
const std::string& packageName, int32_t uid, const std::vector<std::string>& isa,
const std::unique_ptr<std::string>& volumeUuid, int32_t storage_flag, bool* _aidl_return);
const std::optional<std::string>& volumeUuid, int32_t storage_flag, bool* _aidl_return);
binder::Status hashSecondaryDexFile(const std::string& dexPath,
const std::string& packageName, int32_t uid, const std::unique_ptr<std::string>& volumeUuid,
const std::string& packageName, int32_t uid, const std::optional<std::string>& volumeUuid,
int32_t storageFlag, std::vector<uint8_t>* _aidl_return);
binder::Status invalidateMounts();
binder::Status isQuotaSupported(const std::unique_ptr<std::string>& volumeUuid,
binder::Status isQuotaSupported(const std::optional<std::string>& volumeUuid,
bool* _aidl_return);
binder::Status prepareAppProfile(const std::string& packageName,
int32_t userId, int32_t appId, const std::string& profileName,
const std::string& codePath, const std::unique_ptr<std::string>& dexMetadata,
const std::string& codePath, const std::optional<std::string>& dexMetadata,
bool* _aidl_return);
binder::Status migrateLegacyObbData();
@ -169,7 +169,7 @@ private:
/* Map from UID to cache quota size */
std::unordered_map<uid_t, int64_t> mCacheQuotas;
std::string findDataMediaPath(const std::unique_ptr<std::string>& uuid, userid_t userid);
std::string findDataMediaPath(const std::optional<std::string>& uuid, userid_t userid);
};
} // namespace installd

View file

@ -2277,7 +2277,7 @@ enum ReconcileSecondaryDexResult {
// out_secondary_dex_exists will be set to false.
bool reconcile_secondary_dex_file(const std::string& dex_path,
const std::string& pkgname, int uid, const std::vector<std::string>& isas,
const std::unique_ptr<std::string>& volume_uuid, int storage_flag,
const std::optional<std::string>& volume_uuid, int storage_flag,
/*out*/bool* out_secondary_dex_exists) {
*out_secondary_dex_exists = false; // start by assuming the file does not exist.
if (isas.size() == 0) {
@ -2298,7 +2298,7 @@ bool reconcile_secondary_dex_file(const std::string& dex_path,
/* child -- drop privileges before continuing */
drop_capabilities(uid);
const char* volume_uuid_cstr = volume_uuid == nullptr ? nullptr : volume_uuid->c_str();
const char* volume_uuid_cstr = volume_uuid ? volume_uuid->c_str() : nullptr;
if (!validate_secondary_dex_path(pkgname, dex_path, volume_uuid_cstr,
uid, storage_flag)) {
LOG(ERROR) << "Could not validate secondary dex path " << dex_path;
@ -2399,11 +2399,11 @@ bool reconcile_secondary_dex_file(const std::string& dex_path,
// the app.
// For any other errors (e.g. if any of the parameters are invalid) returns false.
bool hash_secondary_dex_file(const std::string& dex_path, const std::string& pkgname, int uid,
const std::unique_ptr<std::string>& volume_uuid, int storage_flag,
const std::optional<std::string>& volume_uuid, int storage_flag,
std::vector<uint8_t>* out_secondary_dex_hash) {
out_secondary_dex_hash->clear();
const char* volume_uuid_cstr = volume_uuid == nullptr ? nullptr : volume_uuid->c_str();
const char* volume_uuid_cstr = volume_uuid ? volume_uuid->c_str() : nullptr;
if (storage_flag != FLAG_STORAGE_CE && storage_flag != FLAG_STORAGE_DE) {
LOG(ERROR) << "hash_secondary_dex_file called with invalid storage_flag: "
@ -2924,7 +2924,7 @@ bool prepare_app_profile(const std::string& package_name,
appid_t app_id,
const std::string& profile_name,
const std::string& code_path,
const std::unique_ptr<std::string>& dex_metadata) {
const std::optional<std::string>& dex_metadata) {
// Prepare the current profile.
std::string cur_profile = create_current_profile_path(user_id, package_name, profile_name,
/*is_secondary_dex*/ false);
@ -2935,7 +2935,7 @@ bool prepare_app_profile(const std::string& package_name,
}
// Check if we need to install the profile from the dex metadata.
if (dex_metadata == nullptr) {
if (!dex_metadata) {
return true;
}

View file

@ -21,6 +21,8 @@
#include <sys/types.h>
#include <optional>
#include <cutils/multiuser.h>
namespace android {
@ -98,17 +100,17 @@ bool prepare_app_profile(const std::string& package_name,
appid_t app_id,
const std::string& profile_name,
const std::string& code_path,
const std::unique_ptr<std::string>& dex_metadata);
const std::optional<std::string>& dex_metadata);
bool delete_odex(const char* apk_path, const char* instruction_set, const char* output_path);
bool reconcile_secondary_dex_file(const std::string& dex_path,
const std::string& pkgname, int uid, const std::vector<std::string>& isas,
const std::unique_ptr<std::string>& volumeUuid, int storage_flag,
const std::optional<std::string>& volumeUuid, int storage_flag,
/*out*/bool* out_secondary_dex_exists);
bool hash_secondary_dex_file(const std::string& dex_path,
const std::string& pkgname, int uid, const std::unique_ptr<std::string>& volume_uuid,
const std::string& pkgname, int uid, const std::optional<std::string>& volume_uuid,
int storage_flag, std::vector<uint8_t>* out_secondary_dex_hash);
int dexopt(const char *apk_path, uid_t uid, const char *pkgName, const char *instruction_set,

View file

@ -114,15 +114,14 @@ static void setxattr(const char* path, const char* key) {
class CacheTest : public testing::Test {
protected:
InstalldNativeService* service;
std::unique_ptr<std::string> testUuid;
std::optional<std::string> testUuid;
virtual void SetUp() {
setenv("ANDROID_LOG_TAGS", "*:v", 1);
android::base::InitLogging(nullptr);
service = new InstalldNativeService();
testUuid = std::make_unique<std::string>();
*testUuid = std::string(kTestUuid);
testUuid = kTestUuid;
system("mkdir -p /data/local/tmp/user/0");
}

View file

@ -193,7 +193,7 @@ protected:
const uid_t kTestAppGid = multiuser_get_shared_gid(kTestUserId, kTestAppId);
InstalldNativeService* service_;
std::unique_ptr<std::string> volume_uuid_;
std::optional<std::string> volume_uuid_;
std::string package_name_;
std::string apk_path_;
std::string empty_dm_file_;
@ -221,7 +221,7 @@ protected:
ASSERT_TRUE(init_selinux());
service_ = new InstalldNativeService();
volume_uuid_ = nullptr;
volume_uuid_ = std::nullopt;
package_name_ = "com.installd.test.dexopt";
se_info_ = "default";
app_apk_dir_ = android_app_dir + package_name_;
@ -294,7 +294,7 @@ protected:
}
// Create a secondary dex file on CE storage
const char* volume_uuid_cstr = volume_uuid_ == nullptr ? nullptr : volume_uuid_->c_str();
const char* volume_uuid_cstr = volume_uuid_ ? volume_uuid_->c_str() : nullptr;
app_private_dir_ce_ = create_data_user_ce_package_path(
volume_uuid_cstr, kTestUserId, package_name_.c_str());
secondary_dex_ce_ = app_private_dir_ce_ + "/secondary_ce.jar";
@ -353,36 +353,32 @@ protected:
if (class_loader_context == nullptr) {
class_loader_context = "&";
}
std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_));
int32_t dexopt_needed = 0; // does not matter;
std::unique_ptr<std::string> out_path = nullptr; // does not matter
std::optional<std::string> out_path; // does not matter
int32_t dex_flags = DEXOPT_SECONDARY_DEX | dex_storage_flag;
std::string compiler_filter = "speed-profile";
std::unique_ptr<std::string> class_loader_context_ptr(
new std::string(class_loader_context));
std::unique_ptr<std::string> se_info_ptr(new std::string(se_info_));
bool downgrade = false;
int32_t target_sdk_version = 0; // default
std::unique_ptr<std::string> profile_name_ptr = nullptr;
std::unique_ptr<std::string> dm_path_ptr = nullptr;
std::unique_ptr<std::string> compilation_reason_ptr = nullptr;
std::optional<std::string> profile_name;
std::optional<std::string> dm_path;
std::optional<std::string> compilation_reason;
binder::Status result = service_->dexopt(path,
uid,
package_name_ptr,
package_name_,
kRuntimeIsa,
dexopt_needed,
out_path,
dex_flags,
compiler_filter,
volume_uuid_,
class_loader_context_ptr,
se_info_ptr,
class_loader_context,
se_info_,
downgrade,
target_sdk_version,
profile_name_ptr,
dm_path_ptr,
compilation_reason_ptr);
profile_name,
dm_path,
compilation_reason);
ASSERT_EQ(should_binder_call_succeed, result.isOk()) << result.toString8().c_str();
int expected_access = should_dex_be_compiled ? 0 : -1;
std::string odex = GetSecondaryDexArtifact(path, "odex");
@ -481,41 +477,35 @@ protected:
bool downgrade,
bool should_binder_call_succeed,
/*out */ binder::Status* binder_result) {
std::unique_ptr<std::string> package_name_ptr(new std::string(package_name_));
std::unique_ptr<std::string> out_path(
oat_dir == nullptr ? nullptr : new std::string(oat_dir));
std::unique_ptr<std::string> class_loader_context_ptr(new std::string("&"));
std::unique_ptr<std::string> se_info_ptr(new std::string(se_info_));
std::optional<std::string> out_path = oat_dir ? std::make_optional<std::string>(oat_dir) : std::nullopt;
std::string class_loader_context = "&";
int32_t target_sdk_version = 0; // default
std::unique_ptr<std::string> profile_name_ptr(new std::string("primary.prof"));
std::unique_ptr<std::string> dm_path_ptr = nullptr;
if (dm_path != nullptr) {
dm_path_ptr.reset(new std::string(dm_path));
}
std::unique_ptr<std::string> compilation_reason_ptr(new std::string("test-reason"));
std::string profile_name = "primary.prof";
std::optional<std::string> dm_path_opt = dm_path ? std::make_optional<std::string>(dm_path) : std::nullopt;
std::string compilation_reason = "test-reason";
bool prof_result;
ASSERT_BINDER_SUCCESS(service_->prepareAppProfile(
package_name_, kTestUserId, kTestAppId, *profile_name_ptr, apk_path_,
dm_path_ptr, &prof_result));
package_name_, kTestUserId, kTestAppId, profile_name, apk_path_,
dm_path_opt, &prof_result));
ASSERT_TRUE(prof_result);
binder::Status result = service_->dexopt(apk_path_,
uid,
package_name_ptr,
package_name_,
kRuntimeIsa,
dexopt_needed,
out_path,
dex_flags,
compiler_filter,
volume_uuid_,
class_loader_context_ptr,
se_info_ptr,
class_loader_context,
se_info_,
downgrade,
target_sdk_version,
profile_name_ptr,
dm_path_ptr,
compilation_reason_ptr);
profile_name,
dm_path_opt,
compilation_reason);
ASSERT_EQ(should_binder_call_succeed, result.isOk()) << result.toString8().c_str();
if (!should_binder_call_succeed) {
@ -953,7 +943,7 @@ class ProfileTest : public DexoptTest {
bool result;
ASSERT_BINDER_SUCCESS(service_->prepareAppProfile(
package_name, kTestUserId, kTestAppId, profile_name, apk_path_,
/*dex_metadata*/ nullptr, &result));
/*dex_metadata*/ {}, &result));
ASSERT_EQ(expected_result, result);
if (!expected_result) {

View file

@ -99,15 +99,14 @@ static int stat_mode(const char* path) {
class ServiceTest : public testing::Test {
protected:
InstalldNativeService* service;
std::unique_ptr<std::string> testUuid;
std::optional<std::string> testUuid;
virtual void SetUp() {
setenv("ANDROID_LOG_TAGS", "*:v", 1);
android::base::InitLogging(nullptr);
service = new InstalldNativeService();
testUuid = std::make_unique<std::string>();
*testUuid = std::string(kTestUuid);
testUuid = kTestUuid;
system("mkdir -p /data/local/tmp/user/0");
init_globals_from_data_and_root();
@ -322,7 +321,7 @@ TEST_F(AppDataSnapshotTest, CreateAppDataSnapshot) {
// Request a snapshot of the CE content but not the DE content.
int64_t ce_snapshot_inode;
ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_unique<std::string>("TEST"),
ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_optional<std::string>("TEST"),
"com.foo", 0, 37, FLAG_STORAGE_CE, &ce_snapshot_inode));
struct stat buf;
memset(&buf, 0, sizeof(buf));
@ -344,7 +343,7 @@ TEST_F(AppDataSnapshotTest, CreateAppDataSnapshot) {
0700, 10000, 20000, false /* follow_symlinks */));
// Request a snapshot of the DE content but not the CE content.
ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_unique<std::string>("TEST"),
ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_optional<std::string>("TEST"),
"com.foo", 0, 37, FLAG_STORAGE_DE, &ce_snapshot_inode));
// Only DE content snapshot was requested.
ASSERT_EQ(ce_snapshot_inode, 0);
@ -365,7 +364,7 @@ TEST_F(AppDataSnapshotTest, CreateAppDataSnapshot) {
0700, 10000, 20000, false /* follow_symlinks */));
// Request a snapshot of both the CE as well as the DE content.
ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_unique<std::string>("TEST"),
ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_optional<std::string>("TEST"),
"com.foo", 0, 37, FLAG_STORAGE_DE | FLAG_STORAGE_CE, nullptr));
ASSERT_TRUE(android::base::ReadFileToString(
@ -407,10 +406,10 @@ TEST_F(AppDataSnapshotTest, CreateAppDataSnapshot_TwoSnapshotsWithTheSameId) {
0700, 10000, 20000, false /* follow_symlinks */));
// Request snapshot for the package com.foo.
ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_unique<std::string>("TEST"),
ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_optional<std::string>("TEST"),
"com.foo", 0, 67, FLAG_STORAGE_DE | FLAG_STORAGE_CE, nullptr));
// Now request snapshot with the same id for the package com.bar
ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_unique<std::string>("TEST"),
ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_optional<std::string>("TEST"),
"com.bar", 0, 67, FLAG_STORAGE_DE | FLAG_STORAGE_CE, nullptr));
// Check that both snapshots have correct data in them.
@ -439,9 +438,9 @@ TEST_F(AppDataSnapshotTest, CreateAppDataSnapshot_AppDataAbsent) {
ASSERT_EQ(0, delete_dir_contents_and_dir(fake_package_de_path, true));
int64_t ce_snapshot_inode;
ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_unique<std::string>("TEST"),
ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_optional<std::string>("TEST"),
"com.foo", 0, 73, FLAG_STORAGE_CE, &ce_snapshot_inode));
ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_unique<std::string>("TEST"),
ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_optional<std::string>("TEST"),
"com.foo", 0, 73, FLAG_STORAGE_DE, nullptr));
// No CE content snapshot was performed.
ASSERT_EQ(ce_snapshot_inode, 0);
@ -476,7 +475,7 @@ TEST_F(AppDataSnapshotTest, CreateAppDataSnapshot_ClearsExistingSnapshot) {
"TEST_CONTENT_2_DE", fake_package_de_path + "/file2",
0700, 10000, 20000, false /* follow_symlinks */));
ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_unique<std::string>("TEST"),
ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_optional<std::string>("TEST"),
"com.foo", 0, 13, FLAG_STORAGE_DE | FLAG_STORAGE_CE, nullptr));
// Previous snapshot (with data for file1) must be cleared.
@ -497,7 +496,7 @@ TEST_F(AppDataSnapshotTest, SnapshotAppData_WrongVolumeUuid) {
ASSERT_TRUE(mkdirs(rollback_ce_dir, 0700));
ASSERT_TRUE(mkdirs(rollback_de_dir, 0700));
EXPECT_BINDER_FAIL(service->snapshotAppData(std::make_unique<std::string>("FOO"),
EXPECT_BINDER_FAIL(service->snapshotAppData(std::make_optional<std::string>("FOO"),
"com.foo", 0, 17, FLAG_STORAGE_DE, nullptr));
}
@ -524,7 +523,7 @@ TEST_F(AppDataSnapshotTest, CreateAppDataSnapshot_ClearsCache) {
ASSERT_TRUE(android::base::WriteStringToFile(
"TEST_CONTENT_DE", fake_package_de_code_cache_path + "/file1",
0700, 10000, 20000, false /* follow_symlinks */));
ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_unique<std::string>("TEST"),
ASSERT_BINDER_SUCCESS(service->snapshotAppData(std::make_optional<std::string>("TEST"),
"com.foo", 0, 23, FLAG_STORAGE_CE | FLAG_STORAGE_DE, nullptr));
// The snapshot call must clear cache.
struct stat sb;
@ -558,7 +557,7 @@ TEST_F(AppDataSnapshotTest, RestoreAppDataSnapshot) {
"TEST_CONTENT_DE", fake_package_de_path + "/file1",
0700, 10000, 20000, false /* follow_symlinks */));
ASSERT_BINDER_SUCCESS(service->restoreAppDataSnapshot(std::make_unique<std::string>("TEST"),
ASSERT_BINDER_SUCCESS(service->restoreAppDataSnapshot(std::make_optional<std::string>("TEST"),
"com.foo", 10000, "", 0, 239, FLAG_STORAGE_DE | FLAG_STORAGE_CE));
std::string ce_content, de_content;
@ -584,7 +583,7 @@ TEST_F(AppDataSnapshotTest, CreateSnapshotThenDestroyIt) {
int64_t ce_snapshot_inode;
// Request a snapshot of both the CE as well as the DE content.
ASSERT_TRUE(service->snapshotAppData(std::make_unique<std::string>("TEST"),
ASSERT_TRUE(service->snapshotAppData(std::make_optional<std::string>("TEST"),
"com.foo", 0, 57, FLAG_STORAGE_DE | FLAG_STORAGE_CE, &ce_snapshot_inode).isOk());
// Because CE data snapshot was requested, ce_snapshot_inode can't be null.
ASSERT_NE(0, ce_snapshot_inode);
@ -594,7 +593,7 @@ TEST_F(AppDataSnapshotTest, CreateSnapshotThenDestroyIt) {
ASSERT_EQ(0, stat((rollback_de_dir + "/com.foo").c_str(), &sb));
ASSERT_TRUE(service->destroyAppDataSnapshot(std::make_unique<std::string>("TEST"),
ASSERT_TRUE(service->destroyAppDataSnapshot(std::make_optional<std::string>("TEST"),
"com.foo", 0, ce_snapshot_inode, 57, FLAG_STORAGE_DE | FLAG_STORAGE_CE).isOk());
// Check snapshot is deleted.
ASSERT_EQ(-1, stat((rollback_ce_dir + "/com.foo").c_str(), &sb));
@ -615,7 +614,7 @@ TEST_F(AppDataSnapshotTest, DestroyAppDataSnapshot_CeSnapshotInodeIsZero) {
"DE_RESTORE_CONTENT", rollback_de_dir + "/com.foo/file1",
0700, 10000, 20000, false /* follow_symlinks */));
ASSERT_TRUE(service->destroyAppDataSnapshot(std::make_unique<std::string>("TEST"),
ASSERT_TRUE(service->destroyAppDataSnapshot(std::make_optional<std::string>("TEST"),
"com.foo", 0, 0, 1543, FLAG_STORAGE_DE | FLAG_STORAGE_CE).isOk());
// Check snapshot is deleted.
@ -624,7 +623,7 @@ TEST_F(AppDataSnapshotTest, DestroyAppDataSnapshot_CeSnapshotInodeIsZero) {
ASSERT_EQ(-1, stat((rollback_de_dir + "/com.foo").c_str(), &sb));
// Check that deleting already deleted snapshot is no-op.
ASSERT_TRUE(service->destroyAppDataSnapshot(std::make_unique<std::string>("TEST"),
ASSERT_TRUE(service->destroyAppDataSnapshot(std::make_optional<std::string>("TEST"),
"com.foo", 0, 0, 1543, FLAG_STORAGE_DE | FLAG_STORAGE_CE).isOk());
}
@ -637,7 +636,7 @@ TEST_F(AppDataSnapshotTest, DestroyAppDataSnapshot_WrongVolumeUuid) {
ASSERT_TRUE(mkdirs(rollback_ce_dir, 0700));
ASSERT_TRUE(mkdirs(rollback_de_dir, 0700));
ASSERT_FALSE(service->destroyAppDataSnapshot(std::make_unique<std::string>("BAR"),
ASSERT_FALSE(service->destroyAppDataSnapshot(std::make_optional<std::string>("BAR"),
"com.foo", 0, 0, 43, FLAG_STORAGE_DE).isOk());
}
@ -650,7 +649,7 @@ TEST_F(AppDataSnapshotTest, RestoreAppDataSnapshot_WrongVolumeUuid) {
ASSERT_TRUE(mkdirs(rollback_ce_dir, 0700));
ASSERT_TRUE(mkdirs(rollback_de_dir, 0700));
EXPECT_BINDER_FAIL(service->restoreAppDataSnapshot(std::make_unique<std::string>("BAR"),
EXPECT_BINDER_FAIL(service->restoreAppDataSnapshot(std::make_optional<std::string>("BAR"),
"com.foo", 10000, "", 0, 41, FLAG_STORAGE_DE));
}

View file

@ -22,6 +22,8 @@
#include <binder/Parcel.h>
#include <utils/String8.h>
#include <optional>
namespace android {
// ----------------------------------------------------------------------

View file

@ -749,6 +749,13 @@ status_t Parcel::writeUtf8AsUtf16(const std::string& str) {
return NO_ERROR;
}
status_t Parcel::writeUtf8AsUtf16(const std::optional<std::string>& str) {
if (!str) {
return writeInt32(-1);
}
return writeUtf8AsUtf16(*str);
}
status_t Parcel::writeUtf8AsUtf16(const std::unique_ptr<std::string>& str) {
if (!str) {
return writeInt32(-1);
@ -773,6 +780,12 @@ status_t Parcel::writeByteVector(const std::vector<int8_t>& val) {
return writeByteVectorInternal(val.data(), val.size());
}
status_t Parcel::writeByteVector(const std::optional<std::vector<int8_t>>& val)
{
if (!val) return writeInt32(-1);
return writeByteVectorInternal(val->data(), val->size());
}
status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val)
{
if (!val) return writeInt32(-1);
@ -783,6 +796,12 @@ status_t Parcel::writeByteVector(const std::vector<uint8_t>& val) {
return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val.data()), val.size());
}
status_t Parcel::writeByteVector(const std::optional<std::vector<uint8_t>>& val)
{
if (!val) return writeInt32(-1);
return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), val->size());
}
status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val)
{
if (!val) return writeInt32(-1);
@ -794,6 +813,11 @@ status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val)
return writeTypedVector(val, &Parcel::writeInt32);
}
status_t Parcel::writeInt32Vector(const std::optional<std::vector<int32_t>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeInt32);
}
status_t Parcel::writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeInt32);
@ -804,6 +828,11 @@ status_t Parcel::writeInt64Vector(const std::vector<int64_t>& val)
return writeTypedVector(val, &Parcel::writeInt64);
}
status_t Parcel::writeInt64Vector(const std::optional<std::vector<int64_t>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeInt64);
}
status_t Parcel::writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeInt64);
@ -814,6 +843,11 @@ status_t Parcel::writeUint64Vector(const std::vector<uint64_t>& val)
return writeTypedVector(val, &Parcel::writeUint64);
}
status_t Parcel::writeUint64Vector(const std::optional<std::vector<uint64_t>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeUint64);
}
status_t Parcel::writeUint64Vector(const std::unique_ptr<std::vector<uint64_t>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeUint64);
@ -824,6 +858,11 @@ status_t Parcel::writeFloatVector(const std::vector<float>& val)
return writeTypedVector(val, &Parcel::writeFloat);
}
status_t Parcel::writeFloatVector(const std::optional<std::vector<float>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeFloat);
}
status_t Parcel::writeFloatVector(const std::unique_ptr<std::vector<float>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeFloat);
@ -834,6 +873,11 @@ status_t Parcel::writeDoubleVector(const std::vector<double>& val)
return writeTypedVector(val, &Parcel::writeDouble);
}
status_t Parcel::writeDoubleVector(const std::optional<std::vector<double>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeDouble);
}
status_t Parcel::writeDoubleVector(const std::unique_ptr<std::vector<double>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeDouble);
@ -844,6 +888,11 @@ status_t Parcel::writeBoolVector(const std::vector<bool>& val)
return writeTypedVector(val, &Parcel::writeBool);
}
status_t Parcel::writeBoolVector(const std::optional<std::vector<bool>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeBool);
}
status_t Parcel::writeBoolVector(const std::unique_ptr<std::vector<bool>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeBool);
@ -854,6 +903,11 @@ status_t Parcel::writeCharVector(const std::vector<char16_t>& val)
return writeTypedVector(val, &Parcel::writeChar);
}
status_t Parcel::writeCharVector(const std::optional<std::vector<char16_t>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeChar);
}
status_t Parcel::writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeChar);
@ -864,12 +918,23 @@ status_t Parcel::writeString16Vector(const std::vector<String16>& val)
return writeTypedVector(val, &Parcel::writeString16);
}
status_t Parcel::writeString16Vector(
const std::optional<std::vector<std::optional<String16>>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeString16);
}
status_t Parcel::writeString16Vector(
const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeString16);
}
status_t Parcel::writeUtf8VectorAsUtf16Vector(
const std::optional<std::vector<std::optional<std::string>>>& val) {
return writeNullableTypedVector(val, &Parcel::writeUtf8AsUtf16);
}
status_t Parcel::writeUtf8VectorAsUtf16Vector(
const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& val) {
return writeNullableTypedVector(val, &Parcel::writeUtf8AsUtf16);
@ -995,6 +1060,15 @@ status_t Parcel::writeString8(const String8& str)
return err;
}
status_t Parcel::writeString16(const std::optional<String16>& str)
{
if (!str) {
return writeInt32(-1);
}
return writeString16(*str);
}
status_t Parcel::writeString16(const std::unique_ptr<String16>& str)
{
if (!str) {
@ -1037,11 +1111,20 @@ status_t Parcel::writeStrongBinderVector(const std::vector<sp<IBinder>>& val)
return writeTypedVector(val, &Parcel::writeStrongBinder);
}
status_t Parcel::writeStrongBinderVector(const std::optional<std::vector<sp<IBinder>>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeStrongBinder);
}
status_t Parcel::writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val)
{
return writeNullableTypedVector(val, &Parcel::writeStrongBinder);
}
status_t Parcel::readStrongBinderVector(std::optional<std::vector<sp<IBinder>>>* val) const {
return readNullableTypedVector(val, &Parcel::readNullableStrongBinder);
}
status_t Parcel::readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const {
return readNullableTypedVector(val, &Parcel::readNullableStrongBinder);
}
@ -1140,6 +1223,10 @@ status_t Parcel::writeUniqueFileDescriptorVector(const std::vector<base::unique_
return writeTypedVector(val, &Parcel::writeUniqueFileDescriptor);
}
status_t Parcel::writeUniqueFileDescriptorVector(const std::optional<std::vector<base::unique_fd>>& val) {
return writeNullableTypedVector(val, &Parcel::writeUniqueFileDescriptor);
}
status_t Parcel::writeUniqueFileDescriptorVector(const std::unique_ptr<std::vector<base::unique_fd>>& val) {
return writeNullableTypedVector(val, &Parcel::writeUniqueFileDescriptor);
}
@ -1471,6 +1558,17 @@ status_t Parcel::readByteVector(std::vector<uint8_t>* val) const {
return readByteVectorInternal(val, size);
}
status_t Parcel::readByteVector(std::optional<std::vector<int8_t>>* val) const {
size_t size;
if (status_t status = reserveOutVector(val, &size); status != OK) return status;
if (!*val) {
// reserveOutVector does not create the out vector if size is < 0.
// This occurs when writing a null byte vector.
return OK;
}
return readByteVectorInternal(&**val, size);
}
status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const {
size_t size;
if (status_t status = reserveOutVector(val, &size); status != OK) return status;
@ -1482,6 +1580,17 @@ status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const
return readByteVectorInternal(val->get(), size);
}
status_t Parcel::readByteVector(std::optional<std::vector<uint8_t>>* val) const {
size_t size;
if (status_t status = reserveOutVector(val, &size); status != OK) return status;
if (!*val) {
// reserveOutVector does not create the out vector if size is < 0.
// This occurs when writing a null byte vector.
return OK;
}
return readByteVectorInternal(&**val, size);
}
status_t Parcel::readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const {
size_t size;
if (status_t status = reserveOutVector(val, &size); status != OK) return status;
@ -1493,6 +1602,10 @@ status_t Parcel::readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) cons
return readByteVectorInternal(val->get(), size);
}
status_t Parcel::readInt32Vector(std::optional<std::vector<int32_t>>* val) const {
return readNullableTypedVector(val, &Parcel::readInt32);
}
status_t Parcel::readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const {
return readNullableTypedVector(val, &Parcel::readInt32);
}
@ -1501,6 +1614,10 @@ status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const {
return readTypedVector(val, &Parcel::readInt32);
}
status_t Parcel::readInt64Vector(std::optional<std::vector<int64_t>>* val) const {
return readNullableTypedVector(val, &Parcel::readInt64);
}
status_t Parcel::readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const {
return readNullableTypedVector(val, &Parcel::readInt64);
}
@ -1509,6 +1626,10 @@ status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const {
return readTypedVector(val, &Parcel::readInt64);
}
status_t Parcel::readUint64Vector(std::optional<std::vector<uint64_t>>* val) const {
return readNullableTypedVector(val, &Parcel::readUint64);
}
status_t Parcel::readUint64Vector(std::unique_ptr<std::vector<uint64_t>>* val) const {
return readNullableTypedVector(val, &Parcel::readUint64);
}
@ -1517,6 +1638,10 @@ status_t Parcel::readUint64Vector(std::vector<uint64_t>* val) const {
return readTypedVector(val, &Parcel::readUint64);
}
status_t Parcel::readFloatVector(std::optional<std::vector<float>>* val) const {
return readNullableTypedVector(val, &Parcel::readFloat);
}
status_t Parcel::readFloatVector(std::unique_ptr<std::vector<float>>* val) const {
return readNullableTypedVector(val, &Parcel::readFloat);
}
@ -1525,6 +1650,10 @@ status_t Parcel::readFloatVector(std::vector<float>* val) const {
return readTypedVector(val, &Parcel::readFloat);
}
status_t Parcel::readDoubleVector(std::optional<std::vector<double>>* val) const {
return readNullableTypedVector(val, &Parcel::readDouble);
}
status_t Parcel::readDoubleVector(std::unique_ptr<std::vector<double>>* val) const {
return readNullableTypedVector(val, &Parcel::readDouble);
}
@ -1533,6 +1662,28 @@ status_t Parcel::readDoubleVector(std::vector<double>* val) const {
return readTypedVector(val, &Parcel::readDouble);
}
status_t Parcel::readBoolVector(std::optional<std::vector<bool>>* val) const {
const int32_t start = dataPosition();
int32_t size;
status_t status = readInt32(&size);
val->reset();
if (status != OK || size < 0) {
return status;
}
setDataPosition(start);
val->emplace();
status = readBoolVector(&**val);
if (status != OK) {
val->reset();
}
return status;
}
status_t Parcel::readBoolVector(std::unique_ptr<std::vector<bool>>* val) const {
const int32_t start = dataPosition();
int32_t size;
@ -1585,6 +1736,10 @@ status_t Parcel::readBoolVector(std::vector<bool>* val) const {
return OK;
}
status_t Parcel::readCharVector(std::optional<std::vector<char16_t>>* val) const {
return readNullableTypedVector(val, &Parcel::readChar);
}
status_t Parcel::readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const {
return readNullableTypedVector(val, &Parcel::readChar);
}
@ -1593,6 +1748,11 @@ status_t Parcel::readCharVector(std::vector<char16_t>* val) const {
return readTypedVector(val, &Parcel::readChar);
}
status_t Parcel::readString16Vector(
std::optional<std::vector<std::optional<String16>>>* val) const {
return readNullableTypedVector(val, &Parcel::readString16);
}
status_t Parcel::readString16Vector(
std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const {
return readNullableTypedVector(val, &Parcel::readString16);
@ -1602,6 +1762,11 @@ status_t Parcel::readString16Vector(std::vector<String16>* val) const {
return readTypedVector(val, &Parcel::readString16);
}
status_t Parcel::readUtf8VectorFromUtf16Vector(
std::optional<std::vector<std::optional<std::string>>>* val) const {
return readNullableTypedVector(val, &Parcel::readUtf8FromUtf16);
}
status_t Parcel::readUtf8VectorFromUtf16Vector(
std::unique_ptr<std::vector<std::unique_ptr<std::string>>>* val) const {
return readNullableTypedVector(val, &Parcel::readUtf8FromUtf16);
@ -1794,6 +1959,21 @@ status_t Parcel::readUtf8FromUtf16(std::string* str) const {
return NO_ERROR;
}
status_t Parcel::readUtf8FromUtf16(std::optional<std::string>* str) const {
const int32_t start = dataPosition();
int32_t size;
status_t status = readInt32(&size);
str->reset();
if (status != OK || size < 0) {
return status;
}
setDataPosition(start);
str->emplace();
return readUtf8FromUtf16(&**str);
}
status_t Parcel::readUtf8FromUtf16(std::unique_ptr<std::string>* str) const {
const int32_t start = dataPosition();
int32_t size;
@ -1870,6 +2050,29 @@ String16 Parcel::readString16() const
return String16();
}
status_t Parcel::readString16(std::optional<String16>* pArg) const
{
const int32_t start = dataPosition();
int32_t size;
status_t status = readInt32(&size);
pArg->reset();
if (status != OK || size < 0) {
return status;
}
setDataPosition(start);
pArg->emplace();
status = readString16(&**pArg);
if (status != OK) {
pArg->reset();
}
return status;
}
status_t Parcel::readString16(std::unique_ptr<String16>* pArg) const
{
const int32_t start = dataPosition();
@ -2075,6 +2278,10 @@ status_t Parcel::readUniqueParcelFileDescriptor(base::unique_fd* val) const
return OK;
}
status_t Parcel::readUniqueFileDescriptorVector(std::optional<std::vector<base::unique_fd>>* val) const {
return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
}
status_t Parcel::readUniqueFileDescriptorVector(std::unique_ptr<std::vector<base::unique_fd>>* val) const {
return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
}

View file

@ -120,6 +120,7 @@ public:
status_t writeCString(const char* str);
status_t writeString8(const String8& str);
status_t writeString16(const String16& str);
status_t writeString16(const std::optional<String16>& str);
status_t writeString16(const std::unique_ptr<String16>& str);
status_t writeString16(const char16_t* str, size_t len);
status_t writeStrongBinder(const sp<IBinder>& val);
@ -131,33 +132,48 @@ public:
// Take a UTF8 encoded string, convert to UTF16, write it to the parcel.
status_t writeUtf8AsUtf16(const std::string& str);
status_t writeUtf8AsUtf16(const std::optional<std::string>& str);
status_t writeUtf8AsUtf16(const std::unique_ptr<std::string>& str);
status_t writeByteVector(const std::optional<std::vector<int8_t>>& val);
status_t writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val);
status_t writeByteVector(const std::vector<int8_t>& val);
status_t writeByteVector(const std::optional<std::vector<uint8_t>>& val);
status_t writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val);
status_t writeByteVector(const std::vector<uint8_t>& val);
status_t writeInt32Vector(const std::optional<std::vector<int32_t>>& val);
status_t writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val);
status_t writeInt32Vector(const std::vector<int32_t>& val);
status_t writeInt64Vector(const std::optional<std::vector<int64_t>>& val);
status_t writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val);
status_t writeInt64Vector(const std::vector<int64_t>& val);
status_t writeUint64Vector(const std::optional<std::vector<uint64_t>>& val);
status_t writeUint64Vector(const std::unique_ptr<std::vector<uint64_t>>& val);
status_t writeUint64Vector(const std::vector<uint64_t>& val);
status_t writeFloatVector(const std::optional<std::vector<float>>& val);
status_t writeFloatVector(const std::unique_ptr<std::vector<float>>& val);
status_t writeFloatVector(const std::vector<float>& val);
status_t writeDoubleVector(const std::optional<std::vector<double>>& val);
status_t writeDoubleVector(const std::unique_ptr<std::vector<double>>& val);
status_t writeDoubleVector(const std::vector<double>& val);
status_t writeBoolVector(const std::optional<std::vector<bool>>& val);
status_t writeBoolVector(const std::unique_ptr<std::vector<bool>>& val);
status_t writeBoolVector(const std::vector<bool>& val);
status_t writeCharVector(const std::optional<std::vector<char16_t>>& val);
status_t writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val);
status_t writeCharVector(const std::vector<char16_t>& val);
status_t writeString16Vector(
const std::optional<std::vector<std::optional<String16>>>& val);
status_t writeString16Vector(
const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val);
status_t writeString16Vector(const std::vector<String16>& val);
status_t writeUtf8VectorAsUtf16Vector(
const std::optional<std::vector<std::optional<std::string>>>& val);
status_t writeUtf8VectorAsUtf16Vector(
const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& val);
status_t writeUtf8VectorAsUtf16Vector(const std::vector<std::string>& val);
status_t writeStrongBinderVector(const std::optional<std::vector<sp<IBinder>>>& val);
status_t writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val);
status_t writeStrongBinderVector(const std::vector<sp<IBinder>>& val);
@ -166,13 +182,19 @@ public:
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> = 0>
status_t writeEnumVector(const std::vector<T>& val);
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> = 0>
status_t writeEnumVector(const std::optional<std::vector<T>>& val);
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> = 0>
status_t writeEnumVector(const std::unique_ptr<std::vector<T>>& val);
// Write an Enum vector with underlying type != int8_t.
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> = 0>
status_t writeEnumVector(const std::vector<T>& val);
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> = 0>
status_t writeEnumVector(const std::optional<std::vector<T>>& val);
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> = 0>
status_t writeEnumVector(const std::unique_ptr<std::vector<T>>& val);
template<typename T>
status_t writeParcelableVector(const std::optional<std::vector<std::optional<T>>>& val);
template<typename T>
status_t writeParcelableVector(const std::unique_ptr<std::vector<std::unique_ptr<T>>>& val);
template<typename T>
@ -180,6 +202,8 @@ public:
template<typename T>
status_t writeParcelableVector(const std::vector<T>& val);
template<typename T>
status_t writeNullableParcelable(const std::optional<T>& parcelable);
template<typename T>
status_t writeNullableParcelable(const std::unique_ptr<T>& parcelable);
@ -194,6 +218,8 @@ public:
template<typename T>
status_t writeVectorSize(const std::vector<T>& val);
template<typename T>
status_t writeVectorSize(const std::optional<std::vector<T>>& val);
template<typename T>
status_t writeVectorSize(const std::unique_ptr<std::vector<T>>& val);
// Place a native_handle into the parcel (the native_handle's file-
@ -228,6 +254,8 @@ public:
// Place a vector of file desciptors into the parcel. Each descriptor is
// dup'd as in writeDupFileDescriptor
status_t writeUniqueFileDescriptorVector(
const std::optional<std::vector<base::unique_fd>>& val);
status_t writeUniqueFileDescriptorVector(
const std::unique_ptr<std::vector<base::unique_fd>>& val);
status_t writeUniqueFileDescriptorVector(
@ -278,6 +306,7 @@ public:
// Read a UTF16 encoded string, convert to UTF8
status_t readUtf8FromUtf16(std::string* str) const;
status_t readUtf8FromUtf16(std::optional<std::string>* str) const;
status_t readUtf8FromUtf16(std::unique_ptr<std::string>* str) const;
const char* readCString() const;
@ -285,25 +314,32 @@ public:
status_t readString8(String8* pArg) const;
String16 readString16() const;
status_t readString16(String16* pArg) const;
status_t readString16(std::optional<String16>* pArg) const;
status_t readString16(std::unique_ptr<String16>* pArg) const;
const char16_t* readString16Inplace(size_t* outLen) const;
sp<IBinder> readStrongBinder() const;
status_t readStrongBinder(sp<IBinder>* val) const;
status_t readNullableStrongBinder(sp<IBinder>* val) const;
// Read an Enum vector with underlying type int8_t.
// Does not use padding; each byte is contiguous.
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> = 0>
status_t readEnumVector(std::vector<T>* val) const;
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> = 0>
status_t readEnumVector(std::unique_ptr<std::vector<T>>* val) const;
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> = 0>
status_t readEnumVector(std::optional<std::vector<T>>* val) const;
// Read an Enum vector with underlying type != int8_t.
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> = 0>
status_t readEnumVector(std::vector<T>* val) const;
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> = 0>
status_t readEnumVector(std::unique_ptr<std::vector<T>>* val) const;
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> = 0>
status_t readEnumVector(std::optional<std::vector<T>>* val) const;
template<typename T>
status_t readParcelableVector(
std::optional<std::vector<std::optional<T>>>* val) const;
template<typename T>
status_t readParcelableVector(
std::unique_ptr<std::vector<std::unique_ptr<T>>>* val) const;
@ -312,6 +348,8 @@ public:
status_t readParcelable(Parcelable* parcelable) const;
template<typename T>
status_t readParcelable(std::optional<T>* parcelable) const;
template<typename T>
status_t readParcelable(std::unique_ptr<T>* parcelable) const;
@ -321,30 +359,44 @@ public:
template<typename T>
status_t readNullableStrongBinder(sp<T>* val) const;
status_t readStrongBinderVector(std::optional<std::vector<sp<IBinder>>>* val) const;
status_t readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const;
status_t readStrongBinderVector(std::vector<sp<IBinder>>* val) const;
status_t readByteVector(std::optional<std::vector<int8_t>>* val) const;
status_t readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const;
status_t readByteVector(std::vector<int8_t>* val) const;
status_t readByteVector(std::optional<std::vector<uint8_t>>* val) const;
status_t readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const;
status_t readByteVector(std::vector<uint8_t>* val) const;
status_t readInt32Vector(std::optional<std::vector<int32_t>>* val) const;
status_t readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const;
status_t readInt32Vector(std::vector<int32_t>* val) const;
status_t readInt64Vector(std::optional<std::vector<int64_t>>* val) const;
status_t readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const;
status_t readInt64Vector(std::vector<int64_t>* val) const;
status_t readUint64Vector(std::optional<std::vector<uint64_t>>* val) const;
status_t readUint64Vector(std::unique_ptr<std::vector<uint64_t>>* val) const;
status_t readUint64Vector(std::vector<uint64_t>* val) const;
status_t readFloatVector(std::optional<std::vector<float>>* val) const;
status_t readFloatVector(std::unique_ptr<std::vector<float>>* val) const;
status_t readFloatVector(std::vector<float>* val) const;
status_t readDoubleVector(std::optional<std::vector<double>>* val) const;
status_t readDoubleVector(std::unique_ptr<std::vector<double>>* val) const;
status_t readDoubleVector(std::vector<double>* val) const;
status_t readBoolVector(std::optional<std::vector<bool>>* val) const;
status_t readBoolVector(std::unique_ptr<std::vector<bool>>* val) const;
status_t readBoolVector(std::vector<bool>* val) const;
status_t readCharVector(std::optional<std::vector<char16_t>>* val) const;
status_t readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const;
status_t readCharVector(std::vector<char16_t>* val) const;
status_t readString16Vector(
std::optional<std::vector<std::optional<String16>>>* val) const;
status_t readString16Vector(
std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const;
status_t readString16Vector(std::vector<String16>* val) const;
status_t readUtf8VectorFromUtf16Vector(
std::optional<std::vector<std::optional<std::string>>>* val) const;
status_t readUtf8VectorFromUtf16Vector(
std::unique_ptr<std::vector<std::unique_ptr<std::string>>>* val) const;
status_t readUtf8VectorFromUtf16Vector(std::vector<std::string>* val) const;
@ -358,10 +410,15 @@ public:
template<typename T>
status_t resizeOutVector(std::vector<T>* val) const;
template<typename T>
status_t resizeOutVector(std::optional<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::optional<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;
@ -396,6 +453,8 @@ public:
// Retrieve a vector of smart file descriptors from the parcel.
status_t readUniqueFileDescriptorVector(
std::optional<std::vector<base::unique_fd>>* val) const;
status_t readUniqueFileDescriptorVector(
std::unique_ptr<std::vector<base::unique_fd>>* val) const;
status_t readUniqueFileDescriptorVector(
@ -490,6 +549,9 @@ private:
status_t unsafeReadTypedVector(std::vector<T>* val,
status_t(Parcel::*read_func)(U*) const) const;
template<typename T>
status_t readNullableTypedVector(std::optional<std::vector<T>>* val,
status_t(Parcel::*read_func)(T*) const) const;
template<typename T>
status_t readNullableTypedVector(std::unique_ptr<std::vector<T>>* val,
status_t(Parcel::*read_func)(T*) const) const;
template<typename T>
@ -499,9 +561,15 @@ private:
status_t unsafeWriteTypedVector(const std::vector<T>& val,
status_t(Parcel::*write_func)(U));
template<typename T>
status_t writeNullableTypedVector(const std::optional<std::vector<T>>& val,
status_t(Parcel::*write_func)(const T&));
template<typename T>
status_t writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
status_t(Parcel::*write_func)(const T&));
template<typename T>
status_t writeNullableTypedVector(const std::optional<std::vector<T>>& val,
status_t(Parcel::*write_func)(T));
template<typename T>
status_t writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
status_t(Parcel::*write_func)(T));
template<typename T>
@ -688,6 +756,15 @@ status_t Parcel::writeVectorSize(const std::vector<T>& val) {
return writeInt32(static_cast<int32_t>(val.size()));
}
template<typename T>
status_t Parcel::writeVectorSize(const std::optional<std::vector<T>>& val) {
if (!val) {
return writeInt32(-1);
}
return writeVectorSize(*val);
}
template<typename T>
status_t Parcel::writeVectorSize(const std::unique_ptr<std::vector<T>>& val) {
if (!val) {
@ -712,6 +789,22 @@ status_t Parcel::resizeOutVector(std::vector<T>* val) const {
return OK;
}
template<typename T>
status_t Parcel::resizeOutVector(std::optional<std::vector<T>>* val) const {
int32_t size;
status_t err = readInt32(&size);
if (err != NO_ERROR) {
return err;
}
val->reset();
if (size >= 0) {
val->emplace(size_t(size));
}
return OK;
}
template<typename T>
status_t Parcel::resizeOutVector(std::unique_ptr<std::vector<T>>* val) const {
int32_t size;
@ -744,6 +837,25 @@ status_t Parcel::reserveOutVector(std::vector<T>* val, size_t* size) const {
return OK;
}
template<typename T>
status_t Parcel::reserveOutVector(std::optional<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->emplace();
(*val)->reserve(*size);
} else {
val->reset();
}
return OK;
}
template<typename T>
status_t Parcel::reserveOutVector(std::unique_ptr<std::vector<T>>* val,
size_t* size) const {
@ -838,6 +950,30 @@ status_t Parcel::readTypedVector(std::vector<T>* val,
return unsafeReadTypedVector(val, read_func);
}
template<typename T>
status_t Parcel::readNullableTypedVector(std::optional<std::vector<T>>* val,
status_t(Parcel::*read_func)(T*) const) const {
const size_t start = dataPosition();
int32_t size;
status_t status = readInt32(&size);
val->reset();
if (status != OK || size < 0) {
return status;
}
setDataPosition(start);
val->emplace();
status = unsafeReadTypedVector(&**val, read_func);
if (status != OK) {
val->reset();
}
return status;
}
template<typename T>
status_t Parcel::readNullableTypedVector(std::unique_ptr<std::vector<T>>* val,
status_t(Parcel::*read_func)(T*) const) const {
@ -898,6 +1034,16 @@ status_t Parcel::writeTypedVector(const std::vector<T>& val,
return unsafeWriteTypedVector(val, write_func);
}
template<typename T>
status_t Parcel::writeNullableTypedVector(const std::optional<std::vector<T>>& val,
status_t(Parcel::*write_func)(const T&)) {
if (!val) {
return this->writeInt32(-1);
}
return unsafeWriteTypedVector(*val, write_func);
}
template<typename T>
status_t Parcel::writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
status_t(Parcel::*write_func)(const T&)) {
@ -908,6 +1054,16 @@ status_t Parcel::writeNullableTypedVector(const std::unique_ptr<std::vector<T>>&
return unsafeWriteTypedVector(*val, write_func);
}
template<typename T>
status_t Parcel::writeNullableTypedVector(const std::optional<std::vector<T>>& val,
status_t(Parcel::*write_func)(T)) {
if (!val) {
return this->writeInt32(-1);
}
return unsafeWriteTypedVector(*val, write_func);
}
template<typename T>
status_t Parcel::writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& val,
status_t(Parcel::*write_func)(T)) {
@ -923,6 +1079,30 @@ status_t Parcel::readParcelableVector(std::vector<T>* val) const {
return unsafeReadTypedVector<T, Parcelable>(val, &Parcel::readParcelable);
}
template<typename T>
status_t Parcel::readParcelableVector(std::optional<std::vector<std::optional<T>>>* val) const {
const size_t start = dataPosition();
int32_t size;
status_t status = readInt32(&size);
val->reset();
if (status != OK || size < 0) {
return status;
}
setDataPosition(start);
val->emplace();
using NullableT = std::optional<T>;
status = unsafeReadTypedVector<NullableT, NullableT>(&**val, &Parcel::readParcelable);
if (status != OK) {
val->reset();
}
return status;
}
template<typename T>
status_t Parcel::readParcelableVector(std::unique_ptr<std::vector<std::unique_ptr<T>>>* val) const {
const size_t start = dataPosition();
@ -937,7 +1117,8 @@ status_t Parcel::readParcelableVector(std::unique_ptr<std::vector<std::unique_pt
setDataPosition(start);
val->reset(new std::vector<std::unique_ptr<T>>());
status = unsafeReadTypedVector(val->get(), &Parcel::readParcelable<T>);
using NullableT = std::unique_ptr<T>;
status = unsafeReadTypedVector<NullableT, NullableT>(val->get(), &Parcel::readParcelable);
if (status != OK) {
val->reset();
@ -946,6 +1127,29 @@ status_t Parcel::readParcelableVector(std::unique_ptr<std::vector<std::unique_pt
return status;
}
template<typename T>
status_t Parcel::readParcelable(std::optional<T>* parcelable) const {
const size_t start = dataPosition();
int32_t present;
status_t status = readInt32(&present);
parcelable->reset();
if (status != OK || !present) {
return status;
}
setDataPosition(start);
parcelable->emplace();
status = readParcelable(&**parcelable);
if (status != OK) {
parcelable->reset();
}
return status;
}
template<typename T>
status_t Parcel::readParcelable(std::unique_ptr<T>* parcelable) const {
const size_t start = dataPosition();
@ -969,6 +1173,11 @@ status_t Parcel::readParcelable(std::unique_ptr<T>* parcelable) const {
return status;
}
template<typename T>
status_t Parcel::writeNullableParcelable(const std::optional<T>& parcelable) {
return writeRawNullableParcelable(parcelable ? &*parcelable : nullptr);
}
template<typename T>
status_t Parcel::writeNullableParcelable(const std::unique_ptr<T>& parcelable) {
return writeRawNullableParcelable(parcelable.get());
@ -979,6 +1188,16 @@ status_t Parcel::writeParcelableVector(const std::vector<T>& val) {
return unsafeWriteTypedVector<T,const Parcelable&>(val, &Parcel::writeParcelable);
}
template<typename T>
status_t Parcel::writeParcelableVector(const std::optional<std::vector<std::optional<T>>>& val) {
if (!val) {
return this->writeInt32(-1);
}
using NullableT = std::optional<T>;
return unsafeWriteTypedVector<NullableT, const NullableT&>(*val, &Parcel::writeNullableParcelable);
}
template<typename T>
status_t Parcel::writeParcelableVector(const std::unique_ptr<std::vector<std::unique_ptr<T>>>& val) {
if (val.get() == nullptr) {
@ -994,7 +1213,8 @@ status_t Parcel::writeParcelableVector(const std::shared_ptr<std::vector<std::un
return this->writeInt32(-1);
}
return unsafeWriteTypedVector(*val, &Parcel::writeNullableParcelable<T>);
using NullableT = std::unique_ptr<T>;
return unsafeWriteTypedVector<NullableT, const NullableT&>(*val, &Parcel::writeNullableParcelable);
}
template<typename T, std::enable_if_t<std::is_same_v<typename std::underlying_type_t<T>,int32_t>, bool>>
@ -1011,6 +1231,11 @@ status_t Parcel::writeEnumVector(const std::vector<T>& val) {
return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val.data()), 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::writeEnumVector(const std::optional<std::vector<T>>& val) {
if (!val) return writeInt32(-1);
return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), 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::writeEnumVector(const std::unique_ptr<std::vector<T>>& val) {
if (!val) return writeInt32(-1);
return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), val->size());
@ -1020,6 +1245,10 @@ status_t Parcel::writeEnumVector(const std::vector<T>& val) {
return writeTypedVector(val, &Parcel::writeEnum);
}
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::writeEnumVector(const std::optional<std::vector<T>>& val) {
return writeNullableTypedVector(val, &Parcel::writeEnum);
}
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::writeEnumVector(const std::unique_ptr<std::vector<T>>& val) {
return writeNullableTypedVector(val, &Parcel::writeEnum);
}
@ -1051,6 +1280,17 @@ status_t Parcel::readEnumVector(std::vector<T>* val) const {
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::optional<std::vector<T>>* val) const {
size_t size;
if (status_t status = reserveOutVector(val, &size); status != OK) return status;
if (!*val) {
// reserveOutVector does not create the out vector if size is < 0.
// This occurs when writing a null Enum vector.
return OK;
}
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 {
size_t size;
if (status_t status = reserveOutVector(val, &size); status != OK) return status;
@ -1066,6 +1306,10 @@ status_t Parcel::readEnumVector(std::vector<T>* val) const {
return readTypedVector(val, &Parcel::readEnum);
}
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::optional<std::vector<T>>* val) const {
return readNullableTypedVector(val, &Parcel::readEnum);
}
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 {
return readNullableTypedVector(val, &Parcel::readEnum);
}

View file

@ -32,6 +32,7 @@ public:
ParcelFileDescriptor();
explicit ParcelFileDescriptor(android::base::unique_fd fd);
ParcelFileDescriptor(ParcelFileDescriptor&& other) : mFd(std::move(other.mFd)) { }
ParcelFileDescriptor& operator=(ParcelFileDescriptor&& other) = default;
~ParcelFileDescriptor() override;
int get() const { return mFd.get(); }