diff options
author | 2020-01-23 12:45:10 +0900 | |
---|---|---|
committer | 2020-02-26 04:00:15 +0000 | |
commit | 2d5878e69b6df009a936ab29710ef00673bb7b0a (patch) | |
tree | 1892ed9c2d147f7af66051d9792bb50b675ebce7 | |
parent | 331af0119f577cfe409be88363b0ff7864ec3d60 (diff) |
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 149be4a25ef423491c73dfc7bfd95e8177e9b4f8)
Exempt-From-Owner-Approval: CP from master
-rw-r--r-- | cmds/installd/CrateManager.cpp | 24 | ||||
-rw-r--r-- | cmds/installd/CrateManager.h | 10 | ||||
-rw-r--r-- | cmds/installd/InstalldNativeService.cpp | 129 | ||||
-rw-r--r-- | cmds/installd/InstalldNativeService.h | 78 | ||||
-rw-r--r-- | cmds/installd/dexopt.cpp | 12 | ||||
-rw-r--r-- | cmds/installd/dexopt.h | 8 | ||||
-rw-r--r-- | cmds/installd/tests/installd_cache_test.cpp | 5 | ||||
-rw-r--r-- | cmds/installd/tests/installd_dexopt_test.cpp | 64 | ||||
-rw-r--r-- | cmds/installd/tests/installd_service_test.cpp | 39 | ||||
-rw-r--r-- | libs/binder/AppOpsManager.cpp | 12 | ||||
-rw-r--r-- | libs/binder/IAppOpsService.cpp | 14 | ||||
-rw-r--r-- | libs/binder/Parcel.cpp | 207 | ||||
-rw-r--r-- | libs/binder/include/binder/AppOpsManager.h | 8 | ||||
-rw-r--r-- | libs/binder/include/binder/IAppOpsService.h | 8 | ||||
-rw-r--r-- | libs/binder/include/binder/Parcel.h | 250 | ||||
-rw-r--r-- | libs/binder/include/binder/ParcelFileDescriptor.h | 1 |
16 files changed, 658 insertions, 211 deletions
diff --git a/cmds/installd/CrateManager.cpp b/cmds/installd/CrateManager.cpp index 6e079ebbf3..b17cba15d5 100644 --- a/cmds/installd/CrateManager.cpp +++ b/cmds/installd/CrateManager.cpp @@ -86,7 +86,7 @@ void CrateManager::traverseChildDir(const std::string& targetDir, } void CrateManager::traverseAllPackagesForUser( - const std::unique_ptr<std::string>& uuid, userid_t userId, + const std::optional<std::string>& uuid, userid_t userId, std::function<void(FTSENT*)>& onHandlingPackage) { const char* uuid_ = uuid ? uuid->c_str() : nullptr; @@ -96,21 +96,21 @@ void CrateManager::traverseAllPackagesForUser( void CrateManager::createCrate( CratedFolder cratedFolder, - std::function<void(CratedFolder, std::unique_ptr<CrateMetadata>&)>& onCreateCrate) { + std::function<void(CratedFolder, CrateMetadata&&)>& onCreateCrate) { const char* path = cratedFolder->fts_path; if (path == nullptr || *path == '\0') { return; } - std::unique_ptr<CrateMetadata> crateMetadata = std::make_unique<CrateMetadata>(); - crateMetadata->uid = cratedFolder->fts_statp->st_uid; - crateMetadata->packageName = mPackageName; - crateMetadata->id = getValidatedCratedPath(path); + CrateMetadata crateMetadata; + crateMetadata.uid = cratedFolder->fts_statp->st_uid; + crateMetadata.packageName = mPackageName; + crateMetadata.id = getValidatedCratedPath(path); - onCreateCrate(cratedFolder, crateMetadata); + onCreateCrate(cratedFolder, std::move(crateMetadata)); } -void CrateManager::traverseAllCrates(std::function<void(CratedFolder, std::unique_ptr<CrateMetadata>&)>& onCreateCrate) { +void CrateManager::traverseAllCrates(std::function<void(CratedFolder, CrateMetadata&&)>& onCreateCrate) { std::function<void(FTSENT*)> onVisitCrateDir = [&](FTSENT* cratedFolder) -> void { createCrate(cratedFolder, onCreateCrate); }; @@ -118,11 +118,11 @@ void CrateManager::traverseAllCrates(std::function<void(CratedFolder, std::uniqu } #if CRATE_DEBUG -void CrateManager::dump(std::unique_ptr<CrateMetadata>& CrateMetadata) { +void CrateManager::dump(const CrateMetadata& CrateMetadata) { LOG(DEBUG) << "CrateMetadata = {" - << "uid : \"" << CrateMetadata->uid - << "\", packageName : \"" << CrateMetadata->packageName - << "\", id : \"" << CrateMetadata->id + << "uid : \"" << CrateMetadata.uid + << "\", packageName : \"" << CrateMetadata.packageName + << "\", id : \"" << CrateMetadata.id << "\"}"; } #endif diff --git a/cmds/installd/CrateManager.h b/cmds/installd/CrateManager.h index 4332d4cbc9..1f30b5dc79 100644 --- a/cmds/installd/CrateManager.h +++ b/cmds/installd/CrateManager.h @@ -25,7 +25,7 @@ #include <sys/stat.h> #include <sys/types.h> -#include <memory> +#include <optional> #include <string> #include <vector> @@ -55,18 +55,18 @@ public: CrateManager(const char* uuid, userid_t userId, const std::string& packageName); ~CrateManager(); - void traverseAllCrates(std::function<void(CratedFolder, std::unique_ptr<CrateMetadata>&)>& onCreateCrate); + void traverseAllCrates(std::function<void(CratedFolder, CrateMetadata&&)>& onCreateCrate); static void traverseChildDir(const std::string& targetDir, std::function<void(FTSENT*)>& onVisitChildDir); static void traverseAllPackagesForUser( - const std::unique_ptr<std::string>& uuid, + const std::optional<std::string>& uuid, userid_t userId, std::function<void(FTSENT*)>& onHandlingPackage); #if CRATE_DEBUG - static void dump(std::unique_ptr<CrateMetadata>& CrateMetadata); + static void dump(const CrateMetadata& CrateMetadata); #endif private: std::string mRoot; @@ -75,7 +75,7 @@ private: void createCrate( CratedFolder cratedFolder, - std::function<void(CratedFolder, std::unique_ptr<CrateMetadata>&)>& onCreateCrate); + std::function<void(CratedFolder, CrateMetadata&&)>& onCreateCrate); }; } // namespace installd diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index c9b51b597f..26f9d79cd4 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -164,7 +164,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 { @@ -173,7 +173,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 { @@ -212,7 +212,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 { @@ -418,7 +418,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); @@ -499,7 +499,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); @@ -560,7 +560,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); @@ -680,7 +680,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); @@ -752,7 +752,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); @@ -872,7 +872,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); @@ -999,7 +999,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); @@ -1069,7 +1069,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); @@ -1102,8 +1102,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, int32_t appId, const std::string& seInfo, int32_t targetSdkVersion, const std::string& fromCodePath) { ENFORCE_UID(AID_SYSTEM); @@ -1210,7 +1210,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); @@ -1228,7 +1228,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); @@ -1265,13 +1265,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); @@ -1669,7 +1669,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) { @@ -1709,7 +1709,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)) { @@ -1896,7 +1896,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); @@ -1916,7 +1916,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)) { @@ -2028,7 +2028,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); @@ -2043,7 +2043,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; @@ -2145,9 +2145,9 @@ binder::Status InstalldNativeService::getExternalSize(const std::unique_ptr<std: } binder::Status InstalldNativeService::getAppCrates( - const std::unique_ptr<std::string>& uuid, + const std::optional<std::string>& uuid, const std::vector<std::string>& packageNames, int32_t userId, - std::unique_ptr<std::vector<std::unique_ptr<CrateMetadata>>>* _aidl_return) { + std::optional<std::vector<std::optional<CrateMetadata>>>* _aidl_return) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); for (const auto& packageName : packageNames) { @@ -2156,15 +2156,15 @@ binder::Status InstalldNativeService::getAppCrates( #ifdef ENABLE_STORAGE_CRATES std::lock_guard<std::recursive_mutex> lock(mLock); - auto retVector = std::make_unique<std::vector<std::unique_ptr<CrateMetadata>>>(); + auto retVector = std::vector<std::optional<CrateMetadata>>(); const char* uuid_ = uuid ? uuid->c_str() : nullptr; - std::function<void(CratedFolder, std::unique_ptr<CrateMetadata> &)> onCreateCrate = - [&](CratedFolder cratedFolder, std::unique_ptr<CrateMetadata> &crateMetadata) -> void { + std::function<void(CratedFolder, CrateMetadata&&)> onCreateCrate = + [&](CratedFolder cratedFolder, CrateMetadata&& crateMetadata) -> void { if (cratedFolder == nullptr) { return; } - retVector->push_back(std::move(crateMetadata)); + retVector.push_back(std::move(crateMetadata)); }; for (const auto& packageName : packageNames) { @@ -2176,15 +2176,15 @@ binder::Status InstalldNativeService::getAppCrates( } #if CRATE_DEBUG - LOG(WARNING) << "retVector->size() =" << retVector->size(); - for (auto iter = retVector->begin(); iter != retVector->end(); ++iter) { - CrateManager::dump(*iter); + LOG(WARNING) << "retVector.size() =" << retVector.size(); + for (auto& item : retVector) { + CrateManager::dump(item); } #endif *_aidl_return = std::move(retVector); #else // ENABLE_STORAGE_CRATES - *_aidl_return = nullptr; + _aidl_return->reset(); /* prevent compile warning fail */ if (userId < 0) { @@ -2195,18 +2195,18 @@ binder::Status InstalldNativeService::getAppCrates( } binder::Status InstalldNativeService::getUserCrates( - const std::unique_ptr<std::string>& uuid, int32_t userId, - std::unique_ptr<std::vector<std::unique_ptr<CrateMetadata>>>* _aidl_return) { + const std::optional<std::string>& uuid, int32_t userId, + std::optional<std::vector<std::optional<CrateMetadata>>>* _aidl_return) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); #ifdef ENABLE_STORAGE_CRATES std::lock_guard<std::recursive_mutex> lock(mLock); const char* uuid_ = uuid ? uuid->c_str() : nullptr; - auto retVector = std::make_unique<std::vector<std::unique_ptr<CrateMetadata>>>(); + auto retVector = std::vector<std::optional<CrateMetadata>>(); - std::function<void(CratedFolder, std::unique_ptr<CrateMetadata> &)> onCreateCrate = - [&](CratedFolder cratedFolder, std::unique_ptr<CrateMetadata> &crateMetadata) -> void { + std::function<void(CratedFolder, CrateMetadata&&)> onCreateCrate = + [&](CratedFolder cratedFolder, CrateMetadata&& crateMetadata) -> void { if (cratedFolder == nullptr) { return; } @@ -2220,15 +2220,15 @@ binder::Status InstalldNativeService::getUserCrates( CrateManager::traverseAllPackagesForUser(uuid, userId, onHandingPackage); #if CRATE_DEBUG - LOG(DEBUG) << "retVector->size() =" << retVector->size(); - for (auto iter = retVector->begin(); iter != retVector->end(); ++iter) { - CrateManager::dump(*iter); + LOG(DEBUG) << "retVector.size() =" << retVector.size(); + for (auto& item : retVector) { + CrateManager::dump(item); } #endif *_aidl_return = std::move(retVector); #else // ENABLE_STORAGE_CRATES - *_aidl_return = nullptr; + _aidl_return->reset(); /* prevent compile warning fail */ if (userId < 0) { @@ -2238,7 +2238,7 @@ binder::Status InstalldNativeService::getUserCrates( 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); @@ -2309,19 +2309,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 ? data->c_str() : default_value; } 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); @@ -2367,7 +2367,7 @@ binder::Status InstalldNativeService::compileLayouts(const std::string& apkPath, } 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); @@ -2458,7 +2458,7 @@ out: return res; } -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); @@ -2576,7 +2576,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); @@ -2728,7 +2728,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); @@ -2743,7 +2743,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); @@ -2802,7 +2802,7 @@ binder::Status InstalldNativeService::invalidateMounts() { // Mount volume's CE and DE storage to mirror binder::Status InstalldNativeService::tryMountDataMirror( - const std::unique_ptr<std::string>& uuid) { + const std::optional<std::string>& uuid) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); if (!sAppDataIsolationEnabled) { @@ -2866,7 +2866,7 @@ binder::Status InstalldNativeService::tryMountDataMirror( // Unmount volume's CE and DE storage from mirror binder::Status InstalldNativeService::onPrivateVolumeRemoved( - const std::unique_ptr<std::string>& uuid) { + const std::optional<std::string>& uuid) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); if (!sAppDataIsolationEnabled) { @@ -2910,7 +2910,7 @@ binder::Status InstalldNativeService::onPrivateVolumeRemoved( } 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()); @@ -2923,15 +2923,14 @@ std::string InstalldNativeService::findDataMediaPath( } binder::Status InstalldNativeService::isQuotaSupported( - const std::unique_ptr<std::string>& uuid, bool* _aidl_return) { - auto uuidString = uuid ? *uuid : ""; - *_aidl_return = IsQuotaSupported(uuidString); + const std::optional<std::string>& uuid, bool* _aidl_return) { + *_aidl_return = IsQuotaSupported(uuid.value_or("")); 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); diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h index df01c3ca85..8e22c3e5d9 100644 --- a/cmds/installd/InstalldNativeService.h +++ b/cmds/installd/InstalldNativeService.h @@ -40,74 +40,74 @@ 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 getAppCrates(const std::unique_ptr<std::string>& uuid, + binder::Status getAppCrates(const std::optional<std::string>& uuid, const std::vector<std::string>& packageNames, int32_t userId, - std::unique_ptr<std::vector<std::unique_ptr<android::os::storage::CrateMetadata>>>* + std::optional<std::vector<std::optional<android::os::storage::CrateMetadata>>>* _aidl_return); binder::Status getUserCrates( - const std::unique_ptr<std::string>& uuid, int32_t userId, - std::unique_ptr<std::vector<std::unique_ptr<android::os::storage::CrateMetadata>>>* + const std::optional<std::string>& uuid, int32_t userId, + std::optional<std::vector<std::optional<android::os::storage::CrateMetadata>>>* _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, int32_t appId, const std::string& seInfo, int32_t targetSdkVersion, const std::string& fromCodePath); 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); @@ -130,9 +130,9 @@ public: const std::string& profileName); binder::Status rmPackageDir(const std::string& packageDir); - 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, @@ -140,27 +140,27 @@ 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 tryMountDataMirror(const std::unique_ptr<std::string>& volumeUuid); - binder::Status onPrivateVolumeRemoved(const std::unique_ptr<std::string>& volumeUuid); + binder::Status tryMountDataMirror(const std::optional<std::string>& volumeUuid); + binder::Status onPrivateVolumeRemoved(const std::optional<std::string>& volumeUuid); 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(); @@ -177,7 +177,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 diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp index 70bbc33b42..ebb8f0f90e 100644 --- a/cmds/installd/dexopt.cpp +++ b/cmds/installd/dexopt.cpp @@ -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; } diff --git a/cmds/installd/dexopt.h b/cmds/installd/dexopt.h index ef739bafd4..92b13c79c1 100644 --- a/cmds/installd/dexopt.h +++ b/cmds/installd/dexopt.h @@ -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, diff --git a/cmds/installd/tests/installd_cache_test.cpp b/cmds/installd/tests/installd_cache_test.cpp index 5a5cb53431..863cdfe55b 100644 --- a/cmds/installd/tests/installd_cache_test.cpp +++ b/cmds/installd/tests/installd_cache_test.cpp @@ -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"); } diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp index 69fefa199b..7d8cf1f9e5 100644 --- a/cmds/installd/tests/installd_dexopt_test.cpp +++ b/cmds/installd/tests/installd_dexopt_test.cpp @@ -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) { diff --git a/cmds/installd/tests/installd_service_test.cpp b/cmds/installd/tests/installd_service_test.cpp index a31d510565..727867720d 100644 --- a/cmds/installd/tests/installd_service_test.cpp +++ b/cmds/installd/tests/installd_service_test.cpp @@ -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)); } diff --git a/libs/binder/AppOpsManager.cpp b/libs/binder/AppOpsManager.cpp index aeca12b582..4ab144bdf1 100644 --- a/libs/binder/AppOpsManager.cpp +++ b/libs/binder/AppOpsManager.cpp @@ -115,12 +115,12 @@ int32_t AppOpsManager::checkAudioOpNoThrow(int32_t op, int32_t usage, int32_t ui } int32_t AppOpsManager::noteOp(int32_t op, int32_t uid, const String16& callingPackage) { - return noteOp(op, uid, callingPackage, std::unique_ptr<String16>(), + return noteOp(op, uid, callingPackage, {}, String16("Legacy AppOpsManager.noteOp call")); } int32_t AppOpsManager::noteOp(int32_t op, int32_t uid, const String16& callingPackage, - const std::unique_ptr<String16>& featureId, const String16& message) { + const std::optional<String16>& featureId, const String16& message) { sp<IAppOpsService> service = getService(); int32_t mode = service != nullptr ? service->noteOperation(op, uid, callingPackage, featureId, shouldCollectNotes(op), @@ -132,12 +132,12 @@ int32_t AppOpsManager::noteOp(int32_t op, int32_t uid, const String16& callingPa int32_t AppOpsManager::startOpNoThrow(int32_t op, int32_t uid, const String16& callingPackage, bool startIfModeDefault) { - return startOpNoThrow(op, uid, callingPackage, startIfModeDefault, std::unique_ptr<String16>(), + return startOpNoThrow(op, uid, callingPackage, startIfModeDefault, {}, String16("Legacy AppOpsManager.startOpNoThrow call")); } int32_t AppOpsManager::startOpNoThrow(int32_t op, int32_t uid, const String16& callingPackage, - bool startIfModeDefault, const std::unique_ptr<String16>& featureId, + bool startIfModeDefault, const std::optional<String16>& featureId, const String16& message) { sp<IAppOpsService> service = getService(); int32_t mode = service != nullptr @@ -149,11 +149,11 @@ int32_t AppOpsManager::startOpNoThrow(int32_t op, int32_t uid, const String16& c } void AppOpsManager::finishOp(int32_t op, int32_t uid, const String16& callingPackage) { - finishOp(op, uid, callingPackage, std::unique_ptr<String16>()); + finishOp(op, uid, callingPackage, {}); } void AppOpsManager::finishOp(int32_t op, int32_t uid, const String16& callingPackage, - const std::unique_ptr<String16>& callingFeatureId) { + const std::optional<String16>& callingFeatureId) { sp<IAppOpsService> service = getService(); if (service != nullptr) { service->finishOperation(getClientId(), op, uid, callingPackage, callingFeatureId); diff --git a/libs/binder/IAppOpsService.cpp b/libs/binder/IAppOpsService.cpp index a5555a304f..50e23b50a7 100644 --- a/libs/binder/IAppOpsService.cpp +++ b/libs/binder/IAppOpsService.cpp @@ -22,6 +22,8 @@ #include <binder/Parcel.h> #include <utils/String8.h> +#include <optional> + namespace android { // ---------------------------------------------------------------------- @@ -47,7 +49,7 @@ public: } virtual int32_t noteOperation(int32_t code, int32_t uid, const String16& packageName, - const std::unique_ptr<String16>& featureId, bool shouldCollectAsyncNotedOp, + const std::optional<String16>& featureId, bool shouldCollectAsyncNotedOp, const String16& message) { Parcel data, reply; data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); @@ -64,7 +66,7 @@ public: } virtual int32_t startOperation(const sp<IBinder>& token, int32_t code, int32_t uid, - const String16& packageName, const std::unique_ptr<String16>& featureId, + const String16& packageName, const std::optional<String16>& featureId, bool startIfModeDefault, bool shouldCollectAsyncNotedOp, const String16& message) { Parcel data, reply; data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); @@ -83,7 +85,7 @@ public: } virtual void finishOperation(const sp<IBinder>& token, int32_t code, int32_t uid, - const String16& packageName, const std::unique_ptr<String16>& featureId) { + const String16& packageName, const std::optional<String16>& featureId) { Parcel data, reply; data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor()); data.writeStrongBinder(token); @@ -182,7 +184,7 @@ status_t BnAppOpsService::onTransact( int32_t code = data.readInt32(); int32_t uid = data.readInt32(); String16 packageName = data.readString16(); - std::unique_ptr<String16> featureId; + std::optional<String16> featureId; data.readString16(&featureId); bool shouldCollectAsyncNotedOp = data.readInt32() == 1; String16 message = data.readString16(); @@ -198,7 +200,7 @@ status_t BnAppOpsService::onTransact( int32_t code = data.readInt32(); int32_t uid = data.readInt32(); String16 packageName = data.readString16(); - std::unique_ptr<String16> featureId; + std::optional<String16> featureId; data.readString16(&featureId); bool startIfModeDefault = data.readInt32() == 1; bool shouldCollectAsyncNotedOp = data.readInt32() == 1; @@ -215,7 +217,7 @@ status_t BnAppOpsService::onTransact( int32_t code = data.readInt32(); int32_t uid = data.readInt32(); String16 packageName = data.readString16(); - std::unique_ptr<String16> featureId; + std::optional<String16> featureId; data.readString16(&featureId); finishOperation(token, code, uid, packageName, featureId); reply->writeNoException(); diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index beab270387..5f1f682a5b 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -751,6 +751,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); @@ -775,6 +782,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); @@ -785,6 +798,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); @@ -796,6 +815,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); @@ -806,6 +830,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); @@ -816,6 +845,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); @@ -826,6 +860,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); @@ -836,6 +875,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); @@ -846,6 +890,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); @@ -856,6 +905,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); @@ -867,12 +921,23 @@ status_t Parcel::writeString16Vector(const std::vector<String16>& val) } 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); } @@ -997,6 +1062,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) { @@ -1039,11 +1113,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); } @@ -1142,6 +1225,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); } @@ -1475,6 +1562,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; @@ -1486,6 +1584,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; @@ -1497,6 +1606,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); } @@ -1505,6 +1618,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); } @@ -1513,6 +1630,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); } @@ -1521,6 +1642,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); } @@ -1529,6 +1654,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); } @@ -1537,6 +1666,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; @@ -1589,6 +1740,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); } @@ -1598,6 +1753,11 @@ status_t Parcel::readCharVector(std::vector<char16_t>* val) const { } 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); } @@ -1607,6 +1767,11 @@ status_t Parcel::readString16Vector(std::vector<String16>* val) const { } 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); } @@ -1798,6 +1963,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; @@ -1874,6 +2054,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(); @@ -2079,6 +2282,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); } diff --git a/libs/binder/include/binder/AppOpsManager.h b/libs/binder/include/binder/AppOpsManager.h index 5b6eb6863e..e4641822ad 100644 --- a/libs/binder/include/binder/AppOpsManager.h +++ b/libs/binder/include/binder/AppOpsManager.h @@ -21,6 +21,8 @@ #include <utils/threads.h> +#include <optional> + #ifdef __ANDROID_VNDK__ #error "This header is not visible to vendors" #endif @@ -134,18 +136,18 @@ public: // const String16&) instead int32_t noteOp(int32_t op, int32_t uid, const String16& callingPackage); int32_t noteOp(int32_t op, int32_t uid, const String16& callingPackage, - const std::unique_ptr<String16>& featureId, const String16& message); + const std::optional<String16>& featureId, const String16& message); // @Deprecated, use startOpNoThrow(int32_t, int32_t, const String16&, bool, const String16&, // const String16&) instead int32_t startOpNoThrow(int32_t op, int32_t uid, const String16& callingPackage, bool startIfModeDefault); int32_t startOpNoThrow(int32_t op, int32_t uid, const String16& callingPackage, - bool startIfModeDefault, const std::unique_ptr<String16>& featureId, + bool startIfModeDefault, const std::optional<String16>& featureId, const String16& message); // @Deprecated, use finishOp(int32_t, int32_t, const String16&, bool, const String16&) instead void finishOp(int32_t op, int32_t uid, const String16& callingPackage); void finishOp(int32_t op, int32_t uid, const String16& callingPackage, - const std::unique_ptr<String16>& featureId); + const std::optional<String16>& featureId); void startWatchingMode(int32_t op, const String16& packageName, const sp<IAppOpsCallback>& callback); void stopWatchingMode(const sp<IAppOpsCallback>& callback); diff --git a/libs/binder/include/binder/IAppOpsService.h b/libs/binder/include/binder/IAppOpsService.h index 1b4bcce20f..95a80ff268 100644 --- a/libs/binder/include/binder/IAppOpsService.h +++ b/libs/binder/include/binder/IAppOpsService.h @@ -21,6 +21,8 @@ #include <binder/IAppOpsCallback.h> #include <binder/IInterface.h> +#include <optional> + #ifdef __ANDROID_VNDK__ #error "This header is not visible to vendors" #endif @@ -36,13 +38,13 @@ public: virtual int32_t checkOperation(int32_t code, int32_t uid, const String16& packageName) = 0; virtual int32_t noteOperation(int32_t code, int32_t uid, const String16& packageName, - const std::unique_ptr<String16>& featureId, bool shouldCollectAsyncNotedOp, + const std::optional<String16>& featureId, bool shouldCollectAsyncNotedOp, const String16& message) = 0; virtual int32_t startOperation(const sp<IBinder>& token, int32_t code, int32_t uid, - const String16& packageName, const std::unique_ptr<String16>& featureId, + const String16& packageName, const std::optional<String16>& featureId, bool startIfModeDefault, bool shouldCollectAsyncNotedOp, const String16& message) = 0; virtual void finishOperation(const sp<IBinder>& token, int32_t code, int32_t uid, - const String16& packageName, const std::unique_ptr<String16>& featureId) = 0; + const String16& packageName, const std::optional<String16>& featureId) = 0; virtual void startWatchingMode(int32_t op, const String16& packageName, const sp<IAppOpsCallback>& callback) = 0; virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) = 0; diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h index 4b1a758f38..97f1aeeb7b 100644 --- a/libs/binder/include/binder/Parcel.h +++ b/libs/binder/include/binder/Parcel.h @@ -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,14 +182,20 @@ 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> status_t writeParcelableVector(const std::shared_ptr<std::vector<std::unique_ptr<T>>>& val); @@ -181,6 +203,8 @@ public: 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); status_t writeParcelable(const Parcelable& 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- @@ -229,6 +255,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( const std::vector<base::unique_fd>& val); @@ -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,27 +314,34 @@ 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; template<typename T> status_t readParcelableVector(std::vector<T>* val) const; @@ -313,6 +349,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; template<typename T> @@ -321,31 +359,45 @@ 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; @@ -397,6 +454,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( std::vector<base::unique_fd>* val) const; @@ -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> @@ -689,6 +757,15 @@ status_t Parcel::writeVectorSize(const std::vector<T>& val) { } 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) { return writeInt32(-1); @@ -713,6 +790,22 @@ status_t Parcel::resizeOutVector(std::vector<T>* val) const { } 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; status_t err = readInt32(&size); @@ -745,6 +838,25 @@ status_t Parcel::reserveOutVector(std::vector<T>* val, size_t* size) const { } 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 { int32_t read_size; @@ -839,6 +951,30 @@ status_t Parcel::readTypedVector(std::vector<T>* val, } 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 { const size_t start = dataPosition(); @@ -899,6 +1035,16 @@ status_t Parcel::writeTypedVector(const std::vector<T>& val, } 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&)) { if (val.get() == nullptr) { @@ -909,6 +1055,16 @@ status_t Parcel::writeNullableTypedVector(const std::unique_ptr<std::vector<T>>& } 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)) { if (val.get() == nullptr) { @@ -924,6 +1080,30 @@ status_t Parcel::readParcelableVector(std::vector<T>* val) const { } 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(); int32_t size; @@ -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(); @@ -947,6 +1128,29 @@ status_t Parcel::readParcelableVector(std::unique_ptr<std::vector<std::unique_pt } 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(); int32_t present; @@ -970,6 +1174,11 @@ status_t Parcel::readParcelable(std::unique_ptr<T>* parcelable) const { } 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()); } @@ -980,6 +1189,16 @@ status_t Parcel::writeParcelableVector(const std::vector<T>& val) { } 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) { return this->writeInt32(-1); @@ -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); } diff --git a/libs/binder/include/binder/ParcelFileDescriptor.h b/libs/binder/include/binder/ParcelFileDescriptor.h index 4635ad84c6..2ede6c4b59 100644 --- a/libs/binder/include/binder/ParcelFileDescriptor.h +++ b/libs/binder/include/binder/ParcelFileDescriptor.h @@ -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(); } |