diff options
87 files changed, 1671 insertions, 397 deletions
diff --git a/METADATA b/METADATA new file mode 100644 index 0000000000..d97975ca3b --- /dev/null +++ b/METADATA @@ -0,0 +1,3 @@ +third_party { + license_type: NOTICE +} diff --git a/cmds/bugreport/bugreport.cpp b/cmds/bugreport/bugreport.cpp index 840ae473bc..e5c52d8dff 100644 --- a/cmds/bugreport/bugreport.cpp +++ b/cmds/bugreport/bugreport.cpp @@ -27,12 +27,20 @@ // dumpstate, then connect to the dumpstate local client to read the // output. All of the dumpstate output is written to stdout, including // any errors encountered while reading/writing the output. -int main() { - +int main(int argc, char* /*argv*/[]) { fprintf(stderr, "=============================================================================\n"); - fprintf(stderr, "WARNING: flat bugreports are deprecated, use adb bugreport <zip_file> instead\n"); + fprintf(stderr, "WARNING: Flat (text file, non-zipped) bugreports are deprecated.\n"); + fprintf(stderr, "WARNING: Please generate zipped bugreports instead.\n"); + fprintf(stderr, "WARNING: On the host use: adb bugreport filename.zip\n"); + fprintf(stderr, "WARNING: On the device use: bugreportz\n"); + fprintf(stderr, "WARNING: bugreportz will output the filename to use with adb pull.\n"); fprintf(stderr, "=============================================================================\n\n\n"); + if (argc != 1) { + fprintf(stderr, "usage: bugreport\n"); + exit(1); + } + // Start the dumpstate service. property_set("ctl.start", "dumpstate"); diff --git a/cmds/bugreportz/main.cpp b/cmds/bugreportz/main.cpp index 40346bee1f..1d48e08f3e 100644 --- a/cmds/bugreportz/main.cpp +++ b/cmds/bugreportz/main.cpp @@ -30,7 +30,7 @@ static constexpr char VERSION[] = "1.1"; static void show_usage() { fprintf(stderr, - "usage: bugreportz [-h | -v]\n" + "usage: bugreportz [-hpv]\n" " -h: to display this help message\n" " -p: display progress\n" " -v: to display the version\n" @@ -64,6 +64,12 @@ int main(int argc, char* argv[]) { } } + // We don't support any non-option arguments. + if (optind != argc) { + show_usage(); + return EXIT_FAILURE; + } + // TODO: code below was copy-and-pasted from bugreport.cpp (except by the // timeout value); // should be reused instead. diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp index acca11acf7..ead491e4dd 100644 --- a/cmds/dumpstate/Android.bp +++ b/cmds/dumpstate/Android.bp @@ -110,29 +110,20 @@ cc_binary { ], required: [ "atrace", - "df", - "getprop", "ip", "iptables", - "ip6tables", - "kill", "librank", "logcat", "lpdump", "lpdumpd", - "lsmod", - "lsof", - "netstat", - "printenv", "procrank", "screencap", "showmap", "ss", "storaged", - "top", - "uptime", + "toolbox", + "toybox", "vdc", - "vril-dump", ], init_rc: ["dumpstate.rc"], } diff --git a/cmds/dumpsys/dumpsys.cpp b/cmds/dumpsys/dumpsys.cpp index a427c8dd68..1327cfd155 100644 --- a/cmds/dumpsys/dumpsys.cpp +++ b/cmds/dumpsys/dumpsys.cpp @@ -230,7 +230,7 @@ int Dumpsys::main(int argc, char* const argv[]) { } const size_t N = services.size(); - if (N > 1) { + if (N > 1 || showListOnly) { // first print a list of the current services std::cout << "Currently running services:" << std::endl; diff --git a/cmds/dumpsys/tests/dumpsys_test.cpp b/cmds/dumpsys/tests/dumpsys_test.cpp index b9395ba4e2..3467898f3e 100644 --- a/cmds/dumpsys/tests/dumpsys_test.cpp +++ b/cmds/dumpsys/tests/dumpsys_test.cpp @@ -206,10 +206,7 @@ class DumpsysTest : public Test { } void AssertRunningServices(const std::vector<std::string>& services) { - std::string expected; - if (services.size() > 1) { - expected.append("Currently running services:\n"); - } + std::string expected = "Currently running services:\n"; for (const std::string& service : services) { expected.append(" ").append(service).append("\n"); } @@ -263,6 +260,21 @@ TEST_F(DumpsysTest, ListAllServices) { AssertRunningServices({"Locksmith", "Valet"}); } +TEST_F(DumpsysTest, ListServicesOneRegistered) { + ExpectListServices({"Locksmith"}); + ExpectCheckService("Locksmith"); + + CallMain({"-l"}); + + AssertRunningServices({"Locksmith"}); +} + +TEST_F(DumpsysTest, ListServicesEmpty) { + CallMain({"-l"}); + + AssertRunningServices({}); +} + // Tests 'dumpsys -l' when a service is not running TEST_F(DumpsysTest, ListRunningServices) { ExpectListServices({"Locksmith", "Valet"}); 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 b9c1addf89..0782b430a3 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -166,7 +166,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 { @@ -175,7 +175,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 { @@ -214,7 +214,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 { @@ -421,8 +421,8 @@ static bool prepare_app_profile_dir(const std::string& packageName, int32_t appI } binder::Status InstalldNativeService::createAppDataBatched( - const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& uuids, - const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& packageNames, + const std::optional<std::vector<std::optional<std::string>>>& uuids, + const std::optional<std::vector<std::optional<std::string>>>& packageNames, int32_t userId, int32_t flags, const std::vector<int32_t>& appIds, const std::vector<std::string>& seInfos, const std::vector<int32_t>& targetSdkVersions, int64_t* _aidl_return) { @@ -432,10 +432,11 @@ binder::Status InstalldNativeService::createAppDataBatched( ATRACE_BEGIN("createAppDataBatched"); binder::Status ret; for (size_t i = 0; i < uuids->size(); i++) { - if (!packageNames->at(i)) { + std::optional<std::string> packageName = packageNames->at(i); + if (!packageName) { continue; } - ret = createAppData(uuids->at(i), *packageNames->at(i), userId, flags, appIds[i], + ret = createAppData(uuids->at(i), *packageName, userId, flags, appIds[i], seInfos[i], targetSdkVersions[i], _aidl_return); if (!ret.isOk()) { ATRACE_END(); @@ -446,7 +447,7 @@ binder::Status InstalldNativeService::createAppDataBatched( return ok(); } -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); @@ -527,7 +528,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); @@ -588,7 +589,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); @@ -708,7 +709,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); @@ -780,7 +781,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); @@ -900,7 +901,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); @@ -1027,7 +1028,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); @@ -1099,7 +1100,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); @@ -1132,7 +1133,7 @@ binder::Status InstalldNativeService::destroyAppDataSnapshot( } binder::Status InstalldNativeService::destroyCeSnapshotsNotSpecified( - const std::unique_ptr<std::string> &volumeUuid, const int32_t userId, + const std::optional<std::string> &volumeUuid, const int32_t user, const std::vector<int32_t>& retainSnapshotIds) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid); @@ -1140,7 +1141,7 @@ binder::Status InstalldNativeService::destroyCeSnapshotsNotSpecified( const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr; - auto base_path = create_data_misc_ce_rollback_base_path(volume_uuid, userId); + auto base_path = create_data_misc_ce_rollback_base_path(volume_uuid, user); std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(base_path.c_str()), closedir); if (!dir) { @@ -1159,7 +1160,7 @@ binder::Status InstalldNativeService::destroyCeSnapshotsNotSpecified( std::find(retainSnapshotIds.begin(), retainSnapshotIds.end(), snapshot_id) == retainSnapshotIds.end()) { auto rollback_path = create_data_misc_ce_rollback_path( - volume_uuid, userId, snapshot_id); + volume_uuid, user, snapshot_id); int res = delete_dir_contents_and_dir(rollback_path, true /* ignore_if_missing */); if (res != 0) { return error(res, "Failed clearing snapshot " + rollback_path); @@ -1169,8 +1170,8 @@ binder::Status InstalldNativeService::destroyCeSnapshotsNotSpecified( return ok(); } -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); @@ -1277,7 +1278,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); @@ -1295,7 +1296,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); @@ -1332,13 +1333,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); @@ -1736,7 +1737,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) { @@ -1776,7 +1777,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)) { @@ -1963,7 +1964,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); @@ -1983,7 +1984,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)) { @@ -2095,7 +2096,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); @@ -2110,7 +2111,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; @@ -2212,9 +2213,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) { @@ -2223,15 +2224,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) { @@ -2243,15 +2244,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) { @@ -2262,18 +2263,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; } @@ -2287,15 +2288,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) { @@ -2305,7 +2306,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); @@ -2376,19 +2377,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); @@ -2434,7 +2435,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); @@ -2525,7 +2526,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); @@ -2643,7 +2644,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); @@ -2795,7 +2796,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); @@ -2810,7 +2811,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); @@ -2869,7 +2870,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) { @@ -2933,7 +2934,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) { @@ -2977,7 +2978,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()); @@ -2990,15 +2991,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 8e7d98b9a1..9819327840 100644 --- a/cmds/installd/InstalldNativeService.h +++ b/cmds/installd/InstalldNativeService.h @@ -40,81 +40,81 @@ 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 createAppDataBatched( - const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& uuids, - const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& packageNames, + const std::optional<std::vector<std::optional<std::string>>>& uuids, + const std::optional<std::vector<std::optional<std::string>>>& packageNames, int32_t userId, int32_t flags, const std::vector<int32_t>& appIds, const std::vector<std::string>& seInfos, const std::vector<int32_t>& targetSdkVersions, int64_t* _aidl_return); - binder::Status createAppData(const std::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 destroyCeSnapshotsNotSpecified(const std::unique_ptr<std::string> &volumeUuid, - const int32_t userId, const std::vector<int32_t>& retainSnapshotIds); + binder::Status destroyCeSnapshotsNotSpecified(const std::optional<std::string> &volumeUuid, + const int32_t user, const std::vector<int32_t>& retainSnapshotIds); - 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); @@ -137,9 +137,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, @@ -147,27 +147,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(); @@ -184,7 +184,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/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl index eeda6c5855..4ac70a4857 100644 --- a/cmds/installd/binder/android/os/IInstalld.aidl +++ b/cmds/installd/binder/android/os/IInstalld.aidl @@ -117,11 +117,10 @@ interface IInstalld { int userId, int snapshotId, int storageFlags); void restoreAppDataSnapshot(@nullable @utf8InCpp String uuid, in @utf8InCpp String packageName, int appId, @utf8InCpp String seInfo, int user, int snapshotId, int storageflags); - void destroyAppDataSnapshot(@nullable @utf8InCpp String uuid, @utf8InCpp String packageName, - int userId, long ceSnapshotInode, int snapshotId, int storageFlags); void destroyCeSnapshotsNotSpecified(@nullable @utf8InCpp String uuid, int userId, in int[] retainSnapshotIds); - + void destroyAppDataSnapshot(@nullable @utf8InCpp String uuid, @utf8InCpp String packageName, + int userId, long ceSnapshotInode, int snapshotId, int storageFlags); void tryMountDataMirror(@nullable @utf8InCpp String volumeUuid); void onPrivateVolumeRemoved(@nullable @utf8InCpp String volumeUuid); diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp index ffa87249e2..82be00747a 100644 --- a/cmds/installd/dexopt.cpp +++ b/cmds/installd/dexopt.cpp @@ -2325,7 +2325,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) { @@ -2346,7 +2346,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; @@ -2447,11 +2447,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: " @@ -2978,7 +2978,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); @@ -2989,7 +2989,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 cc448736ea..d35953c058 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 { @@ -100,17 +102,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 16e4055faa..96f5e44030 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) { @@ -992,7 +982,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 0fb62ae9bf..1e7559d174 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()); } @@ -669,7 +668,7 @@ TEST_F(AppDataSnapshotTest, DestroyCeSnapshotsNotSpecified) { 0700, 10000, 20000, false /* follow_symlinks */)); ASSERT_TRUE(service->destroyCeSnapshotsNotSpecified( - std::make_unique<std::string>("TEST"), 0, { 1543, 77 }).isOk()); + std::make_optional<std::string>("TEST"), 0, { 1543, 77 }).isOk()); // Check only snapshots not specified are deleted. struct stat sb; @@ -690,7 +689,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/docs/Doxyfile b/docs/Doxyfile index efa639d2e7..a1bd960c5a 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1621,7 +1621,23 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = __attribute__(x)= +PREDEFINED = \ + "__ANDROID_API__=10000" \ + "__BEGIN_DECLS=" \ + "__END_DECLS=" \ + "__INTRODUCED_IN(x)=" \ + "__INTRODUCED_IN_32(x)=" \ + "__INTRODUCED_IN_64(x)=" \ + "__RENAME(x)=" \ + "__RENAME_LDBL(x,y,z)=" \ + "__printflike(x,y)=" \ + "__attribute__(x)=" \ + "__wur=" \ + "__mallocfunc=" \ + "__attribute_pure__=" \ + "__attribute__(x)=" \ + __ANDROID__ \ + __BIONIC__ \ # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff --git a/headers/Android.bp b/headers/Android.bp index 53372357e6..8f41c2b75b 100644 --- a/headers/Android.bp +++ b/headers/Android.bp @@ -18,4 +18,11 @@ cc_library_headers { "libstagefright_foundation_headers", ], min_sdk_version: "29", + + host_supported: true, + target: { + darwin: { + enabled: false, + }, + }, } diff --git a/include/android/bitmap.h b/include/android/bitmap.h index 2631b144af..f19539913e 100644 --- a/include/android/bitmap.h +++ b/include/android/bitmap.h @@ -125,6 +125,8 @@ int AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap, * Note that {@link ADataSpace} only exposes a few values. This may return * {@link ADATASPACE_UNKNOWN}, even for Named ColorSpaces, if they have no * corresponding ADataSpace. + * + * Available since API level 30. */ int32_t AndroidBitmap_getDataSpace(JNIEnv* env, jobject jbitmap) __INTRODUCED_IN(30); @@ -189,6 +191,8 @@ enum AndroidBitmapCompressFormat { /** * User-defined function for writing the output of compression. * + * Available since API level 30. + * * @param userContext Pointer to user-defined data passed to * {@link AndroidBitmap_compress}. * @param data Compressed data of |size| bytes to write. @@ -202,6 +206,8 @@ typedef bool (*AndroidBitmap_CompressWriteFunc)(void* userContext, /** * Compress |pixels| as described by |info|. * + * Available since API level 30. + * * @param info Description of the pixels to compress. * @param dataspace {@link ADataSpace} describing the color space of the * pixels. @@ -234,6 +240,8 @@ typedef struct AHardwareBuffer AHardwareBuffer; * * Client must not modify it while a Bitmap is wrapping it. * + * Available since API level 30. + * * @param bitmap Handle to an android.graphics.Bitmap. * @param outBuffer On success, is set to a pointer to the * {@link AHardwareBuffer} associated with bitmap. This acquires diff --git a/include/android/choreographer.h b/include/android/choreographer.h index c1c4a72cd3..bdf11e42ca 100644 --- a/include/android/choreographer.h +++ b/include/android/choreographer.h @@ -129,9 +129,12 @@ void AChoreographer_postFrameCallbackDelayed64(AChoreographer* choreographer, * * This api is thread-safe. Any thread is allowed to register a new refresh * rate callback for the choreographer instance. + * + * Available since API level 30. */ void AChoreographer_registerRefreshRateCallback(AChoreographer* choreographer, - AChoreographer_refreshRateCallback, void* data); + AChoreographer_refreshRateCallback, void* data) + __INTRODUCED_IN(30); /** * Unregisters a callback to be run when the display refresh rate changes, along @@ -144,9 +147,12 @@ void AChoreographer_registerRefreshRateCallback(AChoreographer* choreographer, * callback and associated data pointer are unregistered, then there is a * guarantee that when the unregistration completes that that callback will not * be run with the data pointer passed. + * + * Available since API level 30. */ void AChoreographer_unregisterRefreshRateCallback(AChoreographer* choreographer, - AChoreographer_refreshRateCallback, void* data); + AChoreographer_refreshRateCallback, void* data) + __INTRODUCED_IN(30); #endif /* __ANDROID_API__ >= 30 */ __END_DECLS diff --git a/include/android/configuration.h b/include/android/configuration.h index 05f43407fb..ccf3e59066 100644 --- a/include/android/configuration.h +++ b/include/android/configuration.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 The Android Open Source Project + * Copyright (C) 2010 The Android Open Source Project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,13 +58,13 @@ enum { ACONFIGURATION_ORIENTATION_ANY = 0x0000, /** * Orientation: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#OrientationQualifier">port</a> + * <a href="/guide/topics/resources/providing-resources.html#OrientationQualifier">port</a> * resource qualifier. */ ACONFIGURATION_ORIENTATION_PORT = 0x0001, /** * Orientation: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#OrientationQualifier">land</a> + * <a href="/guide/topics/resources/providing-resources.html#OrientationQualifier">land</a> * resource qualifier. */ ACONFIGURATION_ORIENTATION_LAND = 0x0002, @@ -75,7 +75,7 @@ enum { ACONFIGURATION_TOUCHSCREEN_ANY = 0x0000, /** * Touchscreen: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#TouchscreenQualifier">notouch</a> + * <a href="/guide/topics/resources/providing-resources.html#TouchscreenQualifier">notouch</a> * resource qualifier. */ ACONFIGURATION_TOUCHSCREEN_NOTOUCH = 0x0001, @@ -83,7 +83,7 @@ enum { ACONFIGURATION_TOUCHSCREEN_STYLUS = 0x0002, /** * Touchscreen: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#TouchscreenQualifier">finger</a> + * <a href="/guide/topics/resources/providing-resources.html#TouchscreenQualifier">finger</a> * resource qualifier. */ ACONFIGURATION_TOUCHSCREEN_FINGER = 0x0003, @@ -92,43 +92,43 @@ enum { ACONFIGURATION_DENSITY_DEFAULT = 0, /** * Density: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#DensityQualifier">ldpi</a> + * <a href="/guide/topics/resources/providing-resources.html#DensityQualifier">ldpi</a> * resource qualifier. */ ACONFIGURATION_DENSITY_LOW = 120, /** * Density: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#DensityQualifier">mdpi</a> + * <a href="/guide/topics/resources/providing-resources.html#DensityQualifier">mdpi</a> * resource qualifier. */ ACONFIGURATION_DENSITY_MEDIUM = 160, /** * Density: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#DensityQualifier">tvdpi</a> + * <a href="/guide/topics/resources/providing-resources.html#DensityQualifier">tvdpi</a> * resource qualifier. */ ACONFIGURATION_DENSITY_TV = 213, /** * Density: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#DensityQualifier">hdpi</a> + * <a href="/guide/topics/resources/providing-resources.html#DensityQualifier">hdpi</a> * resource qualifier. */ ACONFIGURATION_DENSITY_HIGH = 240, /** * Density: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#DensityQualifier">xhdpi</a> + * <a href="/guide/topics/resources/providing-resources.html#DensityQualifier">xhdpi</a> * resource qualifier. */ ACONFIGURATION_DENSITY_XHIGH = 320, /** * Density: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#DensityQualifier">xxhdpi</a> + * <a href="/guide/topics/resources/providing-resources.html#DensityQualifier">xxhdpi</a> * resource qualifier. */ ACONFIGURATION_DENSITY_XXHIGH = 480, /** * Density: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#DensityQualifier">xxxhdpi</a> + * <a href="/guide/topics/resources/providing-resources.html#DensityQualifier">xxxhdpi</a> * resource qualifier. */ ACONFIGURATION_DENSITY_XXXHIGH = 640, @@ -141,19 +141,19 @@ enum { ACONFIGURATION_KEYBOARD_ANY = 0x0000, /** * Keyboard: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#ImeQualifier">nokeys</a> + * <a href="/guide/topics/resources/providing-resources.html#ImeQualifier">nokeys</a> * resource qualifier. */ ACONFIGURATION_KEYBOARD_NOKEYS = 0x0001, /** * Keyboard: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#ImeQualifier">qwerty</a> + * <a href="/guide/topics/resources/providing-resources.html#ImeQualifier">qwerty</a> * resource qualifier. */ ACONFIGURATION_KEYBOARD_QWERTY = 0x0002, /** * Keyboard: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#ImeQualifier">12key</a> + * <a href="/guide/topics/resources/providing-resources.html#ImeQualifier">12key</a> * resource qualifier. */ ACONFIGURATION_KEYBOARD_12KEY = 0x0003, @@ -162,25 +162,25 @@ enum { ACONFIGURATION_NAVIGATION_ANY = 0x0000, /** * Navigation: value corresponding to the - * <a href="@@dacRoot/guide/topics/resources/providing-resources.html#NavigationQualifier">nonav</a> + * <a href="@/guide/topics/resources/providing-resources.html#NavigationQualifier">nonav</a> * resource qualifier. */ ACONFIGURATION_NAVIGATION_NONAV = 0x0001, /** * Navigation: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#NavigationQualifier">dpad</a> + * <a href="/guide/topics/resources/providing-resources.html#NavigationQualifier">dpad</a> * resource qualifier. */ ACONFIGURATION_NAVIGATION_DPAD = 0x0002, /** * Navigation: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#NavigationQualifier">trackball</a> + * <a href="/guide/topics/resources/providing-resources.html#NavigationQualifier">trackball</a> * resource qualifier. */ ACONFIGURATION_NAVIGATION_TRACKBALL = 0x0003, /** * Navigation: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#NavigationQualifier">wheel</a> + * <a href="/guide/topics/resources/providing-resources.html#NavigationQualifier">wheel</a> * resource qualifier. */ ACONFIGURATION_NAVIGATION_WHEEL = 0x0004, @@ -189,19 +189,19 @@ enum { ACONFIGURATION_KEYSHIDDEN_ANY = 0x0000, /** * Keyboard availability: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#KeyboardAvailQualifier">keysexposed</a> + * <a href="/guide/topics/resources/providing-resources.html#KeyboardAvailQualifier">keysexposed</a> * resource qualifier. */ ACONFIGURATION_KEYSHIDDEN_NO = 0x0001, /** * Keyboard availability: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#KeyboardAvailQualifier">keyshidden</a> + * <a href="/guide/topics/resources/providing-resources.html#KeyboardAvailQualifier">keyshidden</a> * resource qualifier. */ ACONFIGURATION_KEYSHIDDEN_YES = 0x0002, /** * Keyboard availability: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#KeyboardAvailQualifier">keyssoft</a> + * <a href="/guide/topics/resources/providing-resources.html#KeyboardAvailQualifier">keyssoft</a> * resource qualifier. */ ACONFIGURATION_KEYSHIDDEN_SOFT = 0x0003, @@ -210,13 +210,13 @@ enum { ACONFIGURATION_NAVHIDDEN_ANY = 0x0000, /** * Navigation availability: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#NavAvailQualifier">navexposed</a> + * <a href="/guide/topics/resources/providing-resources.html#NavAvailQualifier">navexposed</a> * resource qualifier. */ ACONFIGURATION_NAVHIDDEN_NO = 0x0001, /** * Navigation availability: value corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#NavAvailQualifier">navhidden</a> + * <a href="/guide/topics/resources/providing-resources.html#NavAvailQualifier">navhidden</a> * resource qualifier. */ ACONFIGURATION_NAVHIDDEN_YES = 0x0002, @@ -226,28 +226,28 @@ enum { /** * Screen size: value indicating the screen is at least * approximately 320x426 dp units, corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#ScreenSizeQualifier">small</a> + * <a href="/guide/topics/resources/providing-resources.html#ScreenSizeQualifier">small</a> * resource qualifier. */ ACONFIGURATION_SCREENSIZE_SMALL = 0x01, /** * Screen size: value indicating the screen is at least * approximately 320x470 dp units, corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#ScreenSizeQualifier">normal</a> + * <a href="/guide/topics/resources/providing-resources.html#ScreenSizeQualifier">normal</a> * resource qualifier. */ ACONFIGURATION_SCREENSIZE_NORMAL = 0x02, /** * Screen size: value indicating the screen is at least * approximately 480x640 dp units, corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#ScreenSizeQualifier">large</a> + * <a href="/guide/topics/resources/providing-resources.html#ScreenSizeQualifier">large</a> * resource qualifier. */ ACONFIGURATION_SCREENSIZE_LARGE = 0x03, /** * Screen size: value indicating the screen is at least * approximately 720x960 dp units, corresponding to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#ScreenSizeQualifier">xlarge</a> + * <a href="/guide/topics/resources/providing-resources.html#ScreenSizeQualifier">xlarge</a> * resource qualifier. */ ACONFIGURATION_SCREENSIZE_XLARGE = 0x04, @@ -256,13 +256,13 @@ enum { ACONFIGURATION_SCREENLONG_ANY = 0x00, /** * Screen layout: value that corresponds to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#ScreenAspectQualifier">notlong</a> + * <a href="/guide/topics/resources/providing-resources.html#ScreenAspectQualifier">notlong</a> * resource qualifier. */ ACONFIGURATION_SCREENLONG_NO = 0x1, /** * Screen layout: value that corresponds to the - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#ScreenAspectQualifier">long</a> + * <a href="/guide/topics/resources/providing-resources.html#ScreenAspectQualifier">long</a> * resource qualifier. */ ACONFIGURATION_SCREENLONG_YES = 0x2, @@ -275,13 +275,13 @@ enum { ACONFIGURATION_WIDE_COLOR_GAMUT_ANY = 0x00, /** * Wide color gamut: value that corresponds to - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#WideColorGamutQualifier">no + * <a href="/guide/topics/resources/providing-resources.html#WideColorGamutQualifier">no * nowidecg</a> resource qualifier specified. */ ACONFIGURATION_WIDE_COLOR_GAMUT_NO = 0x1, /** * Wide color gamut: value that corresponds to - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#WideColorGamutQualifier"> + * <a href="/guide/topics/resources/providing-resources.html#WideColorGamutQualifier"> * widecg</a> resource qualifier specified. */ ACONFIGURATION_WIDE_COLOR_GAMUT_YES = 0x2, @@ -290,13 +290,13 @@ enum { ACONFIGURATION_HDR_ANY = 0x00, /** * HDR: value that corresponds to - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#HDRQualifier"> + * <a href="/guide/topics/resources/providing-resources.html#HDRQualifier"> * lowdr</a> resource qualifier specified. */ ACONFIGURATION_HDR_NO = 0x1, /** * HDR: value that corresponds to - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#HDRQualifier"> + * <a href="/guide/topics/resources/providing-resources.html#HDRQualifier"> * highdr</a> resource qualifier specified. */ ACONFIGURATION_HDR_YES = 0x2, @@ -305,38 +305,38 @@ enum { ACONFIGURATION_UI_MODE_TYPE_ANY = 0x00, /** * UI mode: value that corresponds to - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#UiModeQualifier">no + * <a href="/guide/topics/resources/providing-resources.html#UiModeQualifier">no * UI mode type</a> resource qualifier specified. */ ACONFIGURATION_UI_MODE_TYPE_NORMAL = 0x01, /** * UI mode: value that corresponds to - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#UiModeQualifier">desk</a> resource qualifier specified. + * <a href="/guide/topics/resources/providing-resources.html#UiModeQualifier">desk</a> resource qualifier specified. */ ACONFIGURATION_UI_MODE_TYPE_DESK = 0x02, /** * UI mode: value that corresponds to - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#UiModeQualifier">car</a> resource qualifier specified. + * <a href="/guide/topics/resources/providing-resources.html#UiModeQualifier">car</a> resource qualifier specified. */ ACONFIGURATION_UI_MODE_TYPE_CAR = 0x03, /** * UI mode: value that corresponds to - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#UiModeQualifier">television</a> resource qualifier specified. + * <a href="/guide/topics/resources/providing-resources.html#UiModeQualifier">television</a> resource qualifier specified. */ ACONFIGURATION_UI_MODE_TYPE_TELEVISION = 0x04, /** * UI mode: value that corresponds to - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#UiModeQualifier">appliance</a> resource qualifier specified. + * <a href="/guide/topics/resources/providing-resources.html#UiModeQualifier">appliance</a> resource qualifier specified. */ ACONFIGURATION_UI_MODE_TYPE_APPLIANCE = 0x05, /** * UI mode: value that corresponds to - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#UiModeQualifier">watch</a> resource qualifier specified. + * <a href="/guide/topics/resources/providing-resources.html#UiModeQualifier">watch</a> resource qualifier specified. */ ACONFIGURATION_UI_MODE_TYPE_WATCH = 0x06, /** * UI mode: value that corresponds to - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#UiModeQualifier">vr</a> resource qualifier specified. + * <a href="/guide/topics/resources/providing-resources.html#UiModeQualifier">vr</a> resource qualifier specified. */ ACONFIGURATION_UI_MODE_TYPE_VR_HEADSET = 0x07, @@ -344,12 +344,12 @@ enum { ACONFIGURATION_UI_MODE_NIGHT_ANY = 0x00, /** * UI night mode: value that corresponds to - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#NightQualifier">notnight</a> resource qualifier specified. + * <a href="/guide/topics/resources/providing-resources.html#NightQualifier">notnight</a> resource qualifier specified. */ ACONFIGURATION_UI_MODE_NIGHT_NO = 0x1, /** * UI night mode: value that corresponds to - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#NightQualifier">night</a> resource qualifier specified. + * <a href="/guide/topics/resources/providing-resources.html#NightQualifier">night</a> resource qualifier specified. */ ACONFIGURATION_UI_MODE_NIGHT_YES = 0x2, @@ -366,78 +366,78 @@ enum { ACONFIGURATION_LAYOUTDIR_ANY = 0x00, /** * Layout direction: value that corresponds to - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#LayoutDirectionQualifier">ldltr</a> resource qualifier specified. + * <a href="/guide/topics/resources/providing-resources.html#LayoutDirectionQualifier">ldltr</a> resource qualifier specified. */ ACONFIGURATION_LAYOUTDIR_LTR = 0x01, /** * Layout direction: value that corresponds to - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#LayoutDirectionQualifier">ldrtl</a> resource qualifier specified. + * <a href="/guide/topics/resources/providing-resources.html#LayoutDirectionQualifier">ldrtl</a> resource qualifier specified. */ ACONFIGURATION_LAYOUTDIR_RTL = 0x02, /** * Bit mask for - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#MccQualifier">mcc</a> + * <a href="/guide/topics/resources/providing-resources.html#MccQualifier">mcc</a> * configuration. */ ACONFIGURATION_MCC = 0x0001, /** * Bit mask for - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#MccQualifier">mnc</a> + * <a href="/guide/topics/resources/providing-resources.html#MccQualifier">mnc</a> * configuration. */ ACONFIGURATION_MNC = 0x0002, /** * Bit mask for - * <a href="{@docRoot}guide/topics/resources/providing-resources.html#LocaleQualifier">locale</a> + * <a href="/guide/topics/resources/providing-resources.html#LocaleQualifier">locale</a> * configuration. */ ACONFIGURATION_LOCALE = 0x0004, /** * Bit mask for - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#TouchscreenQualifier">touchscreen</a> + * <a href="/guide/topics/resources/providing-resources.html#TouchscreenQualifier">touchscreen</a> * configuration. */ ACONFIGURATION_TOUCHSCREEN = 0x0008, /** * Bit mask for - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#ImeQualifier">keyboard</a> + * <a href="/guide/topics/resources/providing-resources.html#ImeQualifier">keyboard</a> * configuration. */ ACONFIGURATION_KEYBOARD = 0x0010, /** * Bit mask for - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#KeyboardAvailQualifier">keyboardHidden</a> + * <a href="/guide/topics/resources/providing-resources.html#KeyboardAvailQualifier">keyboardHidden</a> * configuration. */ ACONFIGURATION_KEYBOARD_HIDDEN = 0x0020, /** * Bit mask for - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#NavigationQualifier">navigation</a> + * <a href="/guide/topics/resources/providing-resources.html#NavigationQualifier">navigation</a> * configuration. */ ACONFIGURATION_NAVIGATION = 0x0040, /** * Bit mask for - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#OrientationQualifier">orientation</a> + * <a href="/guide/topics/resources/providing-resources.html#OrientationQualifier">orientation</a> * configuration. */ ACONFIGURATION_ORIENTATION = 0x0080, /** * Bit mask for - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#DensityQualifier">density</a> + * <a href="/guide/topics/resources/providing-resources.html#DensityQualifier">density</a> * configuration. */ ACONFIGURATION_DENSITY = 0x0100, /** * Bit mask for - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#ScreenSizeQualifier">screen size</a> + * <a href="/guide/topics/resources/providing-resources.html#ScreenSizeQualifier">screen size</a> * configuration. */ ACONFIGURATION_SCREEN_SIZE = 0x0200, /** * Bit mask for - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#VersionQualifier">platform version</a> + * <a href="/guide/topics/resources/providing-resources.html#VersionQualifier">platform version</a> * configuration. */ ACONFIGURATION_VERSION = 0x0400, @@ -447,27 +447,27 @@ enum { ACONFIGURATION_SCREEN_LAYOUT = 0x0800, /** * Bit mask for - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#UiModeQualifier">ui mode</a> + * <a href="/guide/topics/resources/providing-resources.html#UiModeQualifier">ui mode</a> * configuration. */ ACONFIGURATION_UI_MODE = 0x1000, /** * Bit mask for - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#SmallestScreenWidthQualifier">smallest screen width</a> + * <a href="/guide/topics/resources/providing-resources.html#SmallestScreenWidthQualifier">smallest screen width</a> * configuration. */ ACONFIGURATION_SMALLEST_SCREEN_SIZE = 0x2000, /** * Bit mask for - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#LayoutDirectionQualifier">layout direction</a> + * <a href="/guide/topics/resources/providing-resources.html#LayoutDirectionQualifier">layout direction</a> * configuration. */ ACONFIGURATION_LAYOUTDIR = 0x4000, ACONFIGURATION_SCREEN_ROUND = 0x8000, /** * Bit mask for - * <a href="@dacRoot/guide/topics/resources/providing-resources.html#WideColorGamutQualifier">wide color gamut</a> - * and <a href="@dacRoot/guide/topics/resources/providing-resources.html#HDRQualifier">HDR</a> configurations. + * <a href="/guide/topics/resources/providing-resources.html#WideColorGamutQualifier">wide color gamut</a> + * and <a href="/guide/topics/resources/providing-resources.html#HDRQualifier">HDR</a> configurations. */ ACONFIGURATION_COLOR_MODE = 0x10000, /** diff --git a/include/android/imagedecoder.h b/include/android/imagedecoder.h index 3a87da0fee..d7e6e4118f 100644 --- a/include/android/imagedecoder.h +++ b/include/android/imagedecoder.h @@ -133,6 +133,8 @@ typedef struct AImageDecoder AImageDecoder; /** * Create a new {@link AImageDecoder} from an {@link AAsset}. * + * Available since API level 30. + * * @param asset {@link AAsset} containing encoded image data. Client is still * responsible for calling {@link AAsset_close} on it, which may be * done after deleting the returned {@link AImageDecoder}. @@ -162,6 +164,8 @@ int AImageDecoder_createFromAAsset(struct AAsset* asset, AImageDecoder** outDeco /** * Create a new {@link AImageDecoder} from a file descriptor. * + * Available since API level 30. + * * @param fd Seekable, readable, open file descriptor for encoded data. * Client is still responsible for closing it, which may be done * after deleting the returned {@link AImageDecoder}. @@ -190,6 +194,8 @@ int AImageDecoder_createFromFd(int fd, AImageDecoder** outDecoder) __INTRODUCED_ /** * Create a new AImageDecoder from a buffer. * + * Available since API level 30. + * * @param buffer Pointer to encoded data. Must be valid for the entire time * the {@link AImageDecoder} is used. * @param length Byte length of buffer. @@ -217,12 +223,16 @@ int AImageDecoder_createFromBuffer(const void* buffer, size_t length, /** * Delete the AImageDecoder. + * + * Available since API level 30. */ void AImageDecoder_delete(AImageDecoder* decoder) __INTRODUCED_IN(30); /** * Choose the desired output format. * + * Available since API level 30. + * * @param format {@link AndroidBitmapFormat} to use for the output. * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value * indicating the reason for the failure. On failure, the @@ -247,6 +257,8 @@ int AImageDecoder_setAndroidBitmapFormat(AImageDecoder*, * Pass true to this method to leave them unpremultiplied. This has no effect on an * opaque image. * + * Available since API level 30. + * * @param unpremultipliedRequired Pass true to leave the pixels unpremultiplied. * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value * indicating the reason for the failure. @@ -267,6 +279,8 @@ int AImageDecoder_setUnpremultipliedRequired(AImageDecoder*, * Ignored by {@link ANDROID_BITMAP_FORMAT_A_8}, which does not support * an {@link ADataSpace}. * + * Available since API level 30. + * * @param dataspace The {@link ADataSpace} to decode into. An ADataSpace * specifies how to interpret the colors. By default, * AImageDecoder will decode into the ADataSpace specified by @@ -292,6 +306,8 @@ int AImageDecoder_setDataSpace(AImageDecoder*, int32_t dataspace) __INTRODUCED_I * specified by width and height, and the output image will be the size of the * crop rect. * + * Available since API level 30. + * * @param width Width of the output (prior to cropping). * This will affect future calls to * {@link AImageDecoder_getMinimumStride}, which will now return @@ -319,6 +335,8 @@ int AImageDecoder_setTargetSize(AImageDecoder*, int32_t width, int32_t height) _ * others. This computes the most efficient target size to use to reach a * particular sampleSize. * + * Available since API level 30. + * * @param sampleSize A subsampling rate of the original image. Must be greater * than or equal to 1. A sampleSize of 2 means to skip every * other pixel/line, resulting in a width and height that are @@ -344,6 +362,8 @@ int AImageDecoder_computeSampledSize(const AImageDecoder*, int sampleSize, * the specified {@link ARect}. Clients will only need to allocate enough memory * for the cropped ARect. * + * Available since API level 30. + * * @param crop Rectangle describing a crop of the decode. It must be contained inside of * the (possibly scaled, by {@link AImageDecoder_setTargetSize}) * image dimensions. This will affect future calls to @@ -376,6 +396,8 @@ typedef struct AImageDecoderHeaderInfo AImageDecoderHeaderInfo; * * This is owned by the {@link AImageDecoder} and will be destroyed when the * AImageDecoder is destroyed via {@link AImageDecoder_delete}. + * + * Available since API level 30. */ const AImageDecoderHeaderInfo* AImageDecoder_getHeaderInfo( const AImageDecoder*) __INTRODUCED_IN(30); @@ -385,6 +407,8 @@ const AImageDecoderHeaderInfo* AImageDecoder_getHeaderInfo( * pixel width of the output, unless {@link AImageDecoder_setTargetSize} is * used to choose a different size or {@link AImageDecoder_setCrop} is used to * set a crop rect. + * + * Available since API level 30. */ int32_t AImageDecoderHeaderInfo_getWidth(const AImageDecoderHeaderInfo*) __INTRODUCED_IN(30); @@ -393,12 +417,16 @@ int32_t AImageDecoderHeaderInfo_getWidth(const AImageDecoderHeaderInfo*) __INTRO * pixel height of the output, unless {@link AImageDecoder_setTargetSize} is * used to choose a different size or {@link AImageDecoder_setCrop} is used to * set a crop rect. + * + * Available since API level 30. */ int32_t AImageDecoderHeaderInfo_getHeight(const AImageDecoderHeaderInfo*) __INTRODUCED_IN(30); /** * Report the mimeType of the encoded image. * + * Available since API level 30. + * * @return a string literal describing the mime type. */ const char* AImageDecoderHeaderInfo_getMimeType( @@ -409,6 +437,8 @@ const char* AImageDecoderHeaderInfo_getMimeType( * by default. {@link AImageDecoder} will try to choose one that is sensible * for the image and the system. Note that this does not indicate the * encoded format of the image. + * + * Available since API level 30. */ int32_t AImageDecoderHeaderInfo_getAndroidBitmapFormat( const AImageDecoderHeaderInfo*) __INTRODUCED_IN(30); @@ -419,6 +449,8 @@ int32_t AImageDecoderHeaderInfo_getAndroidBitmapFormat( * {@link ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE}. If the image may contain alpha, * this returns {@link ANDROID_BITMAP_FLAGS_ALPHA_PREMUL}, because * {@link AImageDecoder_decodeImage} will premultiply pixels by default. + * + * Available since API level 30. */ int AImageDecoderHeaderInfo_getAlphaFlags( const AImageDecoderHeaderInfo*) __INTRODUCED_IN(30); @@ -429,6 +461,8 @@ int AImageDecoderHeaderInfo_getAlphaFlags( * By default, {@link AImageDecoder_decodeImage} will not do any color * conversion. * + * Available since API level 30. + * * @return The {@link ADataSpace} representing the way the colors * are encoded (or {@link ADATASPACE_UNKNOWN} if there is not a * corresponding ADataSpace). This specifies how to interpret the colors @@ -452,12 +486,16 @@ int32_t AImageDecoderHeaderInfo_getDataSpace( * * If the output is scaled (via {@link AImageDecoder_setTargetSize}) and/or * cropped (via {@link AImageDecoder_setCrop}), this takes those into account. + * + * Available since API level 30. */ size_t AImageDecoder_getMinimumStride(AImageDecoder*) __INTRODUCED_IN(30); /** * Decode the image into pixels, using the settings of the {@link AImageDecoder}. * + * Available since API level 30. + * * @param decoder Opaque object representing the decoder. * @param pixels On success, will be filled with the result * of the decode. Must be large enough to hold |size| bytes. diff --git a/include/android/thermal.h b/include/android/thermal.h index 3247fa167b..83582d6791 100644 --- a/include/android/thermal.h +++ b/include/android/thermal.h @@ -60,8 +60,6 @@ extern "C" { #endif -#if __ANDROID_API__ >= 30 - enum AThermalStatus { /** Error in thermal status. */ ATHERMAL_STATUS_ERROR = -1, @@ -111,36 +109,45 @@ typedef struct AThermalManager AThermalManager; */ typedef void (*AThermal_StatusCallback)(void *data, AThermalStatus status); +#if __ANDROID_API__ >= 30 + /** * Acquire an instance of the thermal manager. This must be freed using * {@link AThermal_releaseManager}. * + * Available since API level 30. + * * @return manager instance on success, nullptr on failure. - */ -AThermalManager* AThermal_acquireManager(); + */ +AThermalManager* AThermal_acquireManager() __INTRODUCED_IN(30); /** * Release the thermal manager pointer acquired via * {@link AThermal_acquireManager}. * - * @param manager The manager to be released. + * Available since API level 30. * + * @param manager The manager to be released. */ -void AThermal_releaseManager(AThermalManager *manager); +void AThermal_releaseManager(AThermalManager *manager) __INTRODUCED_IN(30); /** * Gets the current thermal status. * + * Available since API level 30. + * * @param manager The manager instance to use to query the thermal status. * Acquired via {@link AThermal_acquireManager}. * * @return current thermal status, ATHERMAL_STATUS_ERROR on failure. -*/ -AThermalStatus AThermal_getCurrentThermalStatus(AThermalManager *manager); + */ +AThermalStatus AThermal_getCurrentThermalStatus(AThermalManager *manager) __INTRODUCED_IN(30); /** * Register the thermal status listener for thermal status change. * + * Available since API level 30. + * * @param manager The manager instance to use to register. * Acquired via {@link AThermal_acquireManager}. * @param callback The callback function to be called when thermal status updated. @@ -152,11 +159,13 @@ AThermalStatus AThermal_getCurrentThermalStatus(AThermalManager *manager); * EPIPE if communication with the system service has failed. */ int AThermal_registerThermalStatusListener(AThermalManager *manager, - AThermal_StatusCallback callback, void *data); + AThermal_StatusCallback callback, void *data) __INTRODUCED_IN(30); /** * Unregister the thermal status listener previously resgistered. * + * Available since API level 30. + * * @param manager The manager instance to use to unregister. * Acquired via {@link AThermal_acquireManager}. * @param callback The callback function to be called when thermal status updated. @@ -168,8 +177,7 @@ int AThermal_registerThermalStatusListener(AThermalManager *manager, * EPIPE if communication with the system service has failed. */ int AThermal_unregisterThermalStatusListener(AThermalManager *manager, - AThermal_StatusCallback callback, void *data); - + AThermal_StatusCallback callback, void *data) __INTRODUCED_IN(30); #endif // __ANDROID_API__ >= 30 diff --git a/include/android/trace.h b/include/android/trace.h index d59690ab2e..dbad6f6f21 100644 --- a/include/android/trace.h +++ b/include/android/trace.h @@ -115,7 +115,7 @@ void ATrace_setCounter(const char* counterName, int64_t counterValue) __INTRODUC #endif /* __ANDROID_API__ >= 29 */ #ifdef __cplusplus -}; +} #endif #endif // ANDROID_NATIVE_TRACE_H diff --git a/include/powermanager/IPowerManager.h b/include/powermanager/IPowerManager.h index 853f0c9fde..964e318584 100644 --- a/include/powermanager/IPowerManager.h +++ b/include/powermanager/IPowerManager.h @@ -46,10 +46,10 @@ public: IS_POWER_SAVE_MODE = IBinder::FIRST_CALL_TRANSACTION + 12, GET_POWER_SAVE_STATE = IBinder::FIRST_CALL_TRANSACTION + 13, SET_POWER_SAVE_MODE_ENABLED = IBinder::FIRST_CALL_TRANSACTION + 14, - REBOOT = IBinder::FIRST_CALL_TRANSACTION + 17, - REBOOT_SAFE_MODE = IBinder::FIRST_CALL_TRANSACTION + 18, - SHUTDOWN = IBinder::FIRST_CALL_TRANSACTION + 19, - CRASH = IBinder::FIRST_CALL_TRANSACTION + 20, + REBOOT = IBinder::FIRST_CALL_TRANSACTION + 21, + REBOOT_SAFE_MODE = IBinder::FIRST_CALL_TRANSACTION + 22, + SHUTDOWN = IBinder::FIRST_CALL_TRANSACTION + 23, + CRASH = IBinder::FIRST_CALL_TRANSACTION + 24, }; DECLARE_META_INTERFACE(PowerManager) diff --git a/libs/arect/Android.bp b/libs/arect/Android.bp index f66673f6ad..258a4e3748 100644 --- a/libs/arect/Android.bp +++ b/libs/arect/Android.bp @@ -29,6 +29,8 @@ cc_library_static { name: "libarect", host_supported: true, vendor_available: true, + // TODO(b/153609531): remove when no longer needed. + native_bridge_supported: true, export_include_dirs: ["include"], target: { windows: { diff --git a/libs/binder/AppOpsManager.cpp b/libs/binder/AppOpsManager.cpp index 2174ce2a88..1c6b49135d 100644 --- a/libs/binder/AppOpsManager.cpp +++ b/libs/binder/AppOpsManager.cpp @@ -91,12 +91,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>& attributionTag, const String16& message) { + const std::optional<String16>& attributionTag, const String16& message) { sp<IAppOpsService> service = getService(); int32_t mode = service != nullptr ? service->noteOperation(op, uid, callingPackage, attributionTag, @@ -108,12 +108,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>& attributionTag, + bool startIfModeDefault, const std::optional<String16>& attributionTag, const String16& message) { sp<IAppOpsService> service = getService(); int32_t mode = service != nullptr @@ -125,11 +125,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>& attributionTag) { + const std::optional<String16>& attributionTag) { sp<IAppOpsService> service = getService(); if (service != nullptr) { service->finishOperation(getClientId(), op, uid, callingPackage, attributionTag); diff --git a/libs/binder/IAppOpsService.cpp b/libs/binder/IAppOpsService.cpp index 0714723e02..cd78866624 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>& attributionTag, bool shouldCollectAsyncNotedOp, + const std::optional<String16>& attributionTag, 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>& attributionTag, + const String16& packageName, const std::optional<String16>& attributionTag, 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>& attributionTag) { + const String16& packageName, const std::optional<String16>& attributionTag) { 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> attributionTag; + std::optional<String16> attributionTag; data.readString16(&attributionTag); 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> attributionTag; + std::optional<String16> attributionTag; data.readString16(&attributionTag); 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> attributionTag; + std::optional<String16> attributionTag; data.readString16(&attributionTag); finishOperation(token, code, uid, packageName, attributionTag); reply->writeNoException(); diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp index c2bb811e9f..d8b44f957d 100644 --- a/libs/binder/IMemory.cpp +++ b/libs/binder/IMemory.cpp @@ -82,10 +82,10 @@ public: explicit BpMemoryHeap(const sp<IBinder>& impl); virtual ~BpMemoryHeap(); - virtual int getHeapID() const; - virtual void* getBase() const; - virtual size_t getSize() const; - virtual uint32_t getFlags() const; + int getHeapID() const override; + void* getBase() const override; + size_t getSize() const override; + uint32_t getFlags() const override; off_t getOffset() const override; private: diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp index a9f2d73951..05f43e3658 100644 --- a/libs/binder/IServiceManager.cpp +++ b/libs/binder/IServiceManager.cpp @@ -206,6 +206,10 @@ ServiceManagerShim::ServiceManagerShim(const sp<AidlServiceManager>& impl) : mTheRealServiceManager(impl) {} +// This implementation could be simplified and made more efficient by delegating +// to waitForService. However, this changes the threading structure in some +// cases and could potentially break prebuilts. Once we have higher logistical +// complexity, this could be attempted. sp<IBinder> ServiceManagerShim::getService(const String16& name) const { static bool gSystemBootCompleted = false; diff --git a/libs/binder/LazyServiceRegistrar.cpp b/libs/binder/LazyServiceRegistrar.cpp index 6f49aa1607..325e204203 100644 --- a/libs/binder/LazyServiceRegistrar.cpp +++ b/libs/binder/LazyServiceRegistrar.cpp @@ -45,25 +45,31 @@ protected: Status onClients(const sp<IBinder>& service, bool clients) override; private: + struct Service { + sp<IBinder> service; + bool allowIsolated; + int dumpFlags; + + // whether, based on onClients calls, we know we have a client for this + // service or not + bool clients = false; + }; + + /** + * Looks up a service guaranteed to be registered (service from onClients). + */ + std::map<std::string, Service>::iterator assertRegisteredService(const sp<IBinder>& service); + /** * Unregisters all services that we can. If we can't unregister all, re-register other * services. */ void tryShutdown(); - /** - * Counter of the number of services that currently have at least one client. - */ + // count of services with clients size_t mNumConnectedServices; - struct Service { - sp<IBinder> service; - bool allowIsolated; - int dumpFlags; - }; - /** - * Map of registered names and services - */ + // map of registered names and services std::map<std::string, Service> mRegisteredServices; bool mForcePersist; @@ -89,12 +95,28 @@ bool ClientCounterCallback::registerService(const sp<IBinder>& service, const st } // Only add this when a service is added for the first time, as it is not removed - mRegisteredServices[name] = {service, allowIsolated, dumpFlags}; + mRegisteredServices[name] = { + .service = service, + .allowIsolated = allowIsolated, + .dumpFlags = dumpFlags + }; } return true; } +std::map<std::string, ClientCounterCallback::Service>::iterator ClientCounterCallback::assertRegisteredService(const sp<IBinder>& service) { + LOG_ALWAYS_FATAL_IF(service == nullptr, "Got onClients callback for null service"); + for (auto it = mRegisteredServices.begin(); it != mRegisteredServices.end(); ++it) { + auto const& [name, registered] = *it; + (void) name; + if (registered.service != service) continue; + return it; + } + LOG_ALWAYS_FATAL("Got callback on service which we did not register: %s", String8(service->getInterfaceDescriptor()).c_str()); + __builtin_unreachable(); +} + void ClientCounterCallback::forcePersist(bool persist) { mForcePersist = persist; if(!mForcePersist) { @@ -108,15 +130,25 @@ void ClientCounterCallback::forcePersist(bool persist) { * invocations could occur on different threads however. */ Status ClientCounterCallback::onClients(const sp<IBinder>& service, bool clients) { - if (clients) { - mNumConnectedServices++; - } else { - mNumConnectedServices--; + auto & [name, registered] = *assertRegisteredService(service); + if (registered.clients == clients) { + LOG_ALWAYS_FATAL("Process already thought %s had clients: %d but servicemanager has " + "notified has clients: %d", name.c_str(), registered.clients, clients); + } + registered.clients = clients; + + // update cache count of clients + { + size_t numWithClients = 0; + for (const auto& [name, registered] : mRegisteredServices) { + (void) name; + if (registered.clients) numWithClients++; + } + mNumConnectedServices = numWithClients; } ALOGI("Process has %zu (of %zu available) client(s) in use after notification %s has clients: %d", - mNumConnectedServices, mRegisteredServices.size(), - String8(service->getInterfaceDescriptor()).string(), clients); + mNumConnectedServices, mRegisteredServices.size(), name.c_str(), clients); tryShutdown(); return Status::ok(); @@ -192,4 +224,4 @@ void LazyServiceRegistrar::forcePersist(bool persist) { } } // namespace hardware -} // namespace android
\ No newline at end of file +} // namespace android diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 9642a87f4e..166c1d8d07 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); } @@ -1007,6 +1072,15 @@ status_t Parcel::writeString8(const char* str, size_t len) 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) { @@ -1049,11 +1123,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); } @@ -1152,6 +1235,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); } @@ -1485,6 +1572,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; @@ -1496,6 +1594,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; @@ -1507,6 +1616,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); } @@ -1515,6 +1628,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); } @@ -1523,6 +1640,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); } @@ -1531,6 +1652,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); } @@ -1539,6 +1664,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); } @@ -1547,6 +1676,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; @@ -1599,6 +1750,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); } @@ -1608,6 +1763,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); } @@ -1617,6 +1777,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); } @@ -1808,6 +1973,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; @@ -1886,6 +2066,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(); @@ -2091,6 +2294,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); } @@ -2436,7 +2643,7 @@ status_t Parcel::growData(size_t len) size_t newSize = ((mDataSize+len)*3)/2; return (newSize <= mDataSize) ? (status_t) NO_MEMORY - : continueWrite(newSize); + : continueWrite(std::max(newSize, (size_t) 128)); } status_t Parcel::restartWrite(size_t desired) diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp index 4b773e816f..f3861bb2b5 100644 --- a/libs/binder/ProcessState.cpp +++ b/libs/binder/ProcessState.cpp @@ -328,6 +328,8 @@ void ProcessState::spawnPooledThread(bool isMain) } status_t ProcessState::setThreadPoolMaxThreadCount(size_t maxThreads) { + LOG_ALWAYS_FATAL_IF(mThreadPoolStarted && maxThreads < mMaxThreads, + "Binder threadpool cannot be shrunk after starting"); status_t result = NO_ERROR; if (ioctl(mDriverFD, BINDER_SET_MAX_THREADS, &maxThreads) != -1) { mMaxThreads = maxThreads; diff --git a/libs/binder/Status.cpp b/libs/binder/Status.cpp index 674f0657a9..64ab7a9d14 100644 --- a/libs/binder/Status.cpp +++ b/libs/binder/Status.cpp @@ -193,13 +193,15 @@ status_t Status::writeToParcel(Parcel* parcel) const { } status_t status = parcel->writeInt32(mException); - if (status != OK) { return status; } + if (status != OK) return status; if (mException == EX_NONE) { // We have no more information to write. return status; } status = parcel->writeString16(String16(mMessage)); + if (status != OK) return status; status = parcel->writeInt32(0); // Empty remote stack trace header + if (status != OK) return status; if (mException == EX_SERVICE_SPECIFIC) { status = parcel->writeInt32(mErrorCode); } else if (mException == EX_PARCELABLE) { diff --git a/libs/binder/TEST_MAPPING b/libs/binder/TEST_MAPPING index 9aa76512c8..c23228399b 100644 --- a/libs/binder/TEST_MAPPING +++ b/libs/binder/TEST_MAPPING @@ -7,6 +7,9 @@ "name": "binderVendorDoubleLoadTest" }, { + "name": "binderAllocationLimits" + }, + { "name": "binderDriverInterfaceTest" }, { @@ -29,6 +32,17 @@ }, { "name": "libbinderthreadstateutils_test" + }, + { + "name": "CtsOsTestCases", + "options": [ + { + "exclude-filter": "android.os.cts.BuildTest#testSdkInt" + }, + { + "exclude-filter": "android.os.cts.StrictModeTest#testNonSdkApiUsage" + } + ] } ] } diff --git a/libs/binder/include/binder/AppOpsManager.h b/libs/binder/include/binder/AppOpsManager.h index 6afcd77e70..6d04f13211 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 @@ -143,18 +145,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>& attributionTag, const String16& message); + const std::optional<String16>& attributionTag, 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>& attributionTag, + bool startIfModeDefault, const std::optional<String16>& attributionTag, 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>& attributionTag); + const std::optional<String16>& attributionTag); 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/BpBinder.h b/libs/binder/include/binder/BpBinder.h index 8e871b8214..378a91115e 100644 --- a/libs/binder/include/binder/BpBinder.h +++ b/libs/binder/include/binder/BpBinder.h @@ -137,7 +137,6 @@ private: volatile int32_t mObitsSent; Vector<Obituary>* mObituaries; ObjectManager mObjects; - Parcel* mConstantData; mutable String16 mDescriptorCache; int32_t mTrackedUid; diff --git a/libs/binder/include/binder/IAppOpsService.h b/libs/binder/include/binder/IAppOpsService.h index 1ffb8deaba..a4a20c8b10 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>& attributionTag, bool shouldCollectAsyncNotedOp, + const std::optional<String16>& attributionTag, 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>& attributionTag, + const String16& packageName, const std::optional<String16>& attributionTag, 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>& attributionTag) = 0; + const String16& packageName, const std::optional<String16>& attributionTag) = 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/IBinder.h b/libs/binder/include/binder/IBinder.h index 64604b74f0..eea0e89738 100644 --- a/libs/binder/include/binder/IBinder.h +++ b/libs/binder/include/binder/IBinder.h @@ -173,6 +173,10 @@ public: * The @a cookie is optional -- if non-NULL, it should be a * memory address that you own (that is, you know it is unique). * + * @note When all references to the binder being linked to are dropped, the + * recipient is automatically unlinked. So, you must hold onto a binder in + * order to receive death notifications about it. + * * @note You will only receive death notifications for remote binders, * as local binders by definition can't die without you dying as well. * Trying to use this function on a local binder will result in an diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h index 4818889436..b4e4a428b5 100644 --- a/libs/binder/include/binder/IPCThreadState.h +++ b/libs/binder/include/binder/IPCThreadState.h @@ -39,12 +39,28 @@ public: status_t clearLastError(); + /** + * Returns the PID of the process which has made the current binder + * call. If not in a binder call, this will return getpid. If the + * call is oneway, this will return 0. + */ pid_t getCallingPid() const; - // nullptr if unavailable - // - // this can't be restored once it's cleared, and it does not return the - // context of the current process when not in a binder call. + + /** + * Returns the SELinux security identifier of the process which has + * made the current binder call. If not in a binder call this will + * return nullptr. If this isn't requested with + * IBinder::setRequestingSid, it will also return nullptr. + * + * This can't be restored once it's cleared, and it does not return the + * context of the current process when not in a binder call. + */ const char* getCallingSid() const; + + /** + * Returns the UID of the process which has made the current binder + * call. If not in a binder call, this will return 0. + */ uid_t getCallingUid() const; void setStrictModePolicy(int32_t policy); diff --git a/libs/binder/include/binder/MemoryHeapBase.h b/libs/binder/include/binder/MemoryHeapBase.h index 3fccddcc59..edada3d1b5 100644 --- a/libs/binder/include/binder/MemoryHeapBase.h +++ b/libs/binder/include/binder/MemoryHeapBase.h @@ -57,14 +57,14 @@ public: virtual ~MemoryHeapBase(); /* implement IMemoryHeap interface */ - virtual int getHeapID() const; + int getHeapID() const override; /* virtual address of the heap. returns MAP_FAILED in case of error */ - virtual void* getBase() const; + void* getBase() const override; - virtual size_t getSize() const; - virtual uint32_t getFlags() const; - off_t getOffset() const override; + size_t getSize() const override; + uint32_t getFlags() const override; + off_t getOffset() const override; const char* getDevice() const; diff --git a/libs/binder/include/binder/Nullable.h b/libs/binder/include/binder/Nullable.h index b605bd3315..a98583dc16 100644 --- a/libs/binder/include/binder/Nullable.h +++ b/libs/binder/include/binder/Nullable.h @@ -15,7 +15,7 @@ */ #pragma once -#include <memory> +#include <optional> #include <utility> namespace android { @@ -32,11 +32,11 @@ namespace aidl { // c = std::move(a); template <typename T> -using nullable = std::unique_ptr<T>; +using nullable = std::optional<T>; template <typename T, typename... Args> inline nullable<T> make_nullable(Args&&... args) { - return std::make_unique<T>(std::forward<Args>(args)...); + return std::make_optional<T>(std::forward<Args>(args)...); } } // namespace aidl diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h index c1f64fb541..b6cfb8ec0f 100644 --- a/libs/binder/include/binder/Parcel.h +++ b/libs/binder/include/binder/Parcel.h @@ -121,6 +121,7 @@ public: status_t writeString8(const String8& str); status_t writeString8(const char* str, size_t len); 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); @@ -132,33 +133,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); @@ -167,14 +183,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); @@ -182,6 +204,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); @@ -195,6 +219,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- @@ -230,6 +256,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); @@ -279,6 +307,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; @@ -287,27 +316,34 @@ public: const char* readString8Inplace(size_t* outLen) 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; @@ -315,6 +351,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> @@ -323,31 +361,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; @@ -360,10 +412,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; @@ -399,6 +456,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; @@ -492,6 +551,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> @@ -501,9 +563,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> @@ -691,6 +759,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); @@ -715,6 +792,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); @@ -747,6 +840,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; @@ -841,6 +953,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(); @@ -901,6 +1037,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) { @@ -911,6 +1057,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) { @@ -926,6 +1082,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; @@ -939,7 +1119,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(); @@ -949,6 +1130,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; @@ -972,6 +1176,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()); } @@ -982,6 +1191,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); @@ -996,7 +1215,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>> @@ -1013,6 +1233,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()); @@ -1022,6 +1247,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); } @@ -1053,6 +1282,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; @@ -1068,6 +1308,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..71e1d3cbb4 100644 --- a/libs/binder/include/binder/ParcelFileDescriptor.h +++ b/libs/binder/include/binder/ParcelFileDescriptor.h @@ -31,7 +31,8 @@ class ParcelFileDescriptor : public android::Parcelable { public: ParcelFileDescriptor(); explicit ParcelFileDescriptor(android::base::unique_fd fd); - ParcelFileDescriptor(ParcelFileDescriptor&& other) : mFd(std::move(other.mFd)) { } + ParcelFileDescriptor(ParcelFileDescriptor&& other) noexcept : mFd(std::move(other.mFd)) { } + ParcelFileDescriptor& operator=(ParcelFileDescriptor&& other) noexcept = default; ~ParcelFileDescriptor() override; int get() const { return mFd.get(); } diff --git a/libs/binder/include/binder/Parcelable.h b/libs/binder/include/binder/Parcelable.h index a9166e2408..c1132795de 100644 --- a/libs/binder/include/binder/Parcelable.h +++ b/libs/binder/include/binder/Parcelable.h @@ -52,6 +52,12 @@ public: // // Returns android::OK on success and an appropriate error otherwise. virtual status_t readFromParcel(const Parcel* parcel) = 0; + + // 'Stable' means this parcelable is guaranteed to be stable for multiple years. + // It must be guaranteed by setting stability field in aidl_interface. + // WARNING: isStable() is only expected to be overridden by auto-generated code. + // Returns true if this parcelable is stable. + virtual bool isStable() const { return false; } }; // class Parcelable #if defined(__clang__) diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h index 4560f222cb..13dbec1826 100644 --- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h +++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h @@ -26,6 +26,7 @@ #pragma once +#include <stdbool.h> #include <stdint.h> #include <sys/cdefs.h> #include <sys/types.h> diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel.h b/libs/binder/ndk/include_ndk/android/binder_parcel.h index 86b75b8c61..a031e2973d 100644 --- a/libs/binder/ndk/include_ndk/android/binder_parcel.h +++ b/libs/binder/ndk/include_ndk/android/binder_parcel.h @@ -26,6 +26,7 @@ #pragma once +#include <stdbool.h> #include <stddef.h> #include <sys/cdefs.h> diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h index df5df13c19..09949ea259 100644 --- a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h +++ b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h @@ -831,34 +831,34 @@ inline binder_status_t AParcel_readVector(const AParcel* parcel, } /** - * Writes a vector of int8_t to the next location in a non-null parcel. + * Writes a vector of uint8_t to the next location in a non-null parcel. */ -inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<int8_t>& vec) { - return AParcel_writeByteArray(parcel, vec.data(), vec.size()); +inline binder_status_t AParcel_writeVector(AParcel* parcel, const std::vector<uint8_t>& vec) { + return AParcel_writeByteArray(parcel, reinterpret_cast<const int8_t*>(vec.data()), vec.size()); } /** - * Writes an optional vector of int8_t to the next location in a non-null parcel. + * Writes an optional vector of uint8_t to the next location in a non-null parcel. */ inline binder_status_t AParcel_writeVector(AParcel* parcel, - const std::optional<std::vector<int8_t>>& vec) { + const std::optional<std::vector<uint8_t>>& vec) { if (!vec) return AParcel_writeByteArray(parcel, nullptr, -1); return AParcel_writeVector(parcel, *vec); } /** - * Reads a vector of int8_t from the next location in a non-null parcel. + * Reads a vector of uint8_t from the next location in a non-null parcel. */ -inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<int8_t>* vec) { +inline binder_status_t AParcel_readVector(const AParcel* parcel, std::vector<uint8_t>* vec) { void* vectorData = static_cast<void*>(vec); return AParcel_readByteArray(parcel, vectorData, AParcel_stdVectorAllocator<int8_t>); } /** - * Reads an optional vector of int8_t from the next location in a non-null parcel. + * Reads an optional vector of uint8_t from the next location in a non-null parcel. */ inline binder_status_t AParcel_readVector(const AParcel* parcel, - std::optional<std::vector<int8_t>>* vec) { + std::optional<std::vector<uint8_t>>* vec) { void* vectorData = static_cast<void*>(vec); return AParcel_readByteArray(parcel, vectorData, AParcel_nullableStdVectorAllocator<int8_t>); } diff --git a/libs/binder/ndk/include_ndk/android/binder_status.h b/libs/binder/ndk/include_ndk/android/binder_status.h index ab9a144c53..3a55f9480c 100644 --- a/libs/binder/ndk/include_ndk/android/binder_status.h +++ b/libs/binder/ndk/include_ndk/android/binder_status.h @@ -26,6 +26,7 @@ #pragma once #include <errno.h> +#include <stdbool.h> #include <stdint.h> #include <sys/cdefs.h> diff --git a/libs/binder/ndk/test/Android.bp b/libs/binder/ndk/tests/Android.bp index 5f5265c90e..5f5265c90e 100644 --- a/libs/binder/ndk/test/Android.bp +++ b/libs/binder/ndk/tests/Android.bp diff --git a/libs/binder/ndk/test/AndroidTest.xml b/libs/binder/ndk/tests/AndroidTest.xml index 89646f7776..89646f7776 100644 --- a/libs/binder/ndk/test/AndroidTest.xml +++ b/libs/binder/ndk/tests/AndroidTest.xml diff --git a/libs/binder/ndk/test/IBinderNdkUnitTest.aidl b/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl index 6e8e463ff1..6e8e463ff1 100644 --- a/libs/binder/ndk/test/IBinderNdkUnitTest.aidl +++ b/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl diff --git a/libs/binder/ndk/test/IBinderVendorDoubleLoadTest.aidl b/libs/binder/ndk/tests/IBinderVendorDoubleLoadTest.aidl index 3a5bd9cc56..3a5bd9cc56 100644 --- a/libs/binder/ndk/test/IBinderVendorDoubleLoadTest.aidl +++ b/libs/binder/ndk/tests/IBinderVendorDoubleLoadTest.aidl diff --git a/libs/binder/ndk/test/IEmpty.aidl b/libs/binder/ndk/tests/IEmpty.aidl index 95e4341531..95e4341531 100644 --- a/libs/binder/ndk/test/IEmpty.aidl +++ b/libs/binder/ndk/tests/IEmpty.aidl diff --git a/libs/binder/ndk/test/binderVendorDoubleLoadTest.cpp b/libs/binder/ndk/tests/binderVendorDoubleLoadTest.cpp index ad78e319a2..ad78e319a2 100644 --- a/libs/binder/ndk/test/binderVendorDoubleLoadTest.cpp +++ b/libs/binder/ndk/tests/binderVendorDoubleLoadTest.cpp diff --git a/libs/binder/ndk/test/iface.cpp b/libs/binder/ndk/tests/iface.cpp index 64832f3081..64832f3081 100644 --- a/libs/binder/ndk/test/iface.cpp +++ b/libs/binder/ndk/tests/iface.cpp diff --git a/libs/binder/ndk/test/include/iface/iface.h b/libs/binder/ndk/tests/include/iface/iface.h index cdf5493216..cdf5493216 100644 --- a/libs/binder/ndk/test/include/iface/iface.h +++ b/libs/binder/ndk/tests/include/iface/iface.h diff --git a/libs/binder/ndk/test/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp index fd30d87c76..fd30d87c76 100644 --- a/libs/binder/ndk/test/libbinder_ndk_unit_test.cpp +++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp index c0da2cd8d4..2680e84784 100644 --- a/libs/binder/tests/Android.bp +++ b/libs/binder/tests/Android.bp @@ -169,3 +169,18 @@ cc_test { test_suites: ["device-tests"], require_root: true, } + +cc_test { + name: "binderAllocationLimits", + defaults: ["binder_test_defaults"], + srcs: ["binderAllocationLimits.cpp"], + shared_libs: [ + "libbinder", + "liblog", + "libutils", + "libutilscallstack", + "libbase", + ], + test_suites: ["device-tests"], + require_root: true, +} diff --git a/libs/binder/tests/binderAllocationLimits.cpp b/libs/binder/tests/binderAllocationLimits.cpp new file mode 100644 index 0000000000..e1f5ed5381 --- /dev/null +++ b/libs/binder/tests/binderAllocationLimits.cpp @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <android-base/logging.h> +#include <binder/Parcel.h> +#include <binder/IServiceManager.h> +#include <gtest/gtest.h> +#include <utils/CallStack.h> + +#include <malloc.h> +#include <functional> +#include <vector> + +struct DestructionAction { + DestructionAction(std::function<void()> f) : mF(std::move(f)) {} + ~DestructionAction() { mF(); }; +private: + std::function<void()> mF; +}; + +// Group of hooks +struct MallocHooks { + decltype(__malloc_hook) malloc_hook; + decltype(__realloc_hook) realloc_hook; + + static MallocHooks save() { + return { + .malloc_hook = __malloc_hook, + .realloc_hook = __realloc_hook, + }; + } + + void overwrite() const { + __malloc_hook = malloc_hook; + __realloc_hook = realloc_hook; + } +}; + +static const MallocHooks orig_malloc_hooks = MallocHooks::save(); + +// When malloc is hit, executes lambda. +namespace LambdaHooks { + using AllocationHook = std::function<void(size_t)>; + static std::vector<AllocationHook> lambdas = {}; + + static void* lambda_realloc_hook(void* ptr, size_t bytes, const void* arg); + static void* lambda_malloc_hook(size_t bytes, const void* arg); + + static const MallocHooks lambda_malloc_hooks = { + .malloc_hook = lambda_malloc_hook, + .realloc_hook = lambda_realloc_hook, + }; + + static void* lambda_malloc_hook(size_t bytes, const void* arg) { + { + orig_malloc_hooks.overwrite(); + lambdas.at(lambdas.size() - 1)(bytes); + lambda_malloc_hooks.overwrite(); + } + return orig_malloc_hooks.malloc_hook(bytes, arg); + } + + static void* lambda_realloc_hook(void* ptr, size_t bytes, const void* arg) { + { + orig_malloc_hooks.overwrite(); + lambdas.at(lambdas.size() - 1)(bytes); + lambda_malloc_hooks.overwrite(); + } + return orig_malloc_hooks.realloc_hook(ptr, bytes, arg); + } + +} + +// Action to execute when malloc is hit. Supports nesting. Malloc is not +// restricted when the allocation hook is being processed. +__attribute__((warn_unused_result)) +DestructionAction OnMalloc(LambdaHooks::AllocationHook f) { + MallocHooks before = MallocHooks::save(); + LambdaHooks::lambdas.emplace_back(std::move(f)); + LambdaHooks::lambda_malloc_hooks.overwrite(); + return DestructionAction([before]() { + before.overwrite(); + LambdaHooks::lambdas.pop_back(); + }); +} + +// exported symbol, to force compiler not to optimize away pointers we set here +const void* imaginary_use; + +TEST(TestTheTest, OnMalloc) { + size_t mallocs = 0; + { + const auto on_malloc = OnMalloc([&](size_t bytes) { + mallocs++; + EXPECT_EQ(bytes, 40); + }); + + imaginary_use = new int[10]; + } + EXPECT_EQ(mallocs, 1); +} + + +__attribute__((warn_unused_result)) +DestructionAction ScopeDisallowMalloc() { + return OnMalloc([&](size_t bytes) { + ADD_FAILURE() << "Unexpected allocation: " << bytes; + using android::CallStack; + std::cout << CallStack::stackToString("UNEXPECTED ALLOCATION", CallStack::getCurrent(4 /*ignoreDepth*/).get()) + << std::endl; + }); +} + +using android::IBinder; +using android::Parcel; +using android::String16; +using android::defaultServiceManager; +using android::sp; +using android::IServiceManager; + +static sp<IBinder> GetRemoteBinder() { + // This gets binder representing the service manager + // the current IServiceManager API doesn't expose the binder, and + // I want to avoid adding usages of the AIDL generated interface it + // is using underneath, so to avoid people copying it. + sp<IBinder> binder = defaultServiceManager()->checkService(String16("manager")); + EXPECT_NE(nullptr, binder); + return binder; +} + +TEST(BinderAllocation, ParcelOnStack) { + const auto m = ScopeDisallowMalloc(); + Parcel p; + imaginary_use = p.data(); +} + +TEST(BinderAllocation, GetServiceManager) { + defaultServiceManager(); // first call may alloc + const auto m = ScopeDisallowMalloc(); + defaultServiceManager(); +} + +// note, ping does not include interface descriptor +TEST(BinderAllocation, PingTransaction) { + sp<IBinder> a_binder = GetRemoteBinder(); + const auto m = ScopeDisallowMalloc(); + a_binder->pingBinder(); +} + +TEST(BinderAllocation, SmallTransaction) { + String16 empty_descriptor = String16(""); + sp<IServiceManager> manager = defaultServiceManager(); + + size_t mallocs = 0; + const auto on_malloc = OnMalloc([&](size_t bytes) { + mallocs++; + // Parcel should allocate a small amount by default + EXPECT_EQ(bytes, 128); + }); + manager->checkService(empty_descriptor); + + EXPECT_EQ(mallocs, 1); +} + +int main(int argc, char** argv) { + if (getenv("LIBC_HOOKS_ENABLE") == nullptr) { + CHECK(0 == setenv("LIBC_HOOKS_ENABLE", "1", true /*overwrite*/)); + execv(argv[0], argv); + return 1; + } + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/libs/binder/tests/binderThroughputTest.cpp b/libs/binder/tests/binderThroughputTest.cpp index b7909972ff..3b1faa8c2f 100644 --- a/libs/binder/tests/binderThroughputTest.cpp +++ b/libs/binder/tests/binderThroughputTest.cpp @@ -116,7 +116,7 @@ struct ProcResults { if (time > max_time_bucket) { m_long_transactions++; } - m_buckets[min(time, max_time_bucket-1) / time_per_bucket] += 1; + m_buckets[min((uint32_t)(time / time_per_bucket), num_buckets - 1)] += 1; m_best = min(time, m_best); m_worst = max(time, m_worst); m_transactions += 1; diff --git a/libs/dumputils/dump_utils.cpp b/libs/dumputils/dump_utils.cpp index fd557b71dd..2e144084c1 100644 --- a/libs/dumputils/dump_utils.cpp +++ b/libs/dumputils/dump_utils.cpp @@ -56,6 +56,10 @@ static const char* hal_interfaces_to_dump[] { "android.hardware.audio@4.0::IDevicesFactory", "android.hardware.audio@5.0::IDevicesFactory", "android.hardware.audio@6.0::IDevicesFactory", + "android.hardware.automotive.audiocontrol@1.0::IAudioControl", + "android.hardware.automotive.audiocontrol@2.0::IAudioControl", + "android.hardware.automotive.evs@1.0::IEvsCamera", + "android.hardware.automotive.vehicle@2.0::IVehicle", "android.hardware.biometrics.face@1.0::IBiometricsFace", "android.hardware.biometrics.fingerprint@2.1::IBiometricsFingerprint", "android.hardware.bluetooth@1.0::IBluetoothHci", @@ -67,16 +71,12 @@ static const char* hal_interfaces_to_dump[] { "android.hardware.media.c2@1.0::IComponentStore", "android.hardware.media.omx@1.0::IOmx", "android.hardware.media.omx@1.0::IOmxStore", + "android.hardware.neuralnetworks@1.0::IDevice", "android.hardware.power@1.3::IPower", "android.hardware.power.stats@1.0::IPowerStats", "android.hardware.sensors@1.0::ISensors", "android.hardware.thermal@2.0::IThermal", "android.hardware.vr@1.0::IVr", - "android.hardware.automotive.audiocontrol@1.0::IAudioControl", - "android.hardware.automotive.audiocontrol@2.0::IAudioControl", - "android.hardware.automotive.vehicle@2.0::IVehicle", - "android.hardware.automotive.evs@1.0::IEvsCamera", - "android.hardware.neuralnetworks@1.0::IDevice", NULL, }; diff --git a/libs/fakeservicemanager/Android.bp b/libs/fakeservicemanager/Android.bp index de32ff4e64..69096373fd 100644 --- a/libs/fakeservicemanager/Android.bp +++ b/libs/fakeservicemanager/Android.bp @@ -1,5 +1,6 @@ cc_defaults { name: "fakeservicemanager_defaults", + host_supported: true, srcs: [ "ServiceManager.cpp", ], diff --git a/libs/gralloc/OWNERS b/libs/gralloc/OWNERS index 67743cdb0e..4a957787cc 100644 --- a/libs/gralloc/OWNERS +++ b/libs/gralloc/OWNERS @@ -1,2 +1,2 @@ -marissaw@google.com +chrisforbes@google.com vhau@google.com diff --git a/libs/gui/OWNERS b/libs/gui/OWNERS index c13401dc5c..cbb4b9718e 100644 --- a/libs/gui/OWNERS +++ b/libs/gui/OWNERS @@ -1,12 +1,15 @@ adyabr@google.com akrulec@google.com alecmouri@google.com +chaviw@google.com +chrisforbes@google.com jessehall@google.com -jwcai@google.com lpy@google.com -marissaw@google.com mathias@google.com racarr@google.com steventhomas@google.com stoza@google.com vhau@google.com +vishnun@google.com + +per-file EndToEndNativeInputTest.cpp = svv@google.com diff --git a/libs/input/Android.bp b/libs/input/Android.bp index 8efaf3d90b..7037680935 100644 --- a/libs/input/Android.bp +++ b/libs/input/Android.bp @@ -34,6 +34,9 @@ cc_library { clang: true, + header_libs: ["jni_headers"], + export_header_lib_headers: ["jni_headers"], + shared_libs: [ "libbase", "liblog", diff --git a/libs/nativebase/Android.bp b/libs/nativebase/Android.bp index 9e7e4a2291..8399e8ce0a 100644 --- a/libs/nativebase/Android.bp +++ b/libs/nativebase/Android.bp @@ -16,6 +16,8 @@ cc_library_headers { name: "libnativebase_headers", vendor_available: true, host_supported: true, + // TODO(b/153609531): remove when no longer needed. + native_bridge_supported: true, export_include_dirs: ["include"], target: { diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp index ee006aaaba..52d73e0a56 100644 --- a/libs/nativewindow/Android.bp +++ b/libs/nativewindow/Android.bp @@ -25,6 +25,8 @@ cc_library_headers { name: "libnativewindow_headers", export_include_dirs: ["include"], vendor_available: true, + // TODO(b/153609531): remove when no longer needed. + native_bridge_supported: true, min_sdk_version: "29", } diff --git a/libs/ui/OWNERS b/libs/ui/OWNERS index 97ead2168d..203a7395e8 100644 --- a/libs/ui/OWNERS +++ b/libs/ui/OWNERS @@ -1,7 +1,6 @@ +chrisforbes@google.com lpy@google.com -marissaw@google.com mathias@google.com romainguy@google.com stoza@google.com -jwcai@google.com -tianyuj@google.com +vhau@google.com diff --git a/libs/vr/libbufferhub/Android.bp b/libs/vr/libbufferhub/Android.bp index 2fcee7bee6..37c19d43f7 100644 --- a/libs/vr/libbufferhub/Android.bp +++ b/libs/vr/libbufferhub/Android.bp @@ -16,6 +16,12 @@ cc_library_headers { name: "libbufferhub_headers", export_include_dirs: ["include"], vendor_available: true, // TODO(b/112338314): Does shouldn't be available to vendor. + apex_available: [ + "//apex_available:platform", + "com.android.media", + "com.android.media.swcodec", + ], + min_sdk_version: "29", } sourceFiles = [ diff --git a/libs/vr/libdvr/Android.bp b/libs/vr/libdvr/Android.bp index 81a9b2d26a..340d7bf19a 100644 --- a/libs/vr/libdvr/Android.bp +++ b/libs/vr/libdvr/Android.bp @@ -17,6 +17,12 @@ cc_library_headers { name: "libdvr_headers", export_include_dirs: ["include"], vendor_available: true, + apex_available: [ + "//apex_available:platform", + "com.android.media", + "com.android.media.swcodec", + ], + min_sdk_version: "29", } cc_library_headers { diff --git a/libs/vr/libpdx/fuzz/Android.bp b/libs/vr/libpdx/fuzz/Android.bp new file mode 100644 index 0000000000..34907751fa --- /dev/null +++ b/libs/vr/libpdx/fuzz/Android.bp @@ -0,0 +1,23 @@ +cc_fuzz { + name: "libpdx_fuzz", + clang: true, + srcs: [ + "service_dispatcher_fuzzer.cpp", + ], + cflags: [ + "-Wall", + "-Wextra", + "-Werror", + ], + static_libs: [ + "libpdx", + ], + shared_libs: [ + "libutils", + "liblog", + ], + fuzz_config: { + fuzz_on_haiku_host: false, + fuzz_on_haiku_device: false, + }, +} diff --git a/libs/vr/libpdx/fuzz/helpers.h b/libs/vr/libpdx/fuzz/helpers.h new file mode 100644 index 0000000000..83ec4096f6 --- /dev/null +++ b/libs/vr/libpdx/fuzz/helpers.h @@ -0,0 +1,294 @@ +/* + * Copyright 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Authors: corbin.souffrant@leviathansecurity.com +// brian.balling@leviathansecurity.com + +#ifndef LEV_FUZZERS_LIBPDX_HELPERS_H_ +#define LEV_FUZZERS_LIBPDX_HELPERS_H_ + +#define UNUSED(expr) \ + do { \ + (void)(expr); \ + } while (0) + +#include <fuzzer/FuzzedDataProvider.h> +#include <pdx/client.h> +#include <pdx/service.h> +#include <pdx/service_dispatcher.h> +#include <pdx/service_endpoint.h> +#include <sys/eventfd.h> +#include <memory> +#include <vector> + +using namespace android::pdx; + +// Vector of operations we can call in the dispatcher. +static const std::vector<std::function<void( + const std::unique_ptr<ServiceDispatcher>&, FuzzedDataProvider*)>> + dispatcher_operations = { + [](const std::unique_ptr<ServiceDispatcher>& dispatcher, + FuzzedDataProvider*) -> void { dispatcher->EnterDispatchLoop(); }, + [](const std::unique_ptr<ServiceDispatcher>& dispatcher, + FuzzedDataProvider*) -> void { dispatcher->ReceiveAndDispatch(); }, + [](const std::unique_ptr<ServiceDispatcher>& dispatcher, + FuzzedDataProvider* fdp) -> void { + dispatcher->ReceiveAndDispatch(fdp->ConsumeIntegral<int>()); + }}; + +// Most of the fuzzing occurs within the endpoint, which is derived from an +// abstract class. So we are returning garbage data for most functions besides +// the ones we added or need to actually use. +class FuzzEndpoint : public Endpoint { + public: + explicit FuzzEndpoint(FuzzedDataProvider* fdp) { + _fdp = fdp; + _epoll_fd = eventfd(0, 0); + } + + ~FuzzEndpoint() { close(_epoll_fd); } + + // Returns an fd that can be used with epoll() to wait for incoming messages + // from this endpoint. + int epoll_fd() const { return _epoll_fd; } + + // Associates a Service instance with an endpoint by setting the service + // context pointer to the address of the Service. Only one Service may be + // associated with a given endpoint. + Status<void> SetService(Service* service) { + _service = service; + return Status<void>(0); + } + + // Set the channel context for the given channel. + Status<void> SetChannel(int channel_id, Channel* channel) { + UNUSED(channel_id); + _channel = std::shared_ptr<Channel>(channel); + return Status<void>(0); + } + + // Receives a message on the given endpoint file descriptor. + // This is called by the dispatcher to determine what operations + // to make, so we are fuzzing the response. + Status<void> MessageReceive(Message* message) { + // Create a randomized MessageInfo struct. + MessageInfo info; + eventfd_t wakeup_val = 0; + info.pid = _fdp->ConsumeIntegral<int>(); + info.tid = _fdp->ConsumeIntegral<int>(); + info.cid = _fdp->ConsumeIntegral<int>(); + info.mid = _fdp->ConsumeIntegral<int>(); + info.euid = _fdp->ConsumeIntegral<int>(); + info.egid = _fdp->ConsumeIntegral<int>(); + info.op = _fdp->ConsumeIntegral<int32_t>(); + info.flags = _fdp->ConsumeIntegral<uint32_t>(); + info.service = _service; + info.channel = _channel.get(); + info.send_len = _fdp->ConsumeIntegral<size_t>(); + info.recv_len = _fdp->ConsumeIntegral<size_t>(); + info.fd_count = _fdp->ConsumeIntegral<size_t>(); + if (_fdp->remaining_bytes() >= 32) { + std::vector<uint8_t> impulse_vec = _fdp->ConsumeBytes<uint8_t>(32); + memcpy(info.impulse, impulse_vec.data(), 32); + } + + *message = Message(info); + eventfd_read(_epoll_fd, &wakeup_val); + + return Status<void>(); + } + + // Returns a tag that uniquely identifies a specific underlying IPC + // transport. + uint32_t GetIpcTag() const { return 0; } + + // Close a channel, signaling the client file object and freeing the channel + // id. Once closed, the client side of the channel always returns the error + // ESHUTDOWN and signals the poll/epoll events POLLHUP and POLLFREE. + Status<void> CloseChannel(int channel_id) { + UNUSED(channel_id); + return Status<void>(); + } + + // Update the event bits for the given channel (given by id), using the + // given clear and set masks. + Status<void> ModifyChannelEvents(int channel_id, int clear_mask, + int set_mask) { + UNUSED(channel_id); + UNUSED(clear_mask); + UNUSED(set_mask); + return Status<void>(); + } + + // Create a new channel and push it as a file descriptor to the process + // sending the |message|. |flags| may be set to O_NONBLOCK and/or + // O_CLOEXEC to control the initial behavior of the new file descriptor (the + // sending process may change these later using fcntl()). The internal + // Channel instance associated with this channel is set to |channel|, + // which may be nullptr. The new channel id allocated for this channel is + // returned in |channel_id|, which may also be nullptr if not needed. + Status<RemoteChannelHandle> PushChannel(Message* message, int flags, + Channel* channel, int* channel_id) { + UNUSED(message); + UNUSED(flags); + UNUSED(channel); + UNUSED(channel_id); + return Status<RemoteChannelHandle>(); + } + + // Check whether the |ref| is a reference to a channel to the service + // represented by the |endpoint|. If the channel reference in question is + // valid, the Channel object is returned in |channel| when non-nullptr and + // the channel ID is returned through the Status object. + Status<int> CheckChannel(const Message* message, ChannelReference ref, + Channel** channel) { + UNUSED(message); + UNUSED(ref); + UNUSED(channel); + return Status<int>(); + } + + // Replies to the message with a return code. + Status<void> MessageReply(Message* message, int return_code) { + UNUSED(message); + UNUSED(return_code); + return Status<void>(); + } + + // Replies to the message with a file descriptor. + Status<void> MessageReplyFd(Message* message, unsigned int push_fd) { + UNUSED(message); + UNUSED(push_fd); + return Status<void>(); + } + + // Replies to the message with a local channel handle. + Status<void> MessageReplyChannelHandle(Message* message, + const LocalChannelHandle& handle) { + UNUSED(message); + UNUSED(handle); + return Status<void>(); + } + + // Replies to the message with a borrowed local channel handle. + Status<void> MessageReplyChannelHandle(Message* message, + const BorrowedChannelHandle& handle) { + UNUSED(message); + UNUSED(handle); + return Status<void>(); + } + + // Replies to the message with a remote channel handle. + Status<void> MessageReplyChannelHandle(Message* message, + const RemoteChannelHandle& handle) { + UNUSED(message); + UNUSED(handle); + return Status<void>(); + } + + // Reads message data into an array of memory buffers. + Status<size_t> ReadMessageData(Message* message, const iovec* vector, + size_t vector_length) { + UNUSED(message); + UNUSED(vector); + UNUSED(vector_length); + return Status<size_t>(); + } + + // Sends reply data for message. + Status<size_t> WriteMessageData(Message* message, const iovec* vector, + size_t vector_length) { + UNUSED(message); + UNUSED(vector); + UNUSED(vector_length); + return Status<size_t>(); + } + + // Records a file descriptor into the message buffer and returns the + // remapped reference to be sent to the remote process. + Status<FileReference> PushFileHandle(Message* message, + const LocalHandle& handle) { + UNUSED(message); + UNUSED(handle); + return Status<FileReference>(); + } + + Status<FileReference> PushFileHandle(Message* message, + const BorrowedHandle& handle) { + UNUSED(message); + UNUSED(handle); + return Status<FileReference>(); + } + + Status<FileReference> PushFileHandle(Message* message, + const RemoteHandle& handle) { + UNUSED(message); + UNUSED(handle); + return Status<FileReference>(); + } + + Status<ChannelReference> PushChannelHandle(Message* message, + const LocalChannelHandle& handle) { + UNUSED(message); + UNUSED(handle); + return Status<ChannelReference>(); + } + + Status<ChannelReference> PushChannelHandle( + Message* message, const BorrowedChannelHandle& handle) { + UNUSED(message); + UNUSED(handle); + return Status<ChannelReference>(); + } + + Status<ChannelReference> PushChannelHandle( + Message* message, const RemoteChannelHandle& handle) { + UNUSED(message); + UNUSED(handle); + return Status<ChannelReference>(); + } + + // Obtains a file descriptor/channel handle from a message for the given + // reference. + LocalHandle GetFileHandle(Message* message, FileReference ref) const { + UNUSED(message); + UNUSED(ref); + return LocalHandle(); + } + + LocalChannelHandle GetChannelHandle(Message* message, + ChannelReference ref) const { + UNUSED(message); + UNUSED(ref); + return LocalChannelHandle(); + } + + // Transport-specific message state management. + void* AllocateMessageState() { return nullptr; } + + void FreeMessageState(void* state) { UNUSED(state); } + + // Cancels the endpoint, unblocking any receiver threads waiting for a + // message. + Status<void> Cancel() { return Status<void>(); } + + private: + FuzzedDataProvider* _fdp; + std::shared_ptr<Channel> _channel; + Service* _service; + int _epoll_fd; +}; + +#endif // LEV_FUZZERS_LIBPDX_HELPERS_H_ diff --git a/libs/vr/libpdx/fuzz/service_dispatcher_fuzzer.cpp b/libs/vr/libpdx/fuzz/service_dispatcher_fuzzer.cpp new file mode 100644 index 0000000000..3a3bfd9bcf --- /dev/null +++ b/libs/vr/libpdx/fuzz/service_dispatcher_fuzzer.cpp @@ -0,0 +1,74 @@ +/* + * Copyright 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Authors: corbin.souffrant@leviathansecurity.com +// brian.balling@leviathansecurity.com + +#include <fuzzer/FuzzedDataProvider.h> +#include <helpers.h> +#include <pdx/client_channel.h> +#include <pdx/service.h> +#include <pdx/service_dispatcher.h> +#include <stddef.h> +#include <stdint.h> +#include <sys/eventfd.h> +#include <thread> + +using namespace android::pdx; + +// Dispatch fuzzer entry point. This fuzzer creates a ServiceDispatcher +// and creates an endpoint that returns fuzzed messages that are passed +// to the ReceiveAndDispatch and DispatchLoop functions. +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + eventfd_t wakeup_val = 1; + FuzzedDataProvider fdp = FuzzedDataProvider(data, size); + + // Endpoint is only used to be immediately wrapped as a unique_ptr, + // so it is ok to be using a raw ptr and new here without freeing. + FuzzEndpoint* endpoint = new FuzzEndpoint(&fdp); + std::unique_ptr<ServiceDispatcher> dispatcher = ServiceDispatcher::Create(); + std::shared_ptr<Channel> channel(nullptr); + std::shared_ptr<Client> client(nullptr); + std::shared_ptr<Service> service( + new Service("FuzzService", std::unique_ptr<Endpoint>(endpoint))); + + service->SetChannel(0, std::shared_ptr<Channel>(channel)); + dispatcher->AddService(service); + + // Dispatcher blocks, so needs to run in its own thread. + std::thread run_dispatcher([&]() { + uint8_t opt = 0; + + // Right now the only operations block, so the while loop is pointless + // but leaving it in, just in case that ever changes. + while (fdp.remaining_bytes() > sizeof(MessageInfo)) { + opt = fdp.ConsumeIntegral<uint8_t>() % dispatcher_operations.size(); + dispatcher_operations[opt](dispatcher, &fdp); + } + }); + + // Continuously wake up the epoll so the dispatcher can run. + while (fdp.remaining_bytes() > sizeof(MessageInfo)) { + eventfd_write(endpoint->epoll_fd(), wakeup_val); + } + + // Cleanup the dispatcher and thread. + dispatcher->SetCanceled(true); + if (run_dispatcher.joinable()) + run_dispatcher.join(); + dispatcher->RemoveService(service); + + return 0; +} diff --git a/opengl/libs/EGL/FileBlobCache.cpp b/opengl/libs/EGL/FileBlobCache.cpp index cc42ac7fef..328477806f 100644 --- a/opengl/libs/EGL/FileBlobCache.cpp +++ b/opengl/libs/EGL/FileBlobCache.cpp @@ -17,11 +17,13 @@ #include "FileBlobCache.h" #include <errno.h> +#include <fcntl.h> #include <inttypes.h> -#include <log/log.h> #include <sys/mman.h> #include <sys/stat.h> +#include <unistd.h> +#include <log/log.h> // Cache file header static const char* cacheFileMagic = "EGL$"; diff --git a/opengl/tests/gl2_jni/Android.bp b/opengl/tests/gl2_jni/Android.bp index 65f89b159e..8d4323f9ca 100644 --- a/opengl/tests/gl2_jni/Android.bp +++ b/opengl/tests/gl2_jni/Android.bp @@ -17,6 +17,7 @@ cc_library_shared { "-Werror", "-Wno-error=unused-parameter", ], + header_libs: ["jni_headers"], srcs: ["jni/gl_code.cpp"], shared_libs: [ "liblog", diff --git a/opengl/tests/gl_jni/Android.bp b/opengl/tests/gl_jni/Android.bp index 5bec336dd1..0cb129a117 100644 --- a/opengl/tests/gl_jni/Android.bp +++ b/opengl/tests/gl_jni/Android.bp @@ -19,6 +19,7 @@ cc_library_shared { "-Werror", "-Wno-error=unused-parameter", ], + header_libs: ["jni_headers"], srcs: ["jni/gl_code.cpp"], shared_libs: [ "liblog", diff --git a/opengl/tests/gl_perfapp/Android.bp b/opengl/tests/gl_perfapp/Android.bp index cf899acfee..66afb6a82c 100644 --- a/opengl/tests/gl_perfapp/Android.bp +++ b/opengl/tests/gl_perfapp/Android.bp @@ -17,6 +17,7 @@ cc_library_shared { "-Werror", "-Wno-error=unused-parameter", ], + header_libs: ["jni_headers"], srcs: ["jni/gl_code.cpp"], shared_libs: [ "liblog", diff --git a/opengl/tests/gldual/Android.bp b/opengl/tests/gldual/Android.bp index 24325666e6..1006d44e47 100644 --- a/opengl/tests/gldual/Android.bp +++ b/opengl/tests/gldual/Android.bp @@ -20,6 +20,7 @@ cc_library_shared { "-Werror", "-Wno-error=unused-parameter", ], + header_libs: ["jni_headers"], srcs: ["jni/gl_code.cpp"], shared_libs: [ "liblog", diff --git a/opengl/tools/glgen/gen b/opengl/tools/glgen/gen index 41fcf1bd95..9efd38fff9 100755 --- a/opengl/tools/glgen/gen +++ b/opengl/tools/glgen/gen @@ -1,6 +1,18 @@ #!/bin/bash set -u set -e + +if [ -z "$ANDROID_BUILD_TOP" ] ; then + echo "ANDROID_BUILD_TOP is not set, did you run lunch?" + exit 1 +fi + +# Avoid spewing files in any location other than the intended one. +if [ ! -x "$PWD/gen" ] ; then + echo "Run this script from its parent directory". + exit 1 +fi + rm -rf out generated mkdir out @@ -92,7 +104,7 @@ rm src/*.class # Add UnsupportedAppUsage.java to known sources. mkdir -p out/android/compat/annotation -cp ../../../../../tools/platform-compat/annotation/src/java/android/compat/annotation/UnsupportedAppUsage.java out/android/compat/annotation +cp ${ANDROID_BUILD_TOP}/tools/platform-compat/java/android/compat/annotation/UnsupportedAppUsage.java out/android/compat/annotation pushd out > /dev/null mkdir classes @@ -153,23 +165,23 @@ compareGenerated() { fi } -compareGenerated ../../../../base/core/jni generated/C com_google_android_gles_jni_GLImpl.cpp -compareGenerated ../../../../base/opengl/java/com/google/android/gles_jni generated/com/google/android/gles_jni GLImpl.java +compareGenerated ${ANDROID_BUILD_TOP}/frameworks/base/core/jni generated/C com_google_android_gles_jni_GLImpl.cpp +compareGenerated ${ANDROID_BUILD_TOP}/frameworks/base/opengl/java/com/google/android/gles_jni generated/com/google/android/gles_jni GLImpl.java for x in GL.java GL10.java GL10Ext.java GL11.java GL11Ext.java GL11ExtensionPack.java do - compareGenerated ../../../../base/opengl/java/javax/microedition/khronos/opengles generated/javax/microedition/khronos/opengles $x + compareGenerated ${ANDROID_BUILD_TOP}/frameworks/base/opengl/java/javax/microedition/khronos/opengles generated/javax/microedition/khronos/opengles $x done for x in EGL14 EGL15 EGLExt GLES10 GLES10Ext GLES11 GLES11Ext GLES20 GLES30 GLES31 GLES31Ext GLES32 do - compareGenerated ../../../../base/opengl/java/android/opengl generated/android/opengl ${x}.java - compareGenerated ../../../../base/core/jni generated/C android_opengl_${x}.cpp + compareGenerated ${ANDROID_BUILD_TOP}/frameworks/base/opengl/java/android/opengl generated/android/opengl ${x}.java + compareGenerated ${ANDROID_BUILD_TOP}/frameworks/base/core/jni generated/C android_opengl_${x}.cpp done for x in EGLConfig EGLContext EGLDisplay EGLObjectHandle EGLSurface EGLImage EGLSync do - compareGenerated ../../../../base/opengl/java/android/opengl generated/android/opengl ${x}.java + compareGenerated ${ANDROID_BUILD_TOP}/frameworks/base/opengl/java/android/opengl generated/android/opengl ${x}.java done if [ $KEEP_GENERATED == "0" ] ; then diff --git a/opengl/tools/glgen/stubs/egl/EGL14Header.java-if b/opengl/tools/glgen/stubs/egl/EGL14Header.java-if index 9932556d27..951ecffc32 100644 --- a/opengl/tools/glgen/stubs/egl/EGL14Header.java-if +++ b/opengl/tools/glgen/stubs/egl/EGL14Header.java-if @@ -21,8 +21,8 @@ package android.opengl; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.SurfaceTexture; import android.view.Surface; -import android.view.SurfaceView; import android.view.SurfaceHolder; +import android.view.SurfaceView; /** * EGL 1.4 diff --git a/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl b/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl index afcc3ebe7f..32c9d7d09f 100644 --- a/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl +++ b/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl @@ -19,6 +19,7 @@ package com.google.android.gles_jni; import android.app.AppGlobals; +import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.os.Build; @@ -26,6 +27,7 @@ import android.os.UserHandle; import android.util.Log; import java.nio.Buffer; + import javax.microedition.khronos.opengles.GL10; import javax.microedition.khronos.opengles.GL10Ext; import javax.microedition.khronos.opengles.GL11; @@ -55,6 +57,7 @@ public class GLImpl implements GL10, GL10Ext, GL11, GL11Ext, GL11ExtensionPack { private boolean have_OES_framebuffer_object; private boolean have_OES_texture_cube_map; + @UnsupportedAppUsage public GLImpl() { } diff --git a/services/inputflinger/host/Android.bp b/services/inputflinger/host/Android.bp index cbe0190dfa..b56f356dfd 100644 --- a/services/inputflinger/host/Android.bp +++ b/services/inputflinger/host/Android.bp @@ -21,6 +21,7 @@ cc_library_shared { "InputHost.cpp", ], + header_libs: ["jni_headers"], shared_libs: [ "libbinder", "libcrypto", @@ -42,6 +43,7 @@ cc_library_shared { //-fvisibility=hidden ], + export_header_lib_headers: ["jni_headers"], export_include_dirs: ["."], } diff --git a/services/sensorservice/hidl/Android.bp b/services/sensorservice/hidl/Android.bp index d0c83d6002..0e1af595f0 100644 --- a/services/sensorservice/hidl/Android.bp +++ b/services/sensorservice/hidl/Android.bp @@ -10,6 +10,7 @@ cc_library_shared { "-Wall", "-Werror", ], + header_libs: ["jni_headers"], shared_libs: [ "libbase", "libhidlbase", @@ -24,6 +25,7 @@ cc_library_shared { export_include_dirs: [ "include/" ], + export_header_lib_headers: ["jni_headers"], local_include_dirs: [ "include/sensorservicehidl/" ] diff --git a/services/surfaceflinger/OWNERS b/services/surfaceflinger/OWNERS index f2bc65db35..c5a4689dda 100644 --- a/services/surfaceflinger/OWNERS +++ b/services/surfaceflinger/OWNERS @@ -3,8 +3,8 @@ akrulec@google.com alecmouri@google.com chaviw@google.com lpy@google.com -marissaw@google.com racarr@google.com steventhomas@google.com stoza@google.com vhau@google.com +vishnun@google.com diff --git a/services/vr/virtual_touchpad/Android.bp b/services/vr/virtual_touchpad/Android.bp index dcaa663160..9cf4905b68 100644 --- a/services/vr/virtual_touchpad/Android.bp +++ b/services/vr/virtual_touchpad/Android.bp @@ -14,6 +14,7 @@ shared_libs = [ ] header_libraries = [ + "jni_headers", "libdvr_headers", ] diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp index 7bcb2c1441..74ef0e7073 100644 --- a/vulkan/libvulkan/driver.cpp +++ b/vulkan/libvulkan/driver.cpp @@ -161,7 +161,7 @@ void* LoadLibrary(const android_dlextinfo& dlextinfo, } const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{ - "ro.hardware." HWVULKAN_HARDWARE_MODULE_ID, + "ro.hardware.vulkan", "ro.board.platform", }}; |