diff options
195 files changed, 3239 insertions, 1003 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/build/phone-hdpi-512-dalvik-heap.mk b/build/phone-hdpi-512-dalvik-heap.mk index 102c3f1f66..f9a12ef377 100644 --- a/build/phone-hdpi-512-dalvik-heap.mk +++ b/build/phone-hdpi-512-dalvik-heap.mk @@ -17,10 +17,10 @@ # Provides overrides to configure the Dalvik heap for a standard high density # phone with around 512MB total RAM. -PRODUCT_PROPERTY_OVERRIDES += \ - dalvik.vm.heapstartsize=5m \ - dalvik.vm.heapgrowthlimit=48m \ - dalvik.vm.heapsize=128m \ - dalvik.vm.heaptargetutilization=0.75 \ - dalvik.vm.heapminfree=512k \ - dalvik.vm.heapmaxfree=2m +PRODUCT_VENDOR_PROPERTIES += \ + dalvik.vm.heapstartsize?=5m \ + dalvik.vm.heapgrowthlimit?=48m \ + dalvik.vm.heapsize?=128m \ + dalvik.vm.heaptargetutilization?=0.75 \ + dalvik.vm.heapminfree?=512k \ + dalvik.vm.heapmaxfree?=2m diff --git a/build/phone-hdpi-dalvik-heap.mk b/build/phone-hdpi-dalvik-heap.mk index cc0ac90298..71cce7492a 100644 --- a/build/phone-hdpi-dalvik-heap.mk +++ b/build/phone-hdpi-dalvik-heap.mk @@ -16,9 +16,9 @@ # Provides overrides to configure the Dalvik heap for a standard high density phone. -PRODUCT_PROPERTY_OVERRIDES += \ - dalvik.vm.heapstartsize=5m \ - dalvik.vm.heapsize=32m \ - dalvik.vm.heaptargetutilization=0.75 \ - dalvik.vm.heapminfree=512k \ - dalvik.vm.heapmaxfree=2m +PRODUCT_VENDOR_PROPERTIES += \ + dalvik.vm.heapstartsize?=5m \ + dalvik.vm.heapsize?=32m \ + dalvik.vm.heaptargetutilization?=0.75 \ + dalvik.vm.heapminfree?=512k \ + dalvik.vm.heapmaxfree?=2m diff --git a/build/phone-xhdpi-1024-dalvik-heap.mk b/build/phone-xhdpi-1024-dalvik-heap.mk index 221227d4d8..a522a7dc7c 100644 --- a/build/phone-xhdpi-1024-dalvik-heap.mk +++ b/build/phone-xhdpi-1024-dalvik-heap.mk @@ -16,10 +16,10 @@ # Provides overrides to configure the Dalvik heap for a xhdpi phone -PRODUCT_PROPERTY_OVERRIDES += \ - dalvik.vm.heapstartsize=8m \ - dalvik.vm.heapgrowthlimit=96m \ - dalvik.vm.heapsize=256m \ - dalvik.vm.heaptargetutilization=0.75 \ - dalvik.vm.heapminfree=512k \ - dalvik.vm.heapmaxfree=8m +PRODUCT_VENDOR_PROPERTIES += \ + dalvik.vm.heapstartsize?=8m \ + dalvik.vm.heapgrowthlimit?=96m \ + dalvik.vm.heapsize?=256m \ + dalvik.vm.heaptargetutilization?=0.75 \ + dalvik.vm.heapminfree?=512k \ + dalvik.vm.heapmaxfree?=8m diff --git a/build/phone-xhdpi-2048-dalvik-heap.mk b/build/phone-xhdpi-2048-dalvik-heap.mk index 7ccfc13702..f38d2f22c3 100644 --- a/build/phone-xhdpi-2048-dalvik-heap.mk +++ b/build/phone-xhdpi-2048-dalvik-heap.mk @@ -17,10 +17,10 @@ # Provides overrides to configure the Dalvik heap for a 2GB phone # 192m of RAM gives enough space for 5 8 megapixel camera bitmaps in RAM. -PRODUCT_PROPERTY_OVERRIDES += \ - dalvik.vm.heapstartsize=8m \ - dalvik.vm.heapgrowthlimit=192m \ - dalvik.vm.heapsize=512m \ - dalvik.vm.heaptargetutilization=0.75 \ - dalvik.vm.heapminfree=512k \ - dalvik.vm.heapmaxfree=8m +PRODUCT_VENDOR_PROPERTIES += \ + dalvik.vm.heapstartsize?=8m \ + dalvik.vm.heapgrowthlimit?=192m \ + dalvik.vm.heapsize?=512m \ + dalvik.vm.heaptargetutilization?=0.75 \ + dalvik.vm.heapminfree?=512k \ + dalvik.vm.heapmaxfree?=8m diff --git a/build/phone-xhdpi-4096-dalvik-heap.mk b/build/phone-xhdpi-4096-dalvik-heap.mk index 2b848413fb..a6ff5a88c8 100644 --- a/build/phone-xhdpi-4096-dalvik-heap.mk +++ b/build/phone-xhdpi-4096-dalvik-heap.mk @@ -16,10 +16,10 @@ # Provides overrides to configure the Dalvik heap for a 4GB phone -PRODUCT_PROPERTY_OVERRIDES += \ - dalvik.vm.heapstartsize=8m \ - dalvik.vm.heapgrowthlimit=192m \ - dalvik.vm.heapsize=512m \ - dalvik.vm.heaptargetutilization=0.6 \ - dalvik.vm.heapminfree=8m \ - dalvik.vm.heapmaxfree=16m +PRODUCT_VENDOR_PROPERTIES += \ + dalvik.vm.heapstartsize?=8m \ + dalvik.vm.heapgrowthlimit?=192m \ + dalvik.vm.heapsize?=512m \ + dalvik.vm.heaptargetutilization?=0.6 \ + dalvik.vm.heapminfree?=8m \ + dalvik.vm.heapmaxfree?=16m diff --git a/build/phone-xhdpi-6144-dalvik-heap.mk b/build/phone-xhdpi-6144-dalvik-heap.mk index 2bacc4a9ab..f08830b2cf 100644 --- a/build/phone-xhdpi-6144-dalvik-heap.mk +++ b/build/phone-xhdpi-6144-dalvik-heap.mk @@ -16,10 +16,10 @@ # Provides overrides to configure the Dalvik heap for a 6GB phone -PRODUCT_PROPERTY_OVERRIDES += \ - dalvik.vm.heapstartsize=16m \ - dalvik.vm.heapgrowthlimit=256m \ - dalvik.vm.heapsize=512m \ - dalvik.vm.heaptargetutilization=0.5 \ - dalvik.vm.heapminfree=8m \ - dalvik.vm.heapmaxfree=32m +PRODUCT_VENDOR_PROPERTIES += \ + dalvik.vm.heapstartsize?=16m \ + dalvik.vm.heapgrowthlimit?=256m \ + dalvik.vm.heapsize?=512m \ + dalvik.vm.heaptargetutilization?=0.5 \ + dalvik.vm.heapminfree?=8m \ + dalvik.vm.heapmaxfree?=32m diff --git a/build/tablet-10in-xhdpi-2048-dalvik-heap.mk b/build/tablet-10in-xhdpi-2048-dalvik-heap.mk index 1721fcc2ca..48c6ea651e 100644 --- a/build/tablet-10in-xhdpi-2048-dalvik-heap.mk +++ b/build/tablet-10in-xhdpi-2048-dalvik-heap.mk @@ -16,10 +16,10 @@ # Provides overrides to configure the Dalvik heap for a standard tablet device. -PRODUCT_PROPERTY_OVERRIDES += \ - dalvik.vm.heapstartsize=16m \ - dalvik.vm.heapgrowthlimit=192m \ - dalvik.vm.heapsize=512m \ - dalvik.vm.heaptargetutilization=0.75 \ - dalvik.vm.heapminfree=512k \ - dalvik.vm.heapmaxfree=8m +PRODUCT_VENDOR_PROPERTIES += \ + dalvik.vm.heapstartsize?=16m \ + dalvik.vm.heapgrowthlimit?=192m \ + dalvik.vm.heapsize?=512m \ + dalvik.vm.heaptargetutilization?=0.75 \ + dalvik.vm.heapminfree?=512k \ + dalvik.vm.heapmaxfree?=8m diff --git a/build/tablet-7in-hdpi-1024-dalvik-heap.mk b/build/tablet-7in-hdpi-1024-dalvik-heap.mk index 7fd34b5f15..d0027dc24a 100644 --- a/build/tablet-7in-hdpi-1024-dalvik-heap.mk +++ b/build/tablet-7in-hdpi-1024-dalvik-heap.mk @@ -16,10 +16,10 @@ # Provides overrides to configure the Dalvik heap for a standard tablet device. -PRODUCT_PROPERTY_OVERRIDES += \ - dalvik.vm.heapstartsize=8m \ - dalvik.vm.heapgrowthlimit=80m \ - dalvik.vm.heapsize=384m \ - dalvik.vm.heaptargetutilization=0.75 \ - dalvik.vm.heapminfree=512k \ - dalvik.vm.heapmaxfree=8m +PRODUCT_VENDOR_PROPERTIES += \ + dalvik.vm.heapstartsize?=8m \ + dalvik.vm.heapgrowthlimit?=80m \ + dalvik.vm.heapsize?=384m \ + dalvik.vm.heaptargetutilization?=0.75 \ + dalvik.vm.heapminfree?=512k \ + dalvik.vm.heapmaxfree?=8m diff --git a/build/tablet-7in-xhdpi-2048-dalvik-heap.mk b/build/tablet-7in-xhdpi-2048-dalvik-heap.mk index e0f20c145b..7c06b4b5ab 100644 --- a/build/tablet-7in-xhdpi-2048-dalvik-heap.mk +++ b/build/tablet-7in-xhdpi-2048-dalvik-heap.mk @@ -16,10 +16,10 @@ # Provides overrides to configure the Dalvik heap for a 320dpi 7" tablet device. -PRODUCT_PROPERTY_OVERRIDES += \ - dalvik.vm.heapstartsize=16m \ - dalvik.vm.heapgrowthlimit=192m \ - dalvik.vm.heapsize=512m \ - dalvik.vm.heaptargetutilization=0.75 \ - dalvik.vm.heapminfree=512k \ - dalvik.vm.heapmaxfree=8m +PRODUCT_VENDOR_PROPERTIES += \ + dalvik.vm.heapstartsize?=16m \ + dalvik.vm.heapgrowthlimit?=192m \ + dalvik.vm.heapsize?=512m \ + dalvik.vm.heaptargetutilization?=0.75 \ + dalvik.vm.heapminfree?=512k \ + dalvik.vm.heapmaxfree?=8m diff --git a/build/tablet-dalvik-heap.mk b/build/tablet-dalvik-heap.mk index f577fb86f5..16886651f1 100644 --- a/build/tablet-dalvik-heap.mk +++ b/build/tablet-dalvik-heap.mk @@ -16,10 +16,10 @@ # Provides overrides to configure the Dalvik heap for a standard tablet device. -PRODUCT_PROPERTY_OVERRIDES += \ - dalvik.vm.heapstartsize=5m \ - dalvik.vm.heapgrowthlimit=48m \ - dalvik.vm.heapsize=256m \ - dalvik.vm.heaptargetutilization=0.75 \ - dalvik.vm.heapminfree=512k \ - dalvik.vm.heapmaxfree=2m +PRODUCT_VENDOR_PROPERTIES += \ + dalvik.vm.heapstartsize?=5m \ + dalvik.vm.heapgrowthlimit?=48m \ + dalvik.vm.heapsize?=256m \ + dalvik.vm.heaptargetutilization?=0.75 \ + dalvik.vm.heapminfree?=512k \ + dalvik.vm.heapmaxfree?=2m diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp index 28fdaa4306..08f44c82c6 100644 --- a/cmds/atrace/atrace.cpp +++ b/cmds/atrace/atrace.cpp @@ -172,6 +172,8 @@ static const TracingCategory k_categories[] = { { OPT, "events/clk/clk_enable/enable" }, { OPT, "events/power/cpu_frequency_limits/enable" }, { OPT, "events/power/suspend_resume/enable" }, + { OPT, "events/cpuhp/cpuhp_enter/enable" }, + { OPT, "events/cpuhp/cpuhp_exit/enable" }, } }, { "membus", "Memory Bus Utilization", 0, { { REQ, "events/memory_bus/enable" }, @@ -239,6 +241,10 @@ static const TracingCategory k_categories[] = { { OPT, "events/kmem/ion_heap_shrink/enable" }, { OPT, "events/ion/ion_stat/enable" }, } }, + { "thermal", "Thermal event", 0, { + { REQ, "events/thermal/thermal_temperature/enable" }, + { OPT, "events/thermal/cdev_update/enable" }, + } }, }; struct TracingVendorCategory { diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc index f442dae66f..994375b30e 100644 --- a/cmds/atrace/atrace.rc +++ b/cmds/atrace/atrace.rc @@ -47,6 +47,10 @@ on late-init chmod 0666 /sys/kernel/tracing/events/power/clock_set_rate/enable chmod 0666 /sys/kernel/debug/tracing/events/power/cpu_frequency_limits/enable chmod 0666 /sys/kernel/tracing/events/power/cpu_frequency_limits/enable + chmod 0666 /sys/kernel/debug/tracing/events/cpuhp/cpuhp_enter/enable + chmod 0666 /sys/kernel/tracing/events/cpuhp/cpuhp_enter/enable + chmod 0666 /sys/kernel/debug/tracing/events/cpuhp/cpuhp_exit/enable + chmod 0666 /sys/kernel/tracing/events/cpuhp/cpuhp_exit/enable chmod 0666 /sys/kernel/debug/tracing/events/power/gpu_frequency/enable chmod 0666 /sys/kernel/tracing/events/power/gpu_frequency/enable chmod 0666 /sys/kernel/debug/tracing/events/power/suspend_resume/enable @@ -166,6 +170,12 @@ on late-init chmod 0666 /sys/kernel/tracing/events/filemap/mm_filemap_delete_from_page_cache/enable chmod 0666 /sys/kernel/debug/tracing/events/filemap/mm_filemap_delete_from_page_cache/enable + # thermal + chmod 0666 /sys/kernel/debug/tracing/events/thermal/thermal_temperature/enable + chmod 0666 /sys/kernel/tracing/events/thermal/thermal_temperature/enable + chmod 0666 /sys/kernel/debug/tracing/events/thermal/cdev_update/enable + chmod 0666 /sys/kernel/tracing/events/thermal/cdev_update/enable + # Tracing disabled by default write /sys/kernel/debug/tracing/tracing_on 0 write /sys/kernel/tracing/tracing_on 0 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/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp index 581d3ded89..afb85fc896 100644 --- a/cmds/dumpstate/dumpstate.cpp +++ b/cmds/dumpstate/dumpstate.cpp @@ -1481,8 +1481,7 @@ static Dumpstate::RunStatus dumpstate() { RunCommand("LSMOD", {"lsmod"}); } - if (__android_logger_property_get_bool( - "ro.logd.kernel", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_ENG | BOOL_DEFAULT_FLAG_SVELTE)) { + if (android::base::GetBoolProperty("ro.logd.kernel", false)) { DoKernelLogcat(); } else { do_dmesg(); 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/OWNERS b/cmds/installd/OWNERS index 9a21104131..fc745d0cf7 100644 --- a/cmds/installd/OWNERS +++ b/cmds/installd/OWNERS @@ -1,6 +1,5 @@ set noparent -agampe@google.com calin@google.com jsharkey@android.com maco@google.com 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/otapreopt.cpp b/cmds/installd/otapreopt.cpp index 18f8268bf3..9c757815ae 100644 --- a/cmds/installd/otapreopt.cpp +++ b/cmds/installd/otapreopt.cpp @@ -96,7 +96,7 @@ static constexpr bool IsPowerOfTwo(T x) { template<typename T> static constexpr T RoundDown(T x, typename std::decay<T>::type n) { - return DCHECK_CONSTEXPR(IsPowerOfTwo(n), , T(0))(x & -n); + return (x & -n); } template<typename T> @@ -523,6 +523,7 @@ private: // Choose a random relocation offset. Taken from art/runtime/gc/image_space.cc. static int32_t ChooseRelocationOffsetDelta(int32_t min_delta, int32_t max_delta) { constexpr size_t kPageSize = PAGE_SIZE; + static_assert(IsPowerOfTwo(kPageSize), "page size must be power of two"); CHECK_EQ(min_delta % kPageSize, 0u); CHECK_EQ(max_delta % kPageSize, 0u); CHECK_LT(min_delta, max_delta); 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/cmds/lshal/Android.bp b/cmds/lshal/Android.bp index 5afae4b7d3..987adafc8e 100644 --- a/cmds/lshal/Android.bp +++ b/cmds/lshal/Android.bp @@ -75,7 +75,7 @@ cc_test { defaults: ["lshal_defaults"], gtest: true, static_libs: [ - "android.hardware.tests.baz@1.0", + "android.hardware.tests.inheritance@1.0", "libgmock", ], shared_libs: [ diff --git a/cmds/lshal/DebugCommand.cpp b/cmds/lshal/DebugCommand.cpp index af22ac9b3d..72958bd2a9 100644 --- a/cmds/lshal/DebugCommand.cpp +++ b/cmds/lshal/DebugCommand.cpp @@ -39,7 +39,7 @@ Status DebugCommand::parseArgs(const Arg &arg) { // Optargs cannnot be used because the flag should not be considered set // if it should really be contained in mOptions. if (std::string(arg.argv[optind]) == "-E") { - mExcludesParentInstances = true; + mParentDebugInfoLevel = ParentDebugInfoLevel::NOTHING; optind++; } @@ -67,7 +67,7 @@ Status DebugCommand::main(const Arg &arg) { return mLshal.emitDebugInfo( pair.first, pair.second.empty() ? "default" : pair.second, mOptions, - mExcludesParentInstances, + mParentDebugInfoLevel, mLshal.out().buf(), mLshal.err()); } diff --git a/cmds/lshal/DebugCommand.h b/cmds/lshal/DebugCommand.h index cd57e31bfc..317cc2821c 100644 --- a/cmds/lshal/DebugCommand.h +++ b/cmds/lshal/DebugCommand.h @@ -21,6 +21,7 @@ #include <android-base/macros.h> #include "Command.h" +#include "ParentDebugInfoLevel.h" #include "utils.h" namespace android { @@ -42,9 +43,8 @@ private: std::string mInterfaceName; std::vector<std::string> mOptions; - // Outputs the actual descriptor of a hal instead of the debug output - // if the arguments provided are a superclass of the actual hal impl. - bool mExcludesParentInstances; + // See comment on ParentDebugInfoLevel. + ParentDebugInfoLevel mParentDebugInfoLevel = ParentDebugInfoLevel::FULL; DISALLOW_COPY_AND_ASSIGN(DebugCommand); }; diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp index fb11cee33e..a805a4844a 100644 --- a/cmds/lshal/ListCommand.cpp +++ b/cmds/lshal/ListCommand.cpp @@ -555,7 +555,7 @@ void ListCommand::dumpTable(const NullableOStream<std::ostream>& out) const { std::stringstream ss; auto pair = splitFirst(iName, '/'); mLshal.emitDebugInfo(pair.first, pair.second, {}, - false /* excludesParentInstances */, ss, + ParentDebugInfoLevel::FQNAME_ONLY, ss, NullableOStream<std::ostream>(nullptr)); return ss.str(); }; diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp index 132b31ebc3..2c3efe524e 100644 --- a/cmds/lshal/Lshal.cpp +++ b/cmds/lshal/Lshal.cpp @@ -101,7 +101,7 @@ Status Lshal::emitDebugInfo( const std::string &interfaceName, const std::string &instanceName, const std::vector<std::string> &options, - bool excludesParentInstances, + ParentDebugInfoLevel parentDebugInfoLevel, std::ostream &out, NullableOStream<std::ostream> err) const { using android::hidl::base::V1_0::IBase; @@ -126,7 +126,7 @@ Status Lshal::emitDebugInfo( return NO_INTERFACE; } - if (excludesParentInstances) { + if (parentDebugInfoLevel != ParentDebugInfoLevel::FULL) { const std::string descriptor = getDescriptor(base.get()); if (descriptor.empty()) { std::string msg = interfaceName + "/" + instanceName + " getDescriptor failed"; @@ -134,6 +134,9 @@ Status Lshal::emitDebugInfo( LOG(ERROR) << msg; } if (descriptor != interfaceName) { + if (parentDebugInfoLevel == ParentDebugInfoLevel::FQNAME_ONLY) { + out << "[See " << descriptor << "/" << instanceName << "]"; + } return OK; } } diff --git a/cmds/lshal/Lshal.h b/cmds/lshal/Lshal.h index 830bd872ff..50279d4d7a 100644 --- a/cmds/lshal/Lshal.h +++ b/cmds/lshal/Lshal.h @@ -25,6 +25,7 @@ #include "Command.h" #include "NullableOStream.h" +#include "ParentDebugInfoLevel.h" #include "utils.h" namespace android { @@ -49,7 +50,7 @@ public: const std::string &interfaceName, const std::string &instanceName, const std::vector<std::string> &options, - bool excludesParentInstances, + ParentDebugInfoLevel parentDebugInfoLevel, std::ostream &out, NullableOStream<std::ostream> err) const; diff --git a/cmds/lshal/ParentDebugInfoLevel.h b/cmds/lshal/ParentDebugInfoLevel.h new file mode 100644 index 0000000000..12ac9c8648 --- /dev/null +++ b/cmds/lshal/ParentDebugInfoLevel.h @@ -0,0 +1,34 @@ +/* + * 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. + */ +#pragma once + +namespace android { +namespace lshal { + +// Describe verbosity when dumping debug information on a HAL service by +// referring to a parent HAL interface FQName (for example, when dumping debug information +// on foo@1.0::IFoo but the HAL implementation is foo@1.1::IFoo). +enum class ParentDebugInfoLevel { + // Write nothing. + NOTHING, + // Write a short description that includes the FQName of the real implementation. + FQNAME_ONLY, + // Write full debug info. + FULL, +}; + +} // namespace lshal +} // namespace android diff --git a/cmds/lshal/test.cpp b/cmds/lshal/test.cpp index 3d550babf4..afe5d63575 100644 --- a/cmds/lshal/test.cpp +++ b/cmds/lshal/test.cpp @@ -24,7 +24,7 @@ #include <gtest/gtest.h> #include <gmock/gmock.h> -#include <android/hardware/tests/baz/1.0/IQuux.h> +#include <android/hardware/tests/inheritance/1.0/IChild.h> #include <hidl/HidlTransportSupport.h> #include <vintf/parse_xml.h> @@ -44,6 +44,7 @@ using ::android::hardware::hidl_death_recipient; using ::android::hardware::hidl_handle; using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; +using ::android::hardware::Void; using android::vintf::Arch; using android::vintf::CompatibilityMatrix; using android::vintf::gCompatibilityMatrixConverter; @@ -59,10 +60,14 @@ using hidl_hash = hidl_array<uint8_t, 32>; namespace android { namespace hardware { namespace tests { -namespace baz { +namespace inheritance { namespace V1_0 { namespace implementation { -struct Quux : android::hardware::tests::baz::V1_0::IQuux { +struct Child : android::hardware::tests::inheritance::V1_0::IChild { + ::android::hardware::Return<void> doChild() override { return Void(); } + ::android::hardware::Return<void> doParent() override { return Void(); } + ::android::hardware::Return<void> doGrandparent() override { return Void(); } + ::android::hardware::Return<void> debug(const hidl_handle& hh, const hidl_vec<hidl_string>& options) override { const native_handle_t *handle = hh.getNativeHandle(); if (handle->numFds < 1) { @@ -76,7 +81,7 @@ struct Quux : android::hardware::tests::baz::V1_0::IQuux { } ssize_t written = write(fd, content.c_str(), content.size()); if (written != (ssize_t)content.size()) { - LOG(WARNING) << "SERVER(Quux) debug writes " << written << " bytes < " + LOG(WARNING) << "SERVER(Child) debug writes " << written << " bytes < " << content.size() << " bytes, errno = " << errno; } return Void(); @@ -85,7 +90,7 @@ struct Quux : android::hardware::tests::baz::V1_0::IQuux { } // namespace implementation } // namespace V1_0 -} // namespace baz +} // namespace inheritance } // namespace tests } // namespace hardware @@ -124,18 +129,24 @@ public: class DebugTest : public ::testing::Test { public: void SetUp() override { - using ::android::hardware::tests::baz::V1_0::IQuux; - using ::android::hardware::tests::baz::V1_0::implementation::Quux; + using ::android::hardware::tests::inheritance::V1_0::IChild; + using ::android::hardware::tests::inheritance::V1_0::IParent; + using ::android::hardware::tests::inheritance::V1_0::IGrandparent; + using ::android::hardware::tests::inheritance::V1_0::implementation::Child; err.str(""); out.str(""); serviceManager = new testing::NiceMock<MockServiceManager>(); - ON_CALL(*serviceManager, get(_, _)).WillByDefault(Invoke( - [](const auto &iface, const auto &inst) -> ::android::hardware::Return<sp<IBase>> { - if (iface == IQuux::descriptor && inst == "default") - return new Quux(); - return nullptr; - })); + ON_CALL(*serviceManager, get(_, _)) + .WillByDefault( + Invoke([](const auto& iface, + const auto& inst) -> ::android::hardware::Return<sp<IBase>> { + if (inst != "default") return nullptr; + if (iface == IChild::descriptor || iface == IParent::descriptor || + iface == IGrandparent::descriptor) + return new Child(); + return nullptr; + })); lshal = std::make_unique<Lshal>(out, err, serviceManager, serviceManager); } @@ -159,17 +170,17 @@ static Status callMain(const std::unique_ptr<T>& lshal, const std::vector<const TEST_F(DebugTest, Debug) { EXPECT_EQ(0u, callMain(lshal, { - "lshal", "debug", "android.hardware.tests.baz@1.0::IQuux/default", "foo", "bar" + "lshal", "debug", "android.hardware.tests.inheritance@1.0::IChild/default", "foo", "bar" })); - EXPECT_THAT(out.str(), StrEq("android.hardware.tests.baz@1.0::IQuux\nfoo\nbar")); + EXPECT_THAT(out.str(), StrEq("android.hardware.tests.inheritance@1.0::IChild\nfoo\nbar")); EXPECT_THAT(err.str(), IsEmpty()); } TEST_F(DebugTest, Debug2) { EXPECT_EQ(0u, callMain(lshal, { - "lshal", "debug", "android.hardware.tests.baz@1.0::IQuux", "baz", "quux" + "lshal", "debug", "android.hardware.tests.inheritance@1.0::IChild", "baz", "quux" })); - EXPECT_THAT(out.str(), StrEq("android.hardware.tests.baz@1.0::IQuux\nbaz\nquux")); + EXPECT_THAT(out.str(), StrEq("android.hardware.tests.inheritance@1.0::IChild\nbaz\nquux")); EXPECT_THAT(err.str(), IsEmpty()); } @@ -180,6 +191,22 @@ TEST_F(DebugTest, Debug3) { EXPECT_THAT(err.str(), HasSubstr("does not exist")); } +TEST_F(DebugTest, DebugParent) { + EXPECT_EQ(0u, callMain(lshal, { + "lshal", "debug", "android.hardware.tests.inheritance@1.0::IParent", "calling parent" + })); + EXPECT_THAT(out.str(), StrEq("android.hardware.tests.inheritance@1.0::IChild\ncalling parent")); + EXPECT_THAT(err.str(), IsEmpty()); +} + +TEST_F(DebugTest, DebugParentExclude) { + EXPECT_EQ(0u, callMain(lshal, { + "lshal", "debug", "-E", "android.hardware.tests.inheritance@1.0::IParent", "excluding" + })); + EXPECT_THAT(out.str(), IsEmpty()); + EXPECT_THAT(err.str(), IsEmpty()); +} + class MockLshal : public Lshal { public: MockLshal() {} @@ -766,6 +793,91 @@ TEST_F(ListTest, Vintf) { EXPECT_EQ("", err.str()); } +// Fake service returned by mocked IServiceManager::get for DumpDebug. +// The interfaceChain and getHashChain functions returns +// foo(id - 1) -> foo(id - 2) -> ... foo1 -> IBase. +class InheritingService : public IBase { +public: + explicit InheritingService(pid_t id) : mId(id) {} + android::hardware::Return<void> interfaceDescriptor(interfaceDescriptor_cb cb) override { + cb(getInterfaceName(mId)); + return hardware::Void(); + } + android::hardware::Return<void> interfaceChain(interfaceChain_cb cb) override { + std::vector<hidl_string> ret; + for (auto i = mId; i > 0; --i) { + ret.push_back(getInterfaceName(i)); + } + ret.push_back(IBase::descriptor); + cb(ret); + return hardware::Void(); + } + android::hardware::Return<void> getHashChain(getHashChain_cb cb) override { + std::vector<hidl_hash> ret; + for (auto i = mId; i > 0; --i) { + ret.push_back(getHashFromId(i)); + } + ret.push_back(getHashFromId(0xff)); + cb(ret); + return hardware::Void(); + } + android::hardware::Return<void> debug(const hidl_handle& hh, + const hidl_vec<hidl_string>&) override { + const native_handle_t* handle = hh.getNativeHandle(); + if (handle->numFds < 1) { + return Void(); + } + int fd = handle->data[0]; + std::string content = "debug info for "; + content += getInterfaceName(mId); + ssize_t written = write(fd, content.c_str(), content.size()); + if (written != (ssize_t)content.size()) { + LOG(WARNING) << "SERVER(" << descriptor << ") debug writes " << written << " bytes < " + << content.size() << " bytes, errno = " << errno; + } + return Void(); + } + +private: + pid_t mId; +}; + +TEST_F(ListTest, DumpDebug) { + size_t inheritanceLevel = 3; + sp<IBase> service = new InheritingService(inheritanceLevel); + + EXPECT_CALL(*serviceManager, list(_)).WillRepeatedly(Invoke([&](IServiceManager::list_cb cb) { + std::vector<hidl_string> ret; + for (auto i = 1; i <= inheritanceLevel; ++i) { + ret.push_back(getInterfaceName(i) + "/default"); + } + cb(ret); + return hardware::Void(); + })); + EXPECT_CALL(*serviceManager, get(_, _)) + .WillRepeatedly( + Invoke([&](const hidl_string&, const hidl_string& instance) -> sp<IBase> { + int id = getIdFromInstanceName(instance); + if (id > inheritanceLevel) return nullptr; + return sp<IBase>(service); + })); + + const std::string expected = "[fake description 0]\n" + "Interface\n" + "a.h.foo1@1.0::IFoo/default\n" + "[See a.h.foo3@3.0::IFoo/default]\n" + "a.h.foo2@2.0::IFoo/default\n" + "[See a.h.foo3@3.0::IFoo/default]\n" + "a.h.foo3@3.0::IFoo/default\n" + "debug info for a.h.foo3@3.0::IFoo\n" + "\n"; + + optind = 1; // mimic Lshal::parseArg() + EXPECT_EQ(0u, mockList->main(createArg({"lshal", "--types=b", "-id"}))); + EXPECT_EQ(expected, out.str()); + EXPECT_EQ("", err.str()); +} + class ListVintfTest : public ListTest { public: virtual void SetUp() override { diff --git a/cmds/servicemanager/servicemanager.rc b/cmds/servicemanager/servicemanager.rc index 152ac28ba4..6d5070fa04 100644 --- a/cmds/servicemanager/servicemanager.rc +++ b/cmds/servicemanager/servicemanager.rc @@ -3,16 +3,11 @@ service servicemanager /system/bin/servicemanager user system group system readproc critical - onrestart restart healthd - onrestart restart zygote + onrestart restart apexd onrestart restart audioserver - onrestart restart media - onrestart restart surfaceflinger - onrestart restart inputflinger - onrestart restart drm - onrestart restart cameraserver - onrestart restart keystore onrestart restart gatekeeperd - onrestart restart thermalservice + onrestart class_restart main + onrestart class_restart hal + onrestart class_restart early_hal writepid /dev/cpuset/system-background/tasks shutdown critical diff --git a/cmds/servicemanager/vndservicemanager.rc b/cmds/servicemanager/vndservicemanager.rc index 3fa4d7debd..756f6c3bc8 100644 --- a/cmds/servicemanager/vndservicemanager.rc +++ b/cmds/servicemanager/vndservicemanager.rc @@ -3,4 +3,7 @@ service vndservicemanager /vendor/bin/vndservicemanager /dev/vndbinder user system group system readproc writepid /dev/cpuset/system-background/tasks + onrestart class_restart main + onrestart class_restart hal + onrestart class_restart early_hal shutdown critical 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/headers/media_plugin/media/openmax/OMX_VideoExt.h b/headers/media_plugin/media/openmax/OMX_VideoExt.h index dc37bbd1f7..e65b224a20 100644 --- a/headers/media_plugin/media/openmax/OMX_VideoExt.h +++ b/headers/media_plugin/media/openmax/OMX_VideoExt.h @@ -321,6 +321,46 @@ typedef enum OMX_VIDEO_DOLBYVISIONLEVELTYPE { OMX_VIDEO_DolbyVisionLevelmax = 0x7FFFFFFF } OMX_VIDEO_DOLBYVISIONLEVELTYPE; +/** AV1 Profile enum type */ +typedef enum OMX_VIDEO_AV1PROFILETYPE { + OMX_VIDEO_AV1ProfileMain8 = 0x00000001, + OMX_VIDEO_AV1ProfileMain10 = 0x00000002, + OMX_VIDEO_AV1ProfileMain10HDR10 = 0x00001000, + OMX_VIDEO_AV1ProfileMain10HDR10Plus = 0x00002000, + OMX_VIDEO_AV1ProfileUnknown = 0x6EFFFFFF, + OMX_VIDEO_AV1ProfileMax = 0x7FFFFFFF +} OMX_VIDEO_AV1PROFILETYPE; + +/** AV1 Level enum type */ +typedef enum OMX_VIDEO_AV1LEVELTYPE { + OMX_VIDEO_AV1Level2 = 0x1, + OMX_VIDEO_AV1Level21 = 0x2, + OMX_VIDEO_AV1Level22 = 0x4, + OMX_VIDEO_AV1Level23 = 0x8, + OMX_VIDEO_AV1Level3 = 0x10, + OMX_VIDEO_AV1Level31 = 0x20, + OMX_VIDEO_AV1Level32 = 0x40, + OMX_VIDEO_AV1Level33 = 0x80, + OMX_VIDEO_AV1Level4 = 0x100, + OMX_VIDEO_AV1Level41 = 0x200, + OMX_VIDEO_AV1Level42 = 0x400, + OMX_VIDEO_AV1Level43 = 0x800, + OMX_VIDEO_AV1Level5 = 0x1000, + OMX_VIDEO_AV1Level51 = 0x2000, + OMX_VIDEO_AV1Level52 = 0x4000, + OMX_VIDEO_AV1Level53 = 0x8000, + OMX_VIDEO_AV1Level6 = 0x10000, + OMX_VIDEO_AV1Level61 = 0x20000, + OMX_VIDEO_AV1Level62 = 0x40000, + OMX_VIDEO_AV1Level63 = 0x80000, + OMX_VIDEO_AV1Level7 = 0x100000, + OMX_VIDEO_AV1Level71 = 0x200000, + OMX_VIDEO_AV1Level72 = 0x400000, + OMX_VIDEO_AV1Level73 = 0x800000, + OMX_VIDEO_AV1LevelUnknown = 0x6EFFFFFF, + OMX_VIDEO_AV1LevelMax = 0x7FFFFFFF +} OMX_VIDEO_AV1LEVELTYPE; + /** * Structure for configuring video compression intra refresh period * 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..e9f559cd8e 100644 --- a/include/android/choreographer.h +++ b/include/android/choreographer.h @@ -129,9 +129,19 @@ 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. + * + * Note that in API level 30, this api is not guaranteed to be atomic with + * DisplayManager. That is, calling Display#getRefreshRate very soon after + * a refresh rate callback is invoked may return a stale refresh rate. If any + * Display properties would be required by this callback, then it is recommended + * to listen directly to DisplayManager.DisplayListener#onDisplayChanged events + * instead. + * + * 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 +154,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/hardware_buffer_jni.h b/include/android/hardware_buffer_jni.h index 293e5ac469..ae208a6e75 100644 --- a/include/android/hardware_buffer_jni.h +++ b/include/android/hardware_buffer_jni.h @@ -39,9 +39,9 @@ __BEGIN_DECLS * Return the AHardwareBuffer wrapped by a Java HardwareBuffer object. * * This method does not acquire any additional reference to the AHardwareBuffer - * that is returned. To keep the AHardwareBuffer live after the Java - * HardwareBuffer object got garbage collected, be sure to use AHardwareBuffer_acquire() - * to acquire an additional reference. + * that is returned. To keep the AHardwareBuffer alive after the Java + * HardwareBuffer object is closed, explicitly or by the garbage collector, be + * sure to use AHardwareBuffer_acquire() to acquire an additional reference. * * Available since API level 26. */ @@ -50,7 +50,18 @@ AHardwareBuffer* AHardwareBuffer_fromHardwareBuffer(JNIEnv* env, /** * Return a new Java HardwareBuffer object that wraps the passed native - * AHardwareBuffer object. + * AHardwareBuffer object. The Java HardwareBuffer will acquire a reference to + * the internal buffer and manage its lifetime. For example: + * + * <pre><code> + * AHardwareBuffer* buffer; + * AHardwareBuffer_allocate(..., &buffer); // `buffer` has reference count 1 + * jobject java_result = AHardwareBuffer_toHardwareBuffer(buffer); // `buffer` has reference count 2. + * AHardwareBuffer_release(buffer); // `buffer` has reference count 1 + * return result; // The underlying buffer is kept alive by `java_result` and + * // will be set to 0 when it is closed on the Java side with + * // HardwareBuffer::close(). + * </code></pre> * * Available since API level 26. */ 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/binder/Android.bp b/libs/binder/Android.bp index b24a577588..861b5893e7 100644 --- a/libs/binder/Android.bp +++ b/libs/binder/Android.bp @@ -127,6 +127,10 @@ cc_library { export_aidl_headers: true, }, + // TODO(b/142684679): for com.android.media which is compiled + // as vendor and used as system code. + use_apex_name_macro: true, + cflags: [ "-Wall", "-Wextra", 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/Binder.cpp b/libs/binder/Binder.cpp index e0fb54384e..6ca3b16324 100644 --- a/libs/binder/Binder.cpp +++ b/libs/binder/Binder.cpp @@ -24,6 +24,7 @@ #include <binder/IShellCallback.h> #include <binder/Parcel.h> +#include <linux/sched.h> #include <stdio.h> namespace android { @@ -133,6 +134,8 @@ public: // unlocked objects bool mRequestingSid = false; sp<IBinder> mExtension; + int mPolicy = SCHED_NORMAL; + int mPriority = 0; // for below objects Mutex mLock; @@ -279,6 +282,47 @@ sp<IBinder> BBinder::getExtension() { return e->mExtension; } +void BBinder::setMinSchedulerPolicy(int policy, int priority) { + switch (policy) { + case SCHED_NORMAL: + LOG_ALWAYS_FATAL_IF(priority < -20 || priority > 19, "Invalid priority for SCHED_NORMAL: %d", priority); + break; + case SCHED_RR: + case SCHED_FIFO: + LOG_ALWAYS_FATAL_IF(priority < 1 || priority > 99, "Invalid priority for sched %d: %d", policy, priority); + break; + default: + LOG_ALWAYS_FATAL("Unrecognized scheduling policy: %d", policy); + } + + Extras* e = mExtras.load(std::memory_order_acquire); + + if (e == nullptr) { + // Avoid allocations if called with default. + if (policy == SCHED_NORMAL && priority == 0) { + return; + } + + e = getOrCreateExtras(); + if (!e) return; // out of memory + } + + e->mPolicy = policy; + e->mPriority = priority; +} + +int BBinder::getMinSchedulerPolicy() { + Extras* e = mExtras.load(std::memory_order_acquire); + if (e == nullptr) return SCHED_NORMAL; + return e->mPolicy; +} + +int BBinder::getMinSchedulerPriority() { + Extras* e = mExtras.load(std::memory_order_acquire); + if (e == nullptr) return 0; + return e->mPriority; +} + pid_t BBinder::getDebugPid() { return getpid(); } diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp index d2b9b8f018..c183d29773 100644 --- a/libs/binder/BpBinder.cpp +++ b/libs/binder/BpBinder.cpp @@ -224,7 +224,7 @@ status_t BpBinder::transact( using android::internal::Stability; auto stability = Stability::get(this); - auto required = privateVendor ? Stability::VENDOR : Stability::kLocalStability; + auto required = privateVendor ? Stability::VENDOR : Stability::getLocalStability(); if (CC_UNLIKELY(!Stability::check(stability, required))) { ALOGE("Cannot do a user transaction on a %s binder in a %s context.", 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/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp index d67ce15ca9..157538e63f 100644 --- a/libs/binder/IPCThreadState.cpp +++ b/libs/binder/IPCThreadState.cpp @@ -614,7 +614,7 @@ void IPCThreadState::joinThreadPool(bool isMain) talkWithDriver(false); } -int IPCThreadState::setupPolling(int* fd) +status_t IPCThreadState::setupPolling(int* fd) { if (mProcess->mDriverFD < 0) { return -EBADF; diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp index a9f2d73951..9aa82d908c 100644 --- a/libs/binder/IServiceManager.cpp +++ b/libs/binder/IServiceManager.cpp @@ -18,6 +18,9 @@ #include <binder/IServiceManager.h> +#include <inttypes.h> +#include <unistd.h> + #include <android/os/BnServiceCallback.h> #include <android/os/IServiceManager.h> #include <binder/IPCThreadState.h> @@ -36,8 +39,6 @@ #include "Static.h" -#include <unistd.h> - namespace android { using AidlServiceManager = android::os::IServiceManager; @@ -206,6 +207,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; @@ -215,7 +220,8 @@ sp<IBinder> ServiceManagerShim::getService(const String16& name) const const bool isVendorService = strcmp(ProcessState::self()->getDriverName().c_str(), "/dev/vndbinder") == 0; - const long timeout = uptimeMillis() + 5000; + const long timeout = 5000; + int64_t startTime = uptimeMillis(); // Vendor code can't access system properties if (!gSystemBootCompleted && !isVendorService) { #ifdef __ANDROID__ @@ -229,15 +235,21 @@ sp<IBinder> ServiceManagerShim::getService(const String16& name) const // retry interval in millisecond; note that vendor services stay at 100ms const long sleepTime = gSystemBootCompleted ? 1000 : 100; + ALOGI("Waiting for service '%s' on '%s'...", String8(name).string(), + ProcessState::self()->getDriverName().c_str()); + int n = 0; - while (uptimeMillis() < timeout) { + while (uptimeMillis() - startTime < timeout) { n++; - ALOGI("Waiting for service '%s' on '%s'...", String8(name).string(), - ProcessState::self()->getDriverName().c_str()); usleep(1000*sleepTime); sp<IBinder> svc = checkService(name); - if (svc != nullptr) return svc; + if (svc != nullptr) { + ALOGI("Waiting for service '%s' on '%s' successful after waiting %" PRIi64 "ms", + String8(name).string(), ProcessState::self()->getDriverName().c_str(), + uptimeMillis() - startTime); + return svc; + } } ALOGW("Service %s didn't start. Returning NULL", String8(name).string()); return nullptr; @@ -322,6 +334,11 @@ sp<IBinder> ServiceManagerShim::waitForService(const String16& name16) while(true) { { + // It would be really nice if we could read binder commands on this + // thread instead of needing a threadpool to be started, but for + // instance, if we call getAndExecuteCommand, it might be the case + // that another thread serves the callback, and we never get a + // command, so we hang indefinitely. std::unique_lock<std::mutex> lock(waiter->mMutex); using std::literals::chrono_literals::operator""s; waiter->mCv.wait_for(lock, 1s, [&] { @@ -330,6 +347,8 @@ sp<IBinder> ServiceManagerShim::waitForService(const String16& name16) if (waiter->mBinder != nullptr) return waiter->mBinder; } + ALOGW("Waited one second for %s (is service started? are binder threads started and available?)", name.c_str()); + // Handle race condition for lazy services. Here is what can happen: // - the service dies (not processed by init yet). // - sm processes death notification. @@ -343,8 +362,6 @@ sp<IBinder> ServiceManagerShim::waitForService(const String16& name16) return nullptr; } if (out != nullptr) return out; - - ALOGW("Waited one second for %s", name.c_str()); } } 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/MemoryDealer.cpp b/libs/binder/MemoryDealer.cpp index ebf91f925e..b46b3e88fc 100644 --- a/libs/binder/MemoryDealer.cpp +++ b/libs/binder/MemoryDealer.cpp @@ -387,7 +387,7 @@ SimpleBestFitAllocator::chunk_t* SimpleBestFitAllocator::dealloc(size_t start) while (cur) { if (cur->start == start) { LOG_FATAL_IF(cur->free, - "block at offset 0x%08lX of size 0x%08lX already freed", + "block at offset 0x%08lX of size 0x%08X already freed", cur->start*kMemoryAlign, cur->size*kMemoryAlign); // merge freed blocks together @@ -411,7 +411,7 @@ SimpleBestFitAllocator::chunk_t* SimpleBestFitAllocator::dealloc(size_t start) } #endif LOG_FATAL_IF(!freed->free, - "freed block at offset 0x%08lX of size 0x%08lX is not free!", + "freed block at offset 0x%08lX of size 0x%08X is not free!", freed->start * kMemoryAlign, freed->size * kMemoryAlign); return freed; diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 9642a87f4e..632458e784 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -20,6 +20,7 @@ #include <errno.h> #include <fcntl.h> #include <inttypes.h> +#include <linux/sched.h> #include <pthread.h> #include <stdint.h> #include <stdio.h> @@ -188,16 +189,18 @@ status_t Parcel::finishUnflattenBinder( return OK; } +static constexpr inline int schedPolicyMask(int policy, int priority) { + return (priority & FLAT_BINDER_FLAG_PRIORITY_MASK) | ((policy & 3) << FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT); +} + status_t Parcel::flattenBinder(const sp<IBinder>& binder) { flat_binder_object obj; + obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS; - if (IPCThreadState::self()->backgroundSchedulingDisabled()) { - /* minimum priority for all nodes is nice 0 */ - obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS; - } else { - /* minimum priority for all nodes is MAX_NICE(19) */ - obj.flags = 0x13 | FLAT_BINDER_FLAG_ACCEPTS_FDS; + int schedBits = 0; + if (!IPCThreadState::self()->backgroundSchedulingDisabled()) { + schedBits = schedPolicyMask(SCHED_NORMAL, 19); } if (binder != nullptr) { @@ -213,6 +216,13 @@ status_t Parcel::flattenBinder(const sp<IBinder>& binder) obj.handle = handle; obj.cookie = 0; } else { + int policy = local->getMinSchedulerPolicy(); + int priority = local->getMinSchedulerPriority(); + + if (policy != 0 || priority != 0) { + // override value, since it is set explicitly + schedBits = schedPolicyMask(policy, priority); + } if (local->isRequestingSid()) { obj.flags |= FLAT_BINDER_FLAG_TXN_SECURITY_CTX; } @@ -226,6 +236,8 @@ status_t Parcel::flattenBinder(const sp<IBinder>& binder) obj.cookie = 0; } + obj.flags |= schedBits; + return finishFlattenBinder(binder, obj); } @@ -751,6 +763,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 +794,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 +810,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 +827,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 +842,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 +857,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 +872,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 +887,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 +902,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 +917,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 +933,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 +1084,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 +1135,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 +1247,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 +1584,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 +1606,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 +1628,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 +1640,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 +1652,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 +1664,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 +1676,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 +1688,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 +1762,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 +1775,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 +1789,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 +1985,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 +2078,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 +2306,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 +2655,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..acc1e67eb8 100644 --- a/libs/binder/ProcessState.cpp +++ b/libs/binder/ProcessState.cpp @@ -32,6 +32,7 @@ #include <errno.h> #include <fcntl.h> +#include <mutex> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -73,38 +74,49 @@ protected: sp<ProcessState> ProcessState::self() { - Mutex::Autolock _l(gProcessMutex); - if (gProcess != nullptr) { - return gProcess; - } - gProcess = new ProcessState(kDefaultDriver); - return gProcess; + return init(kDefaultDriver, false /*requireDefault*/); } sp<ProcessState> ProcessState::initWithDriver(const char* driver) { - Mutex::Autolock _l(gProcessMutex); - if (gProcess != nullptr) { - // Allow for initWithDriver to be called repeatedly with the same - // driver. - if (!strcmp(gProcess->getDriverName().c_str(), driver)) { - return gProcess; - } - LOG_ALWAYS_FATAL("ProcessState was already initialized."); - } - - if (access(driver, R_OK) == -1) { - ALOGE("Binder driver %s is unavailable. Using /dev/binder instead.", driver); - driver = "/dev/binder"; - } - - gProcess = new ProcessState(driver); - return gProcess; + return init(driver, true /*requireDefault*/); } sp<ProcessState> ProcessState::selfOrNull() { - Mutex::Autolock _l(gProcessMutex); + return init(nullptr, false /*requireDefault*/); +} + +sp<ProcessState> ProcessState::init(const char *driver, bool requireDefault) +{ + [[clang::no_destroy]] static sp<ProcessState> gProcess; + [[clang::no_destroy]] static std::mutex gProcessMutex; + + if (driver == nullptr) { + std::lock_guard<std::mutex> l(gProcessMutex); + return gProcess; + } + + [[clang::no_destroy]] static std::once_flag gProcessOnce; + std::call_once(gProcessOnce, [&](){ + if (access(driver, R_OK) == -1) { + ALOGE("Binder driver %s is unavailable. Using /dev/binder instead.", driver); + driver = "/dev/binder"; + } + + std::lock_guard<std::mutex> l(gProcessMutex); + gProcess = new ProcessState(driver); + }); + + if (requireDefault) { + // Detect if we are trying to initialize with a different driver, and + // consider that an error. ProcessState will only be initialized once above. + LOG_ALWAYS_FATAL_IF(gProcess->getDriverName() != driver, + "ProcessState was already initialized with %s," + " can't initialize with %s.", + gProcess->getDriverName().c_str(), driver); + } + return gProcess; } @@ -328,6 +340,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/Stability.cpp b/libs/binder/Stability.cpp index e1565fac43..6115aec81d 100644 --- a/libs/binder/Stability.cpp +++ b/libs/binder/Stability.cpp @@ -22,7 +22,7 @@ namespace android { namespace internal { void Stability::markCompilationUnit(IBinder* binder) { - status_t result = set(binder, kLocalStability, true /*log*/); + status_t result = set(binder, getLocalStability(), true /*log*/); LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object."); } @@ -45,7 +45,26 @@ bool Stability::requiresVintfDeclaration(const sp<IBinder>& binder) { } void Stability::tryMarkCompilationUnit(IBinder* binder) { - (void) set(binder, kLocalStability, false /*log*/); + (void) set(binder, getLocalStability(), false /*log*/); +} + +Stability::Level Stability::getLocalStability() { +#ifdef __ANDROID_VNDK__ + #ifdef __ANDROID_APEX__ + // TODO(b/142684679) avoid use_vendor on system APEXes + #if !defined(__ANDROID_APEX_COM_ANDROID_MEDIA_SWCODEC__) \ + && !defined(__ANDROID_APEX_TEST_COM_ANDROID_MEDIA_SWCODEC__) + #error VNDK + APEX only defined for com.android.media.swcodec + #endif + // TODO(b/142684679) avoid use_vendor on system APEXes + return Level::SYSTEM; + #else + return Level::VENDOR; + #endif +#else + // TODO(b/139325195): split up stability levels for system/APEX. + return Level::SYSTEM; +#endif } status_t Stability::set(IBinder* binder, int32_t stability, bool log) { diff --git a/libs/binder/Static.cpp b/libs/binder/Static.cpp index 779ed412ba..db0f1c7c3f 100644 --- a/libs/binder/Static.cpp +++ b/libs/binder/Static.cpp @@ -68,9 +68,4 @@ TextOutput& alog(*new LogTextOutput()); TextOutput& aout(*new FdTextOutput(STDOUT_FILENO)); TextOutput& aerr(*new FdTextOutput(STDERR_FILENO)); -// ------------ ProcessState.cpp - -Mutex& gProcessMutex = *new Mutex; -sp<ProcessState> gProcess; - } // namespace android diff --git a/libs/binder/Static.h b/libs/binder/Static.h index f8e0ee5f8d..83524e8575 100644 --- a/libs/binder/Static.h +++ b/libs/binder/Static.h @@ -27,8 +27,4 @@ namespace android { // For TextStream.cpp extern Vector<int32_t> gTextBuffers; -// For ProcessState.cpp -extern Mutex& gProcessMutex; -extern sp<ProcessState> gProcess; - } // namespace android 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/Binder.h b/libs/binder/include/binder/Binder.h index 74e52db53f..f3fea163cd 100644 --- a/libs/binder/include/binder/Binder.h +++ b/libs/binder/include/binder/Binder.h @@ -72,6 +72,22 @@ public: // This must be called before the object is sent to another process. Not thread safe. void setExtension(const sp<IBinder>& extension); + // This must be called before the object is sent to another process. Not thread safe. + // + // This function will abort if improper parameters are set. This is like + // sched_setscheduler. However, it sets the minimum scheduling policy + // only for the duration that this specific binder object is handling the + // call in a threadpool. By default, this API is set to SCHED_NORMAL/0. In + // this case, the scheduling priority will not actually be modified from + // binder defaults. See also IPCThreadState::disableBackgroundScheduling. + // + // Appropriate values are: + // SCHED_NORMAL: -20 <= priority <= 19 + // SCHED_RR/SCHED_FIFO: 1 <= priority <= 99 + void setMinSchedulerPolicy(int policy, int priority); + int getMinSchedulerPolicy(); + int getMinSchedulerPriority(); + pid_t getDebugPid(); protected: 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..2bd39a7759 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 + * Binder::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); @@ -69,8 +85,8 @@ public: int64_t clearCallingIdentity(); // Restores PID/UID (not SID) void restoreCallingIdentity(int64_t token); - - int setupPolling(int* fd); + + status_t setupPolling(int* fd); status_t handlePolledCommands(); void flushCommands(); 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..83c2f1991d 100644 --- a/libs/binder/include/binder/Parcelable.h +++ b/libs/binder/include/binder/Parcelable.h @@ -52,6 +52,21 @@ public: // // Returns android::OK on success and an appropriate error otherwise. virtual status_t readFromParcel(const Parcel* parcel) = 0; + + // WARNING: for use by auto-generated code only (AIDL). Should not be used + // manually, or there is a risk of breaking CTS, GTS, VTS, or CTS-on-GSI + // tests. + enum class Stability { + STABILITY_LOCAL, + STABILITY_VINTF, // corresponds to @VintfStability + }; + + // 'Stable' means this parcelable is guaranteed to be stable for multiple + // years. + // It must be guaranteed by setting stability field in aidl_interface. + // WARNING: getStability() is only expected to be overridden by auto-generated + // code. Returns true if this parcelable is stable. + virtual Stability getStability() const { return Stability::STABILITY_LOCAL; } }; // class Parcelable #if defined(__clang__) diff --git a/libs/binder/include/binder/ProcessState.h b/libs/binder/include/binder/ProcessState.h index e57ff1c260..9f5346ac27 100644 --- a/libs/binder/include/binder/ProcessState.h +++ b/libs/binder/include/binder/ProcessState.h @@ -42,6 +42,8 @@ public: * any call to ProcessState::self(). The default is /dev/vndbinder * for processes built with the VNDK and /dev/binder for those * which are not. + * + * If this is called with nullptr, the behavior is the same as selfOrNull. */ static sp<ProcessState> initWithDriver(const char *driver); @@ -90,6 +92,8 @@ public: void setCallRestriction(CallRestriction restriction); private: + static sp<ProcessState> init(const char *defaultDriver, bool requireDefault); + friend class IPCThreadState; explicit ProcessState(const char* driver); diff --git a/libs/binder/include/binder/Stability.h b/libs/binder/include/binder/Stability.h index 2894482f55..6566285155 100644 --- a/libs/binder/include/binder/Stability.h +++ b/libs/binder/include/binder/Stability.h @@ -81,11 +81,8 @@ private: VINTF = 0b111111, }; -#if defined(__ANDROID_VNDK__) && !defined(__ANDROID_APEX__) - static constexpr Level kLocalStability = Level::VENDOR; -#else - static constexpr Level kLocalStability = Level::SYSTEM; -#endif + // returns the stability according to how this was built + static Level getLocalStability(); // applies stability to binder if stability level is known __attribute__((warn_unused_result)) diff --git a/libs/binder/include/binder/TextOutput.h b/libs/binder/include/binder/TextOutput.h index f66406f7d4..c7e1e14218 100644 --- a/libs/binder/include/binder/TextOutput.h +++ b/libs/binder/include/binder/TextOutput.h @@ -50,12 +50,18 @@ public: // --------------------------------------------------------------------------- +// DO NOT USE: prefer libutils/libbase logs, which don't require static data to +// be allocated. // Text output stream for printing to the log (via utils/Log.h). extern TextOutput& alog; +// DO NOT USE: prefer libutils/libbase logs, which don't require static data to +// be allocated. // Text output stream for printing to stdout. extern TextOutput& aout; +// DO NOT USE: prefer libutils/libbase logs, which don't require static data to +// be allocated. // Text output stream for printing to stderr. extern TextOutput& aerr; diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp index b37db434a5..4fd06573b7 100644 --- a/libs/binder/ndk/Android.bp +++ b/libs/binder/ndk/Android.bp @@ -36,6 +36,7 @@ cc_library { host_supported: true, export_include_dirs: [ + "include_cpp", "include_ndk", "include_platform", ], @@ -101,6 +102,17 @@ ndk_headers { license: "NOTICE", } +// TODO(b/160624671): package with the aidl compiler +ndk_headers { + name: "libbinder_ndk_helper_headers", + from: "include_cpp/android", + to: "android", + srcs: [ + "include_cpp/android/*.h", + ], + license: "NOTICE", +} + ndk_library { name: "libbinder_ndk", symbol_file: "libbinder_ndk.map.txt", @@ -111,6 +123,7 @@ llndk_library { name: "libbinder_ndk", symbol_file: "libbinder_ndk.map.txt", export_include_dirs: [ + "include_cpp", "include_ndk", "include_platform", ], diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp index 649faa1c76..d287290a8d 100644 --- a/libs/binder/ndk/ibinder.cpp +++ b/libs/binder/ndk/ibinder.cpp @@ -15,6 +15,7 @@ */ #include <android/binder_ibinder.h> +#include <android/binder_ibinder_platform.h> #include "ibinder_internal.h" #include <android/binder_stability.h> @@ -99,8 +100,14 @@ bool AIBinder::associateClass(const AIBinder_Class* clazz) { String8 descriptor(getBinder()->getInterfaceDescriptor()); if (descriptor != newDescriptor) { - LOG(ERROR) << __func__ << ": Expecting binder to have class '" << newDescriptor.c_str() - << "' but descriptor is actually '" << descriptor.c_str() << "'."; + if (getBinder()->isBinderAlive()) { + LOG(ERROR) << __func__ << ": Expecting binder to have class '" << newDescriptor.c_str() + << "' but descriptor is actually '" << descriptor.c_str() << "'."; + } else { + // b/155793159 + LOG(ERROR) << __func__ << ": Cannot associate class '" << newDescriptor.c_str() + << "' to dead binder."; + } return false; } @@ -676,3 +683,29 @@ binder_status_t AIBinder_setExtension(AIBinder* binder, AIBinder* ext) { rawBinder->setExtension(ext->getBinder()); return STATUS_OK; } + +// platform methods follow + +void AIBinder_setRequestingSid(AIBinder* binder, bool requestingSid) { + ABBinder* localBinder = binder->asABBinder(); + if (localBinder == nullptr) { + LOG(FATAL) << "AIBinder_setRequestingSid must be called on a local binder"; + } + + localBinder->setRequestingSid(requestingSid); +} + +const char* AIBinder_getCallingSid() { + return ::android::IPCThreadState::self()->getCallingSid(); +} + +android::sp<android::IBinder> AIBinder_toPlatformBinder(AIBinder* binder) { + if (binder == nullptr) return nullptr; + return binder->getBinder(); +} + +AIBinder* AIBinder_fromPlatformBinder(const android::sp<android::IBinder>& binder) { + sp<AIBinder> ndkBinder = ABpBinder::lookupOrCreateFromBinder(binder); + AIBinder_incStrong(ndkBinder.get()); + return ndkBinder.get(); +} diff --git a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h index 2b61cf18c2..f59bb75cc1 100644 --- a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h +++ b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h @@ -189,6 +189,7 @@ class ScopedAParcel : public impl::ScopedAResource<AParcel*, void, AParcel_delet explicit ScopedAParcel(AParcel* a = nullptr) : ScopedAResource(a) {} ~ScopedAParcel() {} ScopedAParcel(ScopedAParcel&&) = default; + ScopedAParcel& operator=(ScopedAParcel&&) = default; }; /** @@ -273,6 +274,7 @@ class ScopedAIBinder_DeathRecipient : ScopedAResource(a) {} ~ScopedAIBinder_DeathRecipient() {} ScopedAIBinder_DeathRecipient(ScopedAIBinder_DeathRecipient&&) = default; + ScopedAIBinder_DeathRecipient& operator=(ScopedAIBinder_DeathRecipient&&) = default; }; /** @@ -287,6 +289,7 @@ class ScopedAIBinder_Weak explicit ScopedAIBinder_Weak(AIBinder_Weak* a = nullptr) : ScopedAResource(a) {} ~ScopedAIBinder_Weak() {} ScopedAIBinder_Weak(ScopedAIBinder_Weak&&) = default; + ScopedAIBinder_Weak& operator=(ScopedAIBinder_Weak&&) = default; /** * See AIBinder_Weak_promote. @@ -305,6 +308,7 @@ class ScopedFileDescriptor : public impl::ScopedAResource<int, int, close, -1> { explicit ScopedFileDescriptor(int a = -1) : ScopedAResource(a) {} ~ScopedFileDescriptor() {} ScopedFileDescriptor(ScopedFileDescriptor&&) = default; + ScopedFileDescriptor& operator=(ScopedFileDescriptor&&) = default; }; } // namespace ndk diff --git a/libs/binder/ndk/include_ndk/android/binder_enums.h b/libs/binder/ndk/include_cpp/android/binder_enums.h index ee819c0b23..ee819c0b23 100644 --- a/libs/binder/ndk/include_ndk/android/binder_enums.h +++ b/libs/binder/ndk/include_cpp/android/binder_enums.h diff --git a/libs/binder/ndk/include_ndk/android/binder_interface_utils.h b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h index 33e4586137..33e4586137 100644 --- a/libs/binder/ndk/include_ndk/android/binder_interface_utils.h +++ b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h b/libs/binder/ndk/include_cpp/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_cpp/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_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h index 4560f222cb..33763d58be 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> @@ -407,6 +408,8 @@ int32_t AIBinder_debugGetRefCount(AIBinder* binder) __INTRODUCED_IN(29); * This returns true if the class association succeeds. If it fails, no change is made to the * binder object. * + * Warning: this may fail if the binder is dead. + * * Available since API level 29. * * \param binder the object to attach the class to. 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_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/include_platform/android/binder_ibinder_platform.h b/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h new file mode 100644 index 0000000000..d4feabac8a --- /dev/null +++ b/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h @@ -0,0 +1,80 @@ +/* + * 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. + */ + +#pragma once + +#include <android/binder_ibinder.h> + +#if !defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__) +#include <binder/IBinder.h> +#endif + +__BEGIN_DECLS + +/** + * Makes calls to AIBinder_getCallingSid work if the kernel supports it. This + * must be called on a local binder server before it is sent out to any othe + * process. If this is a remote binder, it will abort. If the kernel doesn't + * support this feature, you'll always get null from AIBinder_getCallingSid. + * + * \param binder local server binder to request security contexts on + */ +void AIBinder_setRequestingSid(AIBinder* binder, bool requestingSid) __INTRODUCED_IN(31); + +/** + * Returns the selinux context of the callee. + * + * In order for this to work, the following conditions must be met: + * - The kernel must be new enough to support this feature. + * - The server must have called AIBinder_setRequestingSid. + * - The callee must be a remote process. + * + * \return security context or null if unavailable. The lifetime of this context + * is the lifetime of the transaction. + */ +__attribute__((warn_unused_result)) const char* AIBinder_getCallingSid() __INTRODUCED_IN(31); + +__END_DECLS + +#if !defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__) + +/** + * Get libbinder version of binder from AIBinder. + * + * WARNING: function calls to a local object on the other side of this function + * will parcel. When converting between binders, keep in mind it is not as + * efficient as a direct function call. + * + * \param binder binder with ownership retained by the client + * \return platform binder object + */ +android::sp<android::IBinder> AIBinder_toPlatformBinder(AIBinder* binder); + +/** + * Get libbinder_ndk version of binder from platform binder. + * + * WARNING: function calls to a local object on the other side of this function + * will parcel. When converting between binders, keep in mind it is not as + * efficient as a direct function call. + * + * \param binder platform binder which may be from anywhere (doesn't have to be + * created with libbinder_ndK) + * \return binder with one reference count of ownership given to the client. See + * AIBinder_decStrong + */ +AIBinder* AIBinder_fromPlatformBinder(const android::sp<android::IBinder>& binder); + +#endif diff --git a/libs/binder/ndk/include_platform/android/binder_parcel_platform.h b/libs/binder/ndk/include_platform/android/binder_parcel_platform.h index ac46cb80f4..114a781232 100644 --- a/libs/binder/ndk/include_platform/android/binder_parcel_platform.h +++ b/libs/binder/ndk/include_platform/android/binder_parcel_platform.h @@ -20,6 +20,10 @@ __BEGIN_DECLS +#if defined(__ANDROID_APEX__) || defined(__ANDROID_VNDK__) +#error this is only for platform code +#endif + /** * Gets whether or not FDs are allowed by this AParcel * @@ -29,4 +33,4 @@ __BEGIN_DECLS */ bool AParcel_getAllowFds(const AParcel*); -__END_DECLS
\ No newline at end of file +__END_DECLS diff --git a/libs/binder/ndk/include_platform/android/binder_process.h b/libs/binder/ndk/include_platform/android/binder_process.h index fdefbb4b8a..f408fadee0 100644 --- a/libs/binder/ndk/include_platform/android/binder_process.h +++ b/libs/binder/ndk/include_platform/android/binder_process.h @@ -19,10 +19,15 @@ #include <stdint.h> #include <sys/cdefs.h> +#include <android/binder_status.h> + __BEGIN_DECLS /** * This creates a threadpool for incoming binder transactions if it has not already been created. + * + * When using this, it is expected that ABinderProcess_setupPolling and + * ABinderProcess_handlePolledCommands are not used. */ void ABinderProcess_startThreadPool(); /** @@ -37,4 +42,27 @@ bool ABinderProcess_setThreadPoolMaxThreadCount(uint32_t numThreads); */ void ABinderProcess_joinThreadPool(); +/** + * This gives you an fd to wait on. Whenever data is available on the fd, + * ABinderProcess_handlePolledCommands can be called to handle binder queries. + * This is expected to be used in a single threaded process which waits on + * events from multiple different fds. + * + * When using this, it is expected ABinderProcess_startThreadPool and + * ABinderProcess_joinThreadPool are not used. + * + * \param fd out param corresponding to the binder domain opened in this + * process. + * \return STATUS_OK on success + */ +__attribute__((weak)) binder_status_t ABinderProcess_setupPolling(int* fd) __INTRODUCED_IN(31); + +/** + * This will handle all queued binder commands in this process and then return. + * It is expected to be called whenever there is data on the fd. + * + * \return STATUS_OK on success + */ +__attribute__((weak)) binder_status_t ABinderProcess_handlePolledCommands() __INTRODUCED_IN(31); + __END_DECLS diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt index a9eba47380..d4353823a0 100644 --- a/libs/binder/ndk/libbinder_ndk.map.txt +++ b/libs/binder/ndk/libbinder_ndk.map.txt @@ -95,8 +95,6 @@ LIBBINDER_NDK { # introduced=29 AServiceManager_addService; # apex llndk AServiceManager_checkService; # apex llndk AServiceManager_getService; # apex llndk - local: - *; }; LIBBINDER_NDK30 { # introduced=30 @@ -111,11 +109,23 @@ LIBBINDER_NDK30 { # introduced=30 AIBinder_markVendorStability; # llndk AIBinder_markVintfStability; # apex llndk AIBinder_Class_setHandleShellCommand; # apex llndk - local: - *; +}; + +LIBBINDER_NDK31 { # introduced=31 + global: + ABinderProcess_handlePolledCommands; # apex + ABinderProcess_setupPolling; # apex + AIBinder_getCallingSid; # apex + AIBinder_setRequestingSid; # apex }; LIBBINDER_NDK_PLATFORM { global: AParcel_getAllowFds; + extern "C++" { + AIBinder_fromPlatformBinder*; + AIBinder_toPlatformBinder*; + }; + local: + *; }; diff --git a/libs/binder/ndk/process.cpp b/libs/binder/ndk/process.cpp index c89caaf349..ac582a412e 100644 --- a/libs/binder/ndk/process.cpp +++ b/libs/binder/ndk/process.cpp @@ -34,3 +34,11 @@ bool ABinderProcess_setThreadPoolMaxThreadCount(uint32_t numThreads) { void ABinderProcess_joinThreadPool() { IPCThreadState::self()->joinThreadPool(); } + +binder_status_t ABinderProcess_setupPolling(int* fd) { + return IPCThreadState::self()->setupPolling(fd); +} + +binder_status_t ABinderProcess_handlePolledCommands() { + return IPCThreadState::self()->handlePolledCommands(); +} diff --git a/libs/binder/ndk/test/Android.bp b/libs/binder/ndk/tests/Android.bp index 5f5265c90e..7c271f67cb 100644 --- a/libs/binder/ndk/test/Android.bp +++ b/libs/binder/ndk/tests/Android.bp @@ -40,6 +40,7 @@ cc_library_static { cc_defaults { name: "test_libbinder_ndk_test_defaults", defaults: ["test_libbinder_ndk_defaults"], + // critical that libbinder/libbinder_ndk are shared for VTS shared_libs: [ "libandroid_runtime_lazy", "libbase", @@ -63,7 +64,7 @@ cc_test { "IBinderNdkUnitTest-cpp", "IBinderNdkUnitTest-ndk_platform", ], - test_suites: ["general-tests"], + test_suites: ["general-tests", "vts"], require_root: true, // force since binderVendorDoubleLoadTest has its own @@ -81,13 +82,14 @@ cc_test { "IBinderVendorDoubleLoadTest-ndk_platform", "libbinder_aidl_test_stub-ndk_platform", ], + // critical that libbinder/libbinder_ndk are shared for VTS shared_libs: [ "libbase", "libbinder", "libbinder_ndk", "libutils", ], - test_suites: ["general-tests"], + test_suites: ["general-tests", "vts"], } aidl_interface { 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..dc77467d8c 100644 --- a/libs/binder/ndk/test/IBinderNdkUnitTest.aidl +++ b/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl @@ -22,6 +22,10 @@ import IEmpty; interface IBinderNdkUnitTest { + int repeatInt(int a); + void takeInterface(IEmpty test); void forceFlushCommands(); + + boolean getsRequestedSid(); } 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..9b2fcf009a 100644 --- a/libs/binder/ndk/test/libbinder_ndk_unit_test.cpp +++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp @@ -19,10 +19,12 @@ #include <aidl/BnEmpty.h> #include <android-base/logging.h> #include <android/binder_ibinder_jni.h> +#include <android/binder_ibinder_platform.h> #include <android/binder_manager.h> #include <android/binder_process.h> #include <gtest/gtest.h> #include <iface/iface.h> +#include <utils/Looper.h> // warning: this is assuming that libbinder_ndk is using the same copy // of libbinder that we are. @@ -34,6 +36,7 @@ #include <sys/prctl.h> #include <chrono> #include <condition_variable> +#include <iostream> #include <mutex> using namespace android; @@ -42,6 +45,10 @@ constexpr char kExistingNonNdkService[] = "SurfaceFlinger"; constexpr char kBinderNdkUnitTestService[] = "BinderNdkUnitTest"; class MyBinderNdkUnitTest : public aidl::BnBinderNdkUnitTest { + ndk::ScopedAStatus repeatInt(int32_t in, int32_t* out) { + *out = in; + return ndk::ScopedAStatus::ok(); + } ndk::ScopedAStatus takeInterface(const std::shared_ptr<aidl::IEmpty>& empty) { (void)empty; return ndk::ScopedAStatus::ok(); @@ -52,6 +59,12 @@ class MyBinderNdkUnitTest : public aidl::BnBinderNdkUnitTest { android::IPCThreadState::self()->flushCommands(); return ndk::ScopedAStatus::ok(); } + ndk::ScopedAStatus getsRequestedSid(bool* out) { + const char* sid = AIBinder_getCallingSid(); + std::cout << "Got security context: " << (sid ?: "null") << std::endl; + *out = sid != nullptr; + return ndk::ScopedAStatus::ok(); + } binder_status_t handleShellCommand(int /*in*/, int out, int /*err*/, const char** args, uint32_t numArgs) override { for (uint32_t i = 0; i < numArgs; i++) { @@ -66,8 +79,11 @@ int generatedService() { ABinderProcess_setThreadPoolMaxThreadCount(0); auto service = ndk::SharedRefBase::make<MyBinderNdkUnitTest>(); - binder_status_t status = - AServiceManager_addService(service->asBinder().get(), kBinderNdkUnitTestService); + auto binder = service->asBinder(); + + AIBinder_setRequestingSid(binder.get(), true); + + binder_status_t status = AServiceManager_addService(binder.get(), kBinderNdkUnitTestService); if (status != STATUS_OK) { LOG(FATAL) << "Could not register: " << status << " " << kBinderNdkUnitTestService; @@ -92,19 +108,39 @@ class MyFoo : public IFoo { } }; -int manualService(const char* instance) { - ABinderProcess_setThreadPoolMaxThreadCount(0); - +void manualService(const char* instance) { // Strong reference to MyFoo kept by service manager. binder_status_t status = (new MyFoo)->addService(instance); if (status != STATUS_OK) { LOG(FATAL) << "Could not register: " << status << " " << instance; } +} +int manualPollingService(const char* instance) { + int fd; + CHECK(STATUS_OK == ABinderProcess_setupPolling(&fd)); + manualService(instance); + + class Handler : public LooperCallback { + int handleEvent(int /*fd*/, int /*events*/, void* /*data*/) override { + ABinderProcess_handlePolledCommands(); + return 1; // Continue receiving callbacks. + } + }; + sp<Looper> looper = Looper::prepare(0 /* opts */); + looper->addFd(fd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, new Handler(), nullptr /*data*/); + // normally, would add additional fds + while (true) { + looper->pollAll(-1 /* timeoutMillis */); + } + return 1; // should not reach +} +int manualThreadPoolService(const char* instance) { + ABinderProcess_setThreadPoolMaxThreadCount(0); + manualService(instance); ABinderProcess_joinThreadPool(); - - return 1; // should not return + return 1; } // This is too slow @@ -274,6 +310,16 @@ TEST(NdkBinder, AddServiceMultipleTimes) { EXPECT_EQ(IFoo::getService(kInstanceName1), IFoo::getService(kInstanceName2)); } +TEST(NdkBinder, RequestedSidWorks) { + ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService)); + std::shared_ptr<aidl::IBinderNdkUnitTest> service = + aidl::IBinderNdkUnitTest::fromBinder(binder); + + bool gotSid = false; + EXPECT_TRUE(service->getsRequestedSid(&gotSid).isOk()); + EXPECT_TRUE(gotSid); +} + TEST(NdkBinder, SentAidlBinderCanBeDestroyed) { static volatile bool destroyed = false; static std::mutex dMutex; @@ -308,6 +354,30 @@ TEST(NdkBinder, SentAidlBinderCanBeDestroyed) { EXPECT_TRUE(destroyed); } +TEST(NdkBinder, ConvertToPlatformBinder) { + for (const ndk::SpAIBinder& binder : + {// remote + ndk::SpAIBinder(AServiceManager_getService(kBinderNdkUnitTestService)), + // local + ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder()}) { + // convert to platform binder + EXPECT_NE(binder.get(), nullptr); + sp<IBinder> platformBinder = AIBinder_toPlatformBinder(binder.get()); + EXPECT_NE(platformBinder.get(), nullptr); + auto proxy = interface_cast<IBinderNdkUnitTest>(platformBinder); + EXPECT_NE(proxy, nullptr); + + // use platform binder + int out; + EXPECT_TRUE(proxy->repeatInt(4, &out).isOk()); + EXPECT_EQ(out, 4); + + // convert back + ndk::SpAIBinder backBinder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(platformBinder)); + EXPECT_EQ(backBinder.get(), binder.get()); + } +} + class MyResultReceiver : public BnResultReceiver { public: Mutex mMutex; @@ -399,11 +469,11 @@ int main(int argc, char* argv[]) { if (fork() == 0) { prctl(PR_SET_PDEATHSIG, SIGHUP); - return manualService(IFoo::kInstanceNameToDieFor); + return manualThreadPoolService(IFoo::kInstanceNameToDieFor); } if (fork() == 0) { prctl(PR_SET_PDEATHSIG, SIGHUP); - return manualService(IFoo::kSomeInstanceName); + return manualPollingService(IFoo::kSomeInstanceName); } if (fork() == 0) { prctl(PR_SET_PDEATHSIG, SIGHUP); diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp index c0da2cd8d4..a03835b34c 100644 --- a/libs/binder/tests/Android.bp +++ b/libs/binder/tests/Android.bp @@ -155,6 +155,7 @@ cc_test { "binderStabilityTest.cpp", ], + // critical that libbinder/libbinder_ndk are shared for VTS shared_libs: [ "libbinder_ndk", "libbinder", @@ -166,6 +167,21 @@ cc_test { "binderStabilityTestIface-ndk_platform", ], + test_suites: ["device-tests", "vts"], + 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/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp index 40de2db2cb..917751ef34 100644 --- a/libs/binder/tests/binderLibTest.cpp +++ b/libs/binder/tests/binderLibTest.cpp @@ -50,6 +50,9 @@ static char *binderservername; static char *binderserversuffix; static char binderserverarg[] = "--binderserver"; +static constexpr int kSchedPolicy = SCHED_RR; +static constexpr int kSchedPriority = 7; + static String16 binderLibTestServiceName = String16("test.binderLib"); enum BinderLibTestTranscationCode { @@ -75,6 +78,7 @@ enum BinderLibTestTranscationCode { BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION, BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION, BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION, + BINDER_LIB_TEST_GET_SCHEDULING_POLICY, BINDER_LIB_TEST_ECHO_VECTOR, BINDER_LIB_TEST_REJECT_BUF, }; @@ -1015,6 +1019,22 @@ TEST_F(BinderLibTest, WorkSourcePropagatedForAllFollowingBinderCalls) EXPECT_EQ(NO_ERROR, ret2); } +TEST_F(BinderLibTest, SchedPolicySet) { + sp<IBinder> server = addServer(); + ASSERT_TRUE(server != nullptr); + + Parcel data, reply; + status_t ret = server->transact(BINDER_LIB_TEST_GET_SCHEDULING_POLICY, data, &reply); + EXPECT_EQ(NO_ERROR, ret); + + int policy = reply.readInt32(); + int priority = reply.readInt32(); + + EXPECT_EQ(kSchedPolicy, policy & (~SCHED_RESET_ON_FORK)); + EXPECT_EQ(kSchedPriority, priority); +} + + TEST_F(BinderLibTest, VectorSent) { Parcel data, reply; sp<IBinder> server = addServer(); @@ -1332,6 +1352,16 @@ class BinderLibTestService : public BBinder reply->writeInt32(IPCThreadState::self()->getCallingWorkSourceUid()); return NO_ERROR; } + case BINDER_LIB_TEST_GET_SCHEDULING_POLICY: { + int policy = 0; + sched_param param; + if (0 != pthread_getschedparam(pthread_self(), &policy, ¶m)) { + return UNKNOWN_ERROR; + } + reply->writeInt32(policy); + reply->writeInt32(param.sched_priority); + return NO_ERROR; + } case BINDER_LIB_TEST_ECHO_VECTOR: { std::vector<uint64_t> vector; auto err = data.readUint64Vector(&vector); @@ -1368,6 +1398,8 @@ int run_server(int index, int readypipefd, bool usePoll) { sp<BinderLibTestService> testService = new BinderLibTestService(index); + testService->setMinSchedulerPolicy(kSchedPolicy, kSchedPriority); + /* * Normally would also contain functionality as well, but we are only * testing the extension mechanism. 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/binderthreadstate/test.cpp b/libs/binderthreadstate/test.cpp index 68cc225057..44e2fd19b1 100644 --- a/libs/binderthreadstate/test.cpp +++ b/libs/binderthreadstate/test.cpp @@ -165,7 +165,6 @@ int server(size_t thisId, size_t otherId) { android::ProcessState::self()->startThreadPool(); // HIDL - setenv("TREBLE_TESTING_OVERRIDE", "true", true); android::hardware::configureRpcThreadpool(1, true /*callerWillJoin*/); sp<IHidlStuff> hidlServer = new HidlServer(thisId, otherId); CHECK(OK == hidlServer->registerAsService(id2name(thisId).c_str())); @@ -176,7 +175,7 @@ int server(size_t thisId, size_t otherId) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - setenv("TREBLE_TESTING_OVERRIDE", "true", true); + android::hardware::details::setTrebleTestingOverride(true); if (fork() == 0) { prctl(PR_SET_PDEATHSIG, SIGHUP); return server(kP1Id, kP2Id); 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/BufferHubProducer.cpp b/libs/gui/BufferHubProducer.cpp index 489f3c356b..1f71e23b4d 100644 --- a/libs/gui/BufferHubProducer.cpp +++ b/libs/gui/BufferHubProducer.cpp @@ -696,7 +696,7 @@ String8 BufferHubProducer::getConsumerName() const { // relationship, thus |getConsumerName| from the producer side does not // make any sense. ALOGE("BufferHubProducer::getConsumerName not supported."); - return String8("BufferHubQueue::DummyConsumer"); + return String8("BufferHubQueue::StubConsumer"); } status_t BufferHubProducer::setSharedBufferMode(bool shared_buffer_mode) { diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp index 59f1bcd24e..30d19e3af4 100644 --- a/libs/gui/GLConsumer.cpp +++ b/libs/gui/GLConsumer.cpp @@ -280,7 +280,7 @@ status_t GLConsumer::releaseTexImage() { mCurrentFenceTime = FenceTime::NO_FENCE; if (mAttached) { - // This binds a dummy buffer (mReleasedTexImage). + // This binds a buffer placeholder (mReleasedTexImage). status_t result = bindTextureImageLocked(); if (result != NO_ERROR) { return result; diff --git a/libs/gui/IProducerListener.cpp b/libs/gui/IProducerListener.cpp index 5c81b9d7db..0683087211 100644 --- a/libs/gui/IProducerListener.cpp +++ b/libs/gui/IProducerListener.cpp @@ -119,7 +119,7 @@ status_t BnProducerListener::onTransact(uint32_t code, const Parcel& data, return BBinder::onTransact(code, data, reply, flags); } -DummyProducerListener::~DummyProducerListener() = default; +StubProducerListener::~StubProducerListener() = default; bool BnProducerListener::needsReleaseNotify() { return true; diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index e43446ac8c..0281279d69 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -176,7 +176,12 @@ status_t layer_state_t::read(const Parcel& input) sidebandStream = NativeHandle::create(input.readNativeHandle(), true); } - colorTransform = mat4(static_cast<const float*>(input.readInplace(16 * sizeof(float)))); + const void* color_transform_data = input.readInplace(16 * sizeof(float)); + if (color_transform_data) { + colorTransform = mat4(static_cast<const float*>(color_transform_data)); + } else { + return BAD_VALUE; + } cornerRadius = input.readFloat(); backgroundBlurRadius = input.readUint32(); cachedBuffer.token = input.readStrongBinder(); diff --git a/libs/gui/OWNERS b/libs/gui/OWNERS index c13401dc5c..ecccf29351 100644 --- a/libs/gui/OWNERS +++ b/libs/gui/OWNERS @@ -1,12 +1,25 @@ 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 + +# BufferQueue is feature-frozen +per-file BufferQueue* = set noparent +per-file BufferQueue* = jreck@google.com, sumir@google.com, alecmouri@google.com +per-file IGraphicBuffer* = set noparent +per-file IGraphicBuffer* = jreck@google.com, sumir@google.com, alecmouri@google.com +per-file include/gui/BufferQueue* = set noparent +per-file include/gui/BufferQueue* = jreck@google.com, sumir@google.com, alecmouri@google.com +per-file include/gui/IGraphicBuffer* = set noparent +per-file include/gui/IGraphicBuffer* = jreck@google.com, sumir@google.com, alecmouri@google.com
\ No newline at end of file diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index cf269b33ba..c3323fefb2 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -1513,7 +1513,7 @@ bool Surface::transformToDisplayInverse() { } int Surface::connect(int api) { - static sp<IProducerListener> listener = new DummyProducerListener(); + static sp<IProducerListener> listener = new StubProducerListener(); return connect(api, listener); } diff --git a/libs/gui/bufferqueue/OWNERS b/libs/gui/bufferqueue/OWNERS index cbe931707c..615dd79c63 100644 --- a/libs/gui/bufferqueue/OWNERS +++ b/libs/gui/bufferqueue/OWNERS @@ -1,5 +1,4 @@ -chz@google.com -lajos@google.com -pawin@google.com -taklee@google.com -wonsik@google.com +# BufferQueue is feature-frozen +jreck@google.com +sumir@google.com +alecmouri@google.com
\ No newline at end of file diff --git a/libs/gui/include/gui/GLConsumer.h b/libs/gui/include/gui/GLConsumer.h index ddd868d7d1..2f538ffb86 100644 --- a/libs/gui/include/gui/GLConsumer.h +++ b/libs/gui/include/gui/GLConsumer.h @@ -499,7 +499,7 @@ private: // protects static initialization static Mutex sStaticInitLock; - // mReleasedTexImageBuffer is a dummy buffer used when in single buffer + // mReleasedTexImageBuffer is a buffer placeholder used when in single buffer // mode and releaseTexImage() has been called static sp<GraphicBuffer> sReleasedTexImageBuffer; sp<EglImage> mReleasedTexImage; diff --git a/libs/gui/include/gui/IGraphicBufferProducer.h b/libs/gui/include/gui/IGraphicBufferProducer.h index d7f34920c4..45e0a134ba 100644 --- a/libs/gui/include/gui/IGraphicBufferProducer.h +++ b/libs/gui/include/gui/IGraphicBufferProducer.h @@ -458,7 +458,7 @@ public: // the producer wants to be notified when the consumer releases a buffer // back to the BufferQueue. It is also used to detect the death of the // producer. If only the latter functionality is desired, there is a - // DummyProducerListener class in IProducerListener.h that can be used. + // StubProducerListener class in IProducerListener.h that can be used. // // The api should be one of the NATIVE_WINDOW_API_* values in <window.h> // diff --git a/libs/gui/include/gui/IProducerListener.h b/libs/gui/include/gui/IProducerListener.h index 0b1f4b5838..f7ffbb99ea 100644 --- a/libs/gui/include/gui/IProducerListener.h +++ b/libs/gui/include/gui/IProducerListener.h @@ -80,10 +80,9 @@ class IProducerListener : public ProducerListener { class BnProducerListener : public IProducerListener { }; #endif -class DummyProducerListener : public BnProducerListener -{ +class StubProducerListener : public BnProducerListener { public: - virtual ~DummyProducerListener(); + virtual ~StubProducerListener(); virtual void onBufferReleased() {} virtual bool needsReleaseNotify() { return false; } }; diff --git a/libs/gui/include/gui/bufferqueue/1.0/WGraphicBufferProducer.h b/libs/gui/include/gui/bufferqueue/1.0/WGraphicBufferProducer.h index 99ab0857d3..004d87574a 100644 --- a/libs/gui/include/gui/bufferqueue/1.0/WGraphicBufferProducer.h +++ b/libs/gui/include/gui/bufferqueue/1.0/WGraphicBufferProducer.h @@ -51,12 +51,14 @@ typedef ::android::IGraphicBufferProducer BGraphicBufferProducer; typedef ::android::IProducerListener BProducerListener; #ifndef LOG -struct LOG_dummy { +struct LOG_stub { template <typename T> - LOG_dummy& operator<< (const T&) { return *this; } + LOG_stub& operator<<(const T&) { + return *this; + } }; -#define LOG(x) LOG_dummy() +#define LOG(x) LOG_stub() #endif // Instantiate only if HGraphicBufferProducer is base of BASE. diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp index d929a59f55..da5bbdd2e6 100644 --- a/libs/gui/tests/BLASTBufferQueue_test.cpp +++ b/libs/gui/tests/BLASTBufferQueue_test.cpp @@ -128,7 +128,7 @@ protected: ASSERT_EQ(NO_ERROR, igbProducer->setMaxDequeuedBufferCount(2)); IGraphicBufferProducer::QueueBufferOutput qbOutput; ASSERT_EQ(NO_ERROR, - igbProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false, + igbProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &qbOutput)); ASSERT_NE(ui::Transform::ROT_INVALID, qbOutput.transformHint); producer = igbProducer; diff --git a/libs/gui/tests/BufferItemConsumer_test.cpp b/libs/gui/tests/BufferItemConsumer_test.cpp index b87cbbdec8..fc6551c8e6 100644 --- a/libs/gui/tests/BufferItemConsumer_test.cpp +++ b/libs/gui/tests/BufferItemConsumer_test.cpp @@ -51,7 +51,7 @@ class BufferItemConsumerTest : public ::testing::Test { mBFL = new BufferFreedListener(this); mBIC->setBufferFreedListener(mBFL); - sp<IProducerListener> producerListener = new DummyProducerListener(); + sp<IProducerListener> producerListener = new StubProducerListener(); IGraphicBufferProducer::QueueBufferOutput bufferOutput; ASSERT_EQ(NO_ERROR, mProducer->connect(producerListener, NATIVE_WINDOW_API_CPU, @@ -131,7 +131,7 @@ class BufferItemConsumerTest : public ::testing::Test { // Test that detaching buffer from consumer side triggers onBufferFreed. TEST_F(BufferItemConsumerTest, TriggerBufferFreed_DetachBufferFromConsumer) { int slot; - // Producer: generate a dummy buffer. + // Producer: generate a placeholder buffer. DequeueBuffer(&slot); QueueBuffer(slot); diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp index 6d7b6bb9c6..d1208ee5ae 100644 --- a/libs/gui/tests/BufferQueue_test.cpp +++ b/libs/gui/tests/BufferQueue_test.cpp @@ -17,7 +17,7 @@ #define LOG_TAG "BufferQueue_test" //#define LOG_NDEBUG 0 -#include "DummyConsumer.h" +#include "MockConsumer.h" #include <gui/BufferItem.h> #include <gui/BufferQueue.h> @@ -134,8 +134,8 @@ TEST_F(BufferQueueTest, DISABLED_BufferQueueInAnotherProcess) { mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer); EXPECT_TRUE(mConsumer != nullptr); - sp<DummyConsumer> dc(new DummyConsumer); - ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); + sp<MockConsumer> mc(new MockConsumer); + ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false)); IGraphicBufferProducer::QueueBufferOutput output; ASSERT_EQ(OK, mProducer->connect(nullptr, NATIVE_WINDOW_API_CPU, false, &output)); @@ -171,23 +171,22 @@ TEST_F(BufferQueueTest, DISABLED_BufferQueueInAnotherProcess) { TEST_F(BufferQueueTest, GetMaxBufferCountInQueueBufferOutput_Succeeds) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - mConsumer->consumerConnect(dc, false); + sp<MockConsumer> mc(new MockConsumer); + mConsumer->consumerConnect(mc, false); int bufferCount = 50; mConsumer->setMaxBufferCount(bufferCount); IGraphicBufferProducer::QueueBufferOutput output; - mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false, &output); + mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &output); ASSERT_EQ(output.maxBufferCount, bufferCount); } TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - mConsumer->consumerConnect(dc, false); + sp<MockConsumer> mc(new MockConsumer); + mConsumer->consumerConnect(mc, false); IGraphicBufferProducer::QueueBufferOutput qbo; - mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false, - &qbo); + mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &qbo); mProducer->setMaxDequeuedBufferCount(3); int slot; @@ -219,15 +218,14 @@ TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - mConsumer->consumerConnect(dc, false); + sp<MockConsumer> mc(new MockConsumer); + mConsumer->consumerConnect(mc, false); EXPECT_EQ(OK, mConsumer->setMaxBufferCount(10)); EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(10)); IGraphicBufferProducer::QueueBufferOutput qbo; - mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false, - &qbo); + mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &qbo); mProducer->setMaxDequeuedBufferCount(3); int minBufferCount; @@ -263,12 +261,11 @@ TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - mConsumer->consumerConnect(dc, false); + sp<MockConsumer> mc(new MockConsumer); + mConsumer->consumerConnect(mc, false); IGraphicBufferProducer::QueueBufferOutput qbo; - mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false, - &qbo); + mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &qbo); mProducer->setMaxDequeuedBufferCount(2); int minBufferCount; @@ -310,8 +307,8 @@ TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) { TEST_F(BufferQueueTest, SetMaxBufferCountWithLegalValues_Succeeds) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - mConsumer->consumerConnect(dc, false); + sp<MockConsumer> mc(new MockConsumer); + mConsumer->consumerConnect(mc, false); // Test shared buffer mode EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1)); @@ -319,8 +316,8 @@ TEST_F(BufferQueueTest, SetMaxBufferCountWithLegalValues_Succeeds) { TEST_F(BufferQueueTest, SetMaxBufferCountWithIllegalValues_ReturnsError) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - mConsumer->consumerConnect(dc, false); + sp<MockConsumer> mc(new MockConsumer); + mConsumer->consumerConnect(mc, false); EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(0)); EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount( @@ -332,11 +329,11 @@ TEST_F(BufferQueueTest, SetMaxBufferCountWithIllegalValues_ReturnsError) { TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); + sp<MockConsumer> mc(new MockConsumer); + ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false)); IGraphicBufferProducer::QueueBufferOutput output; - ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, - NATIVE_WINDOW_API_CPU, false, &output)); + ASSERT_EQ(OK, + mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &output)); ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(-1)); // Index too low ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer( @@ -386,11 +383,11 @@ TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) { TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); + sp<MockConsumer> mc(new MockConsumer); + ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false)); IGraphicBufferProducer::QueueBufferOutput output; - ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, - NATIVE_WINDOW_API_CPU, false, &output)); + ASSERT_EQ(OK, + mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &output)); int slot; sp<Fence> fence; @@ -445,11 +442,11 @@ TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { TEST_F(BufferQueueTest, MoveFromConsumerToProducer) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); + sp<MockConsumer> mc(new MockConsumer); + ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false)); IGraphicBufferProducer::QueueBufferOutput output; - ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, - NATIVE_WINDOW_API_CPU, false, &output)); + ASSERT_EQ(OK, + mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &output)); int slot; sp<Fence> fence; @@ -488,11 +485,11 @@ TEST_F(BufferQueueTest, MoveFromConsumerToProducer) { TEST_F(BufferQueueTest, TestDisallowingAllocation) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); + sp<MockConsumer> mc(new MockConsumer); + ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true)); IGraphicBufferProducer::QueueBufferOutput output; - ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, - NATIVE_WINDOW_API_CPU, true, &output)); + ASSERT_EQ(OK, + mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output)); static const uint32_t WIDTH = 320; static const uint32_t HEIGHT = 240; @@ -526,11 +523,11 @@ TEST_F(BufferQueueTest, TestDisallowingAllocation) { TEST_F(BufferQueueTest, TestGenerationNumbers) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); + sp<MockConsumer> mc(new MockConsumer); + ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true)); IGraphicBufferProducer::QueueBufferOutput output; - ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, - NATIVE_WINDOW_API_CPU, true, &output)); + ASSERT_EQ(OK, + mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output)); ASSERT_EQ(OK, mProducer->setGenerationNumber(1)); @@ -568,11 +565,11 @@ TEST_F(BufferQueueTest, TestGenerationNumbers) { TEST_F(BufferQueueTest, TestSharedBufferModeWithoutAutoRefresh) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); + sp<MockConsumer> mc(new MockConsumer); + ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true)); IGraphicBufferProducer::QueueBufferOutput output; - ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, - NATIVE_WINDOW_API_CPU, true, &output)); + ASSERT_EQ(OK, + mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output)); ASSERT_EQ(OK, mProducer->setSharedBufferMode(true)); @@ -618,11 +615,11 @@ TEST_F(BufferQueueTest, TestSharedBufferModeWithoutAutoRefresh) { TEST_F(BufferQueueTest, TestSharedBufferModeWithAutoRefresh) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); + sp<MockConsumer> mc(new MockConsumer); + ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true)); IGraphicBufferProducer::QueueBufferOutput output; - ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, - NATIVE_WINDOW_API_CPU, true, &output)); + ASSERT_EQ(OK, + mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output)); ASSERT_EQ(OK, mProducer->setSharedBufferMode(true)); ASSERT_EQ(OK, mProducer->setAutoRefresh(true)); @@ -687,11 +684,11 @@ TEST_F(BufferQueueTest, TestSharedBufferModeWithAutoRefresh) { TEST_F(BufferQueueTest, TestSharedBufferModeUsingAlreadyDequeuedBuffer) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); + sp<MockConsumer> mc(new MockConsumer); + ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true)); IGraphicBufferProducer::QueueBufferOutput output; - ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, - NATIVE_WINDOW_API_CPU, true, &output)); + ASSERT_EQ(OK, + mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output)); // Dequeue a buffer int sharedSlot; @@ -738,11 +735,11 @@ TEST_F(BufferQueueTest, TestSharedBufferModeUsingAlreadyDequeuedBuffer) { TEST_F(BufferQueueTest, TestTimeouts) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); + sp<MockConsumer> mc(new MockConsumer); + ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true)); IGraphicBufferProducer::QueueBufferOutput output; - ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, - NATIVE_WINDOW_API_CPU, true, &output)); + ASSERT_EQ(OK, + mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output)); // Fill up the queue. Since the controlledByApp flags are set to true, this // queue should be in non-blocking mode, and we should be recycling the same @@ -800,11 +797,11 @@ TEST_F(BufferQueueTest, TestTimeouts) { TEST_F(BufferQueueTest, CanAttachWhileDisallowingAllocation) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); + sp<MockConsumer> mc(new MockConsumer); + ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true)); IGraphicBufferProducer::QueueBufferOutput output; - ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, - NATIVE_WINDOW_API_CPU, true, &output)); + ASSERT_EQ(OK, + mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output)); int slot = BufferQueue::INVALID_BUFFER_SLOT; sp<Fence> sourceFence; @@ -822,11 +819,11 @@ TEST_F(BufferQueueTest, CanAttachWhileDisallowingAllocation) { TEST_F(BufferQueueTest, CanRetrieveLastQueuedBuffer) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); + sp<MockConsumer> mc(new MockConsumer); + ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false)); IGraphicBufferProducer::QueueBufferOutput output; - ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, - NATIVE_WINDOW_API_CPU, false, &output)); + ASSERT_EQ(OK, + mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &output)); // Dequeue and queue the first buffer, storing the handle int slot = BufferQueue::INVALID_BUFFER_SLOT; @@ -876,11 +873,11 @@ TEST_F(BufferQueueTest, CanRetrieveLastQueuedBuffer) { TEST_F(BufferQueueTest, TestOccupancyHistory) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); + sp<MockConsumer> mc(new MockConsumer); + ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false)); IGraphicBufferProducer::QueueBufferOutput output; - ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, - NATIVE_WINDOW_API_CPU, false, &output)); + ASSERT_EQ(OK, + mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &output)); int slot = BufferQueue::INVALID_BUFFER_SLOT; sp<Fence> fence = Fence::NO_FENCE; @@ -1030,8 +1027,8 @@ private: TEST_F(BufferQueueTest, TestDiscardFreeBuffers) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); + sp<MockConsumer> mc(new MockConsumer); + ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false)); IGraphicBufferProducer::QueueBufferOutput output; sp<BufferDiscardedListener> pl(new BufferDiscardedListener); ASSERT_EQ(OK, mProducer->connect(pl, @@ -1115,11 +1112,11 @@ TEST_F(BufferQueueTest, TestDiscardFreeBuffers) { TEST_F(BufferQueueTest, TestBufferReplacedInQueueBuffer) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); + sp<MockConsumer> mc(new MockConsumer); + ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true)); IGraphicBufferProducer::QueueBufferOutput output; - ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, - NATIVE_WINDOW_API_CPU, true, &output)); + ASSERT_EQ(OK, + mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output)); ASSERT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1)); int slot = BufferQueue::INVALID_BUFFER_SLOT; @@ -1156,12 +1153,11 @@ TEST_F(BufferQueueTest, TestBufferReplacedInQueueBuffer) { TEST_F(BufferQueueTest, TestStaleBufferHandleSentAfterDisconnect) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); + sp<MockConsumer> mc(new MockConsumer); + ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true)); IGraphicBufferProducer::QueueBufferOutput output; - sp<IProducerListener> dummyListener(new DummyProducerListener); - ASSERT_EQ(OK, mProducer->connect(dummyListener, NATIVE_WINDOW_API_CPU, - true, &output)); + sp<IProducerListener> fakeListener(new StubProducerListener); + ASSERT_EQ(OK, mProducer->connect(fakeListener, NATIVE_WINDOW_API_CPU, true, &output)); int slot = BufferQueue::INVALID_BUFFER_SLOT; sp<Fence> fence = Fence::NO_FENCE; @@ -1215,15 +1211,13 @@ TEST_F(BufferQueueTest, TestStaleBufferHandleSentAfterDisconnect) { TEST_F(BufferQueueTest, TestProducerConnectDisconnect) { createBufferQueue(); - sp<DummyConsumer> dc(new DummyConsumer); - ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true)); + sp<MockConsumer> mc(new MockConsumer); + ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true)); IGraphicBufferProducer::QueueBufferOutput output; - sp<IProducerListener> dummyListener(new DummyProducerListener); + sp<IProducerListener> fakeListener(new StubProducerListener); ASSERT_EQ(NO_INIT, mProducer->disconnect(NATIVE_WINDOW_API_CPU)); - ASSERT_EQ(OK, mProducer->connect( - dummyListener, NATIVE_WINDOW_API_CPU, true, &output)); - ASSERT_EQ(BAD_VALUE, mProducer->connect( - dummyListener, NATIVE_WINDOW_API_MEDIA, true, &output)); + ASSERT_EQ(OK, mProducer->connect(fakeListener, NATIVE_WINDOW_API_CPU, true, &output)); + ASSERT_EQ(BAD_VALUE, mProducer->connect(fakeListener, NATIVE_WINDOW_API_MEDIA, true, &output)); ASSERT_EQ(BAD_VALUE, mProducer->disconnect(NATIVE_WINDOW_API_MEDIA)); ASSERT_EQ(OK, mProducer->disconnect(NATIVE_WINDOW_API_CPU)); diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp index 103f7753c8..15bd32d354 100644 --- a/libs/gui/tests/IGraphicBufferProducer_test.cpp +++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp @@ -17,7 +17,7 @@ #define LOG_TAG "IGraphicBufferProducer_test" //#define LOG_NDEBUG 0 -#include "DummyConsumer.h" +#include "MockConsumer.h" #include <gtest/gtest.h> @@ -89,7 +89,7 @@ protected: ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name()); - mDC = new DummyConsumer; + mMC = new MockConsumer; switch (GetParam()) { case USE_BUFFER_QUEUE_PRODUCER: { @@ -114,7 +114,7 @@ protected: } // Must connect consumer before producer connects will succeed. - ASSERT_OK(mConsumer->consumerConnect(mDC, /*controlledByApp*/false)); + ASSERT_OK(mConsumer->consumerConnect(mMC, /*controlledByApp*/ false)); } virtual void TearDown() { @@ -249,7 +249,7 @@ protected: } private: // hide from test body - sp<DummyConsumer> mDC; + sp<MockConsumer> mMC; protected: // accessible from test body sp<IGraphicBufferProducer> mProducer; diff --git a/libs/gui/tests/Malicious.cpp b/libs/gui/tests/Malicious.cpp index acd42979c2..58d7cc6f35 100644 --- a/libs/gui/tests/Malicious.cpp +++ b/libs/gui/tests/Malicious.cpp @@ -129,7 +129,7 @@ private: int32_t mExpectedSlot = 0; }; -class DummyListener : public BnConsumerListener { +class FakeListener : public BnConsumerListener { public: void onFrameAvailable(const BufferItem&) override {} void onBuffersReleased() override {} @@ -140,7 +140,7 @@ sp<MaliciousBQP> getMaliciousBQP() { sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - sp<IConsumerListener> listener = new DummyListener; + sp<IConsumerListener> listener = new FakeListener; consumer->consumerConnect(listener, false); sp<MaliciousBQP> malicious = new MaliciousBQP(producer); diff --git a/libs/gui/tests/DummyConsumer.h b/libs/gui/tests/MockConsumer.h index 502bdf981b..4a6c51c17d 100644 --- a/libs/gui/tests/DummyConsumer.h +++ b/libs/gui/tests/MockConsumer.h @@ -18,7 +18,7 @@ namespace android { -struct DummyConsumer : public BnConsumerListener { +struct MockConsumer : public BnConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} diff --git a/libs/gui/tests/StreamSplitter_test.cpp b/libs/gui/tests/StreamSplitter_test.cpp index ad6e051684..b65cddaea3 100644 --- a/libs/gui/tests/StreamSplitter_test.cpp +++ b/libs/gui/tests/StreamSplitter_test.cpp @@ -48,7 +48,7 @@ protected: } }; -struct DummyListener : public BnConsumerListener { +struct FakeListener : public BnConsumerListener { virtual void onFrameAvailable(const BufferItem& /* item */) {} virtual void onBuffersReleased() {} virtual void onSidebandStreamChanged() {} @@ -64,7 +64,7 @@ TEST_F(StreamSplitterTest, OneInputOneOutput) { sp<IGraphicBufferProducer> outputProducer; sp<IGraphicBufferConsumer> outputConsumer; BufferQueue::createBufferQueue(&outputProducer, &outputConsumer); - ASSERT_EQ(OK, outputConsumer->consumerConnect(new DummyListener, false)); + ASSERT_EQ(OK, outputConsumer->consumerConnect(new FakeListener, false)); sp<StreamSplitter> splitter; status_t status = StreamSplitter::createSplitter(inputConsumer, &splitter); @@ -75,8 +75,9 @@ TEST_F(StreamSplitterTest, OneInputOneOutput) { ASSERT_EQ(OK, outputProducer->allowAllocation(false)); IGraphicBufferProducer::QueueBufferOutput qbOutput; - ASSERT_EQ(OK, inputProducer->connect(new DummyProducerListener, - NATIVE_WINDOW_API_CPU, false, &qbOutput)); + ASSERT_EQ(OK, + inputProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, + &qbOutput)); int slot; sp<Fence> fence; @@ -132,8 +133,7 @@ TEST_F(StreamSplitterTest, OneInputMultipleOutputs) { for (int output = 0; output < NUM_OUTPUTS; ++output) { BufferQueue::createBufferQueue(&outputProducers[output], &outputConsumers[output]); - ASSERT_EQ(OK, outputConsumers[output]->consumerConnect( - new DummyListener, false)); + ASSERT_EQ(OK, outputConsumers[output]->consumerConnect(new FakeListener, false)); } sp<StreamSplitter> splitter; @@ -147,8 +147,9 @@ TEST_F(StreamSplitterTest, OneInputMultipleOutputs) { } IGraphicBufferProducer::QueueBufferOutput qbOutput; - ASSERT_EQ(OK, inputProducer->connect(new DummyProducerListener, - NATIVE_WINDOW_API_CPU, false, &qbOutput)); + ASSERT_EQ(OK, + inputProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, + &qbOutput)); int slot; sp<Fence> fence; @@ -203,7 +204,7 @@ TEST_F(StreamSplitterTest, OutputAbandonment) { sp<IGraphicBufferProducer> outputProducer; sp<IGraphicBufferConsumer> outputConsumer; BufferQueue::createBufferQueue(&outputProducer, &outputConsumer); - ASSERT_EQ(OK, outputConsumer->consumerConnect(new DummyListener, false)); + ASSERT_EQ(OK, outputConsumer->consumerConnect(new FakeListener, false)); sp<StreamSplitter> splitter; status_t status = StreamSplitter::createSplitter(inputConsumer, &splitter); @@ -211,8 +212,9 @@ TEST_F(StreamSplitterTest, OutputAbandonment) { ASSERT_EQ(OK, splitter->addOutput(outputProducer)); IGraphicBufferProducer::QueueBufferOutput qbOutput; - ASSERT_EQ(OK, inputProducer->connect(new DummyProducerListener, - NATIVE_WINDOW_API_CPU, false, &qbOutput)); + ASSERT_EQ(OK, + inputProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, + &qbOutput)); int slot; sp<Fence> fence; diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp index c85e84489d..c7458a3755 100644 --- a/libs/gui/tests/SurfaceTextureClient_test.cpp +++ b/libs/gui/tests/SurfaceTextureClient_test.cpp @@ -54,7 +54,7 @@ protected: mANW = mSTC; // We need a valid GL context so we can test updateTexImage() - // This initializes EGL and create a dummy GL context with a + // This initializes EGL and create a GL context placeholder with a // pbuffer render target. mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); ASSERT_EQ(EGL_SUCCESS, eglGetError()); diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 9906166c67..592913c46b 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "DummyConsumer.h" +#include "MockConsumer.h" #include <gtest/gtest.h> @@ -56,12 +56,11 @@ class FakeProducerFrameEventHistory; static constexpr uint64_t NO_FRAME_INDEX = std::numeric_limits<uint64_t>::max(); -class DummySurfaceListener : public SurfaceListener { +class FakeSurfaceListener : public SurfaceListener { public: - DummySurfaceListener(bool enableReleasedCb = false) : - mEnableReleaseCb(enableReleasedCb), - mBuffersReleased(0) {} - virtual ~DummySurfaceListener() = default; + FakeSurfaceListener(bool enableReleasedCb = false) + : mEnableReleaseCb(enableReleasedCb), mBuffersReleased(0) {} + virtual ~FakeSurfaceListener() = default; virtual void onBufferReleased() { mBuffersReleased++; @@ -124,15 +123,15 @@ protected: sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - sp<DummyConsumer> dummyConsumer(new DummyConsumer); - consumer->consumerConnect(dummyConsumer, false); + sp<MockConsumer> mockConsumer(new MockConsumer); + consumer->consumerConnect(mockConsumer, false); consumer->setConsumerName(String8("TestConsumer")); sp<Surface> surface = new Surface(producer); sp<ANativeWindow> window(surface); - sp<DummySurfaceListener> listener; + sp<FakeSurfaceListener> listener; if (hasSurfaceListener) { - listener = new DummySurfaceListener(enableReleasedCb); + listener = new FakeSurfaceListener(enableReleasedCb); } ASSERT_EQ(OK, surface->connect( NATIVE_WINDOW_API_CPU, @@ -381,8 +380,8 @@ TEST_F(SurfaceTest, GetConsumerName) { sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - sp<DummyConsumer> dummyConsumer(new DummyConsumer); - consumer->consumerConnect(dummyConsumer, false); + sp<MockConsumer> mockConsumer(new MockConsumer); + consumer->consumerConnect(mockConsumer, false); consumer->setConsumerName(String8("TestConsumer")); sp<Surface> surface = new Surface(producer); @@ -397,8 +396,8 @@ TEST_F(SurfaceTest, GetWideColorSupport) { sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - sp<DummyConsumer> dummyConsumer(new DummyConsumer); - consumer->consumerConnect(dummyConsumer, false); + sp<MockConsumer> mockConsumer(new MockConsumer); + consumer->consumerConnect(mockConsumer, false); consumer->setConsumerName(String8("TestConsumer")); sp<Surface> surface = new Surface(producer); @@ -428,8 +427,8 @@ TEST_F(SurfaceTest, GetHdrSupport) { sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - sp<DummyConsumer> dummyConsumer(new DummyConsumer); - consumer->consumerConnect(dummyConsumer, false); + sp<MockConsumer> mockConsumer(new MockConsumer); + consumer->consumerConnect(mockConsumer, false); consumer->setConsumerName(String8("TestConsumer")); sp<Surface> surface = new Surface(producer); @@ -452,8 +451,8 @@ TEST_F(SurfaceTest, SetHdrMetadata) { sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - sp<DummyConsumer> dummyConsumer(new DummyConsumer); - consumer->consumerConnect(dummyConsumer, false); + sp<MockConsumer> mockConsumer(new MockConsumer); + consumer->consumerConnect(mockConsumer, false); consumer->setConsumerName(String8("TestConsumer")); sp<Surface> surface = new Surface(producer); @@ -497,8 +496,8 @@ TEST_F(SurfaceTest, DynamicSetBufferCount) { sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - sp<DummyConsumer> dummyConsumer(new DummyConsumer); - consumer->consumerConnect(dummyConsumer, false); + sp<MockConsumer> mockConsumer(new MockConsumer); + consumer->consumerConnect(mockConsumer, false); consumer->setConsumerName(String8("TestConsumer")); sp<Surface> surface = new Surface(producer); @@ -523,13 +522,13 @@ TEST_F(SurfaceTest, GetAndFlushRemovedBuffers) { sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - sp<DummyConsumer> dummyConsumer(new DummyConsumer); - consumer->consumerConnect(dummyConsumer, false); + sp<MockConsumer> mockConsumer(new MockConsumer); + consumer->consumerConnect(mockConsumer, false); consumer->setConsumerName(String8("TestConsumer")); sp<Surface> surface = new Surface(producer); sp<ANativeWindow> window(surface); - sp<DummyProducerListener> listener = new DummyProducerListener(); + sp<StubProducerListener> listener = new StubProducerListener(); ASSERT_EQ(OK, surface->connect( NATIVE_WINDOW_API_CPU, /*listener*/listener, @@ -1910,8 +1909,8 @@ TEST_F(SurfaceTest, DequeueWithConsumerDrivenSize) { sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - sp<DummyConsumer> dummyConsumer(new DummyConsumer); - consumer->consumerConnect(dummyConsumer, false); + sp<MockConsumer> mockConsumer(new MockConsumer); + consumer->consumerConnect(mockConsumer, false); consumer->setDefaultBufferSize(10, 10); sp<Surface> surface = new Surface(producer); @@ -1980,8 +1979,8 @@ TEST_F(SurfaceTest, DefaultMaxBufferCountSetAndUpdated) { sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - sp<DummyConsumer> dummyConsumer(new DummyConsumer); - consumer->consumerConnect(dummyConsumer, false); + sp<MockConsumer> mockConsumer(new MockConsumer); + consumer->consumerConnect(mockConsumer, false); sp<Surface> surface = new Surface(producer); sp<ANativeWindow> window(surface); 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/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp index 92e7e715ea..7c84a19bed 100644 --- a/libs/renderengine/gl/GLESRenderEngine.cpp +++ b/libs/renderengine/gl/GLESRenderEngine.cpp @@ -245,22 +245,22 @@ std::unique_ptr<GLESRenderEngine> GLESRenderEngine::create(const RenderEngineCre // if can't create a GL context, we can only abort. LOG_ALWAYS_FATAL_IF(ctxt == EGL_NO_CONTEXT, "EGLContext creation failed"); - EGLSurface dummy = EGL_NO_SURFACE; + EGLSurface stub = EGL_NO_SURFACE; if (!extensions.hasSurfacelessContext()) { - dummy = createDummyEglPbufferSurface(display, config, args.pixelFormat, - Protection::UNPROTECTED); - LOG_ALWAYS_FATAL_IF(dummy == EGL_NO_SURFACE, "can't create dummy pbuffer"); + stub = createStubEglPbufferSurface(display, config, args.pixelFormat, + Protection::UNPROTECTED); + LOG_ALWAYS_FATAL_IF(stub == EGL_NO_SURFACE, "can't create stub pbuffer"); } - EGLBoolean success = eglMakeCurrent(display, dummy, dummy, ctxt); - LOG_ALWAYS_FATAL_IF(!success, "can't make dummy pbuffer current"); + EGLBoolean success = eglMakeCurrent(display, stub, stub, ctxt); + LOG_ALWAYS_FATAL_IF(!success, "can't make stub pbuffer current"); extensions.initWithGLStrings(glGetString(GL_VENDOR), glGetString(GL_RENDERER), glGetString(GL_VERSION), glGetString(GL_EXTENSIONS)); - EGLSurface protectedDummy = EGL_NO_SURFACE; + EGLSurface protectedStub = EGL_NO_SURFACE; if (protectedContext != EGL_NO_CONTEXT && !extensions.hasSurfacelessContext()) { - protectedDummy = createDummyEglPbufferSurface(display, config, args.pixelFormat, - Protection::PROTECTED); - ALOGE_IF(protectedDummy == EGL_NO_SURFACE, "can't create protected dummy pbuffer"); + protectedStub = createStubEglPbufferSurface(display, config, args.pixelFormat, + Protection::PROTECTED); + ALOGE_IF(protectedStub == EGL_NO_SURFACE, "can't create protected stub pbuffer"); } // now figure out what version of GL did we actually get @@ -278,8 +278,8 @@ std::unique_ptr<GLESRenderEngine> GLESRenderEngine::create(const RenderEngineCre break; case GLES_VERSION_2_0: case GLES_VERSION_3_0: - engine = std::make_unique<GLESRenderEngine>(args, display, config, ctxt, dummy, - protectedContext, protectedDummy); + engine = std::make_unique<GLESRenderEngine>(args, display, config, ctxt, stub, + protectedContext, protectedStub); break; } @@ -334,15 +334,15 @@ EGLConfig GLESRenderEngine::chooseEglConfig(EGLDisplay display, int format, bool } GLESRenderEngine::GLESRenderEngine(const RenderEngineCreationArgs& args, EGLDisplay display, - EGLConfig config, EGLContext ctxt, EGLSurface dummy, - EGLContext protectedContext, EGLSurface protectedDummy) + EGLConfig config, EGLContext ctxt, EGLSurface stub, + EGLContext protectedContext, EGLSurface protectedStub) : renderengine::impl::RenderEngine(args), mEGLDisplay(display), mEGLConfig(config), mEGLContext(ctxt), - mDummySurface(dummy), + mStubSurface(stub), mProtectedEGLContext(protectedContext), - mProtectedDummySurface(protectedDummy), + mProtectedStubSurface(protectedStub), mVpWidth(0), mVpHeight(0), mFramebufferImageCacheSize(args.imageCacheSize), @@ -355,12 +355,12 @@ GLESRenderEngine::GLESRenderEngine(const RenderEngineCreationArgs& args, EGLDisp // Initialize protected EGL Context. if (mProtectedEGLContext != EGL_NO_CONTEXT) { - EGLBoolean success = eglMakeCurrent(display, mProtectedDummySurface, mProtectedDummySurface, + EGLBoolean success = eglMakeCurrent(display, mProtectedStubSurface, mProtectedStubSurface, mProtectedEGLContext); ALOGE_IF(!success, "can't make protected context current"); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei(GL_PACK_ALIGNMENT, 4); - success = eglMakeCurrent(display, mDummySurface, mDummySurface, mEGLContext); + success = eglMakeCurrent(display, mStubSurface, mStubSurface, mEGLContext); LOG_ALWAYS_FATAL_IF(!success, "can't make default context current"); } @@ -896,7 +896,7 @@ bool GLESRenderEngine::cleanupPostRender() { return false; } - // Bind the texture to dummy data so that backing image data can be freed. + // Bind the texture to placeholder so that backing image data can be freed. GLFramebuffer* glFramebuffer = static_cast<GLFramebuffer*>(getFramebufferForDrawing()); glFramebuffer->allocateBuffers(1, 1, mPlaceholderDrawBuffer); // Release the cached fence here, so that we don't churn reallocations when @@ -934,7 +934,7 @@ bool GLESRenderEngine::useProtectedContext(bool useProtectedContext) { if (useProtectedContext && mProtectedEGLContext == EGL_NO_CONTEXT) { return false; } - const EGLSurface surface = useProtectedContext ? mProtectedDummySurface : mDummySurface; + const EGLSurface surface = useProtectedContext ? mProtectedStubSurface : mStubSurface; const EGLContext context = useProtectedContext ? mProtectedEGLContext : mEGLContext; const bool success = eglMakeCurrent(mEGLDisplay, surface, surface, context) == EGL_TRUE; if (success) { @@ -1562,11 +1562,11 @@ EGLContext GLESRenderEngine::createEglContext(EGLDisplay display, EGLConfig conf return context; } -EGLSurface GLESRenderEngine::createDummyEglPbufferSurface(EGLDisplay display, EGLConfig config, - int hwcFormat, Protection protection) { - EGLConfig dummyConfig = config; - if (dummyConfig == EGL_NO_CONFIG) { - dummyConfig = chooseEglConfig(display, hwcFormat, /*logConfig*/ true); +EGLSurface GLESRenderEngine::createStubEglPbufferSurface(EGLDisplay display, EGLConfig config, + int hwcFormat, Protection protection) { + EGLConfig stubConfig = config; + if (stubConfig == EGL_NO_CONFIG) { + stubConfig = chooseEglConfig(display, hwcFormat, /*logConfig*/ true); } std::vector<EGLint> attributes; attributes.reserve(7); @@ -1580,7 +1580,7 @@ EGLSurface GLESRenderEngine::createDummyEglPbufferSurface(EGLDisplay display, EG } attributes.push_back(EGL_NONE); - return eglCreatePbufferSurface(display, dummyConfig, attributes.data()); + return eglCreatePbufferSurface(display, stubConfig, attributes.data()); } bool GLESRenderEngine::isHdrDataSpace(const Dataspace dataSpace) const { diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h index 42b8537b94..61986ff721 100644 --- a/libs/renderengine/gl/GLESRenderEngine.h +++ b/libs/renderengine/gl/GLESRenderEngine.h @@ -53,8 +53,8 @@ public: static std::unique_ptr<GLESRenderEngine> create(const RenderEngineCreationArgs& args); GLESRenderEngine(const RenderEngineCreationArgs& args, EGLDisplay display, EGLConfig config, - EGLContext ctxt, EGLSurface dummy, EGLContext protectedContext, - EGLSurface protectedDummy); + EGLContext ctxt, EGLSurface stub, EGLContext protectedContext, + EGLSurface protectedStub); ~GLESRenderEngine() override EXCLUDES(mRenderingMutex); void primeCache() const override; @@ -115,8 +115,8 @@ private: static EGLContext createEglContext(EGLDisplay display, EGLConfig config, EGLContext shareContext, bool useContextPriority, Protection protection); - static EGLSurface createDummyEglPbufferSurface(EGLDisplay display, EGLConfig config, - int hwcFormat, Protection protection); + static EGLSurface createStubEglPbufferSurface(EGLDisplay display, EGLConfig config, + int hwcFormat, Protection protection); std::unique_ptr<Framebuffer> createFramebuffer(); std::unique_ptr<Image> createImage(); void checkErrors() const; @@ -175,9 +175,9 @@ private: EGLDisplay mEGLDisplay; EGLConfig mEGLConfig; EGLContext mEGLContext; - EGLSurface mDummySurface; + EGLSurface mStubSurface; EGLContext mProtectedEGLContext; - EGLSurface mProtectedDummySurface; + EGLSurface mProtectedStubSurface; GLint mMaxViewportDims[2]; GLint mMaxTextureSize; GLuint mVpWidth; diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp index 16a8a0decb..50e5550e06 100644 --- a/libs/renderengine/tests/RenderEngineTest.cpp +++ b/libs/renderengine/tests/RenderEngineTest.cpp @@ -926,7 +926,7 @@ void RenderEngineTest::clearLeftRegion() { settings.clip = Rect(4, 4); settings.clearRegion = Region(Rect(2, 4)); std::vector<const renderengine::LayerSettings*> layers; - // dummy layer, without bounds should not render anything + // fake layer, without bounds should not render anything renderengine::LayerSettings layer; layers.push_back(&layer); invokeDraw(settings, layers, mBuffer); 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/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp index 8cc7081e4f..fab10978d6 100644 --- a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp +++ b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp @@ -108,7 +108,7 @@ class BufferHubQueueProducerTest : public ::testing::Test { void ConnectProducer() { IGraphicBufferProducer::QueueBufferOutput output; // Can connect the first time. - ASSERT_EQ(OK, mProducer->connect(kDummyListener, kTestApi, + ASSERT_EQ(OK, mProducer->connect(kStubListener, kTestApi, kTestControlledByApp, &output)); } @@ -140,7 +140,7 @@ class BufferHubQueueProducerTest : public ::testing::Test { return QueueBufferInputBuilder().build(); } - const sp<IProducerListener> kDummyListener{new DummyProducerListener}; + const sp<IProducerListener> kStubListener{new StubProducerListener}; sp<BufferHubProducer> mProducer; sp<Surface> mSurface; @@ -150,11 +150,11 @@ TEST_F(BufferHubQueueProducerTest, ConnectFirst_ReturnsError) { IGraphicBufferProducer::QueueBufferOutput output; // NULL output returns BAD_VALUE - EXPECT_EQ(BAD_VALUE, mProducer->connect(kDummyListener, kTestApi, + EXPECT_EQ(BAD_VALUE, mProducer->connect(kStubListener, kTestApi, kTestControlledByApp, nullptr)); // Invalid API returns bad value - EXPECT_EQ(BAD_VALUE, mProducer->connect(kDummyListener, kTestApiInvalid, + EXPECT_EQ(BAD_VALUE, mProducer->connect(kStubListener, kTestApiInvalid, kTestControlledByApp, &output)); } @@ -163,7 +163,7 @@ TEST_F(BufferHubQueueProducerTest, ConnectAgain_ReturnsError) { // Can't connect when there is already a producer connected. IGraphicBufferProducer::QueueBufferOutput output; - EXPECT_EQ(BAD_VALUE, mProducer->connect(kDummyListener, kTestApi, + EXPECT_EQ(BAD_VALUE, mProducer->connect(kStubListener, kTestApi, kTestControlledByApp, &output)); } @@ -554,18 +554,18 @@ TEST_F(BufferHubQueueProducerTest, TakeAsParcelable) { ProducerQueueParcelable producer_parcelable; EXPECT_EQ(mProducer->TakeAsParcelable(&producer_parcelable), BAD_VALUE); - // Create a valid dummy producer parcelable. - auto dummy_channel_parcelable = + // Create a valid fake producer parcelable. + auto fake_channel_parcelable = std::make_unique<pdx::default_transport::ChannelParcelable>( LocalHandle(0), LocalHandle(0), LocalHandle(0)); - EXPECT_TRUE(dummy_channel_parcelable->IsValid()); - ProducerQueueParcelable dummy_producer_parcelable( - std::move(dummy_channel_parcelable)); - EXPECT_TRUE(dummy_producer_parcelable.IsValid()); + EXPECT_TRUE(fake_channel_parcelable->IsValid()); + ProducerQueueParcelable fake_producer_parcelable( + std::move(fake_channel_parcelable)); + EXPECT_TRUE(fake_producer_parcelable.IsValid()); // Disconnect producer can be taken out, but only to an invalid parcelable. ASSERT_EQ(mProducer->disconnect(kTestApi), OK); - EXPECT_EQ(mProducer->TakeAsParcelable(&dummy_producer_parcelable), BAD_VALUE); + EXPECT_EQ(mProducer->TakeAsParcelable(&fake_producer_parcelable), BAD_VALUE); EXPECT_FALSE(producer_parcelable.IsValid()); EXPECT_EQ(mProducer->TakeAsParcelable(&producer_parcelable), OK); EXPECT_TRUE(producer_parcelable.IsValid()); @@ -583,7 +583,7 @@ TEST_F(BufferHubQueueProducerTest, TakeAsParcelable) { // But connect to API will fail. IGraphicBufferProducer::QueueBufferOutput output; - EXPECT_EQ(mProducer->connect(kDummyListener, kTestApi, kTestControlledByApp, + EXPECT_EQ(mProducer->connect(kStubListener, kTestApi, kTestControlledByApp, &output), BAD_VALUE); @@ -592,8 +592,8 @@ TEST_F(BufferHubQueueProducerTest, TakeAsParcelable) { sp<BufferHubProducer> new_producer = BufferHubProducer::Create(std::move(producer_parcelable)); ASSERT_TRUE(new_producer != nullptr); - EXPECT_EQ(new_producer->connect(kDummyListener, kTestApi, - kTestControlledByApp, &output), + EXPECT_EQ(new_producer->connect(kStubListener, kTestApi, kTestControlledByApp, + &output), OK); } 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/encoder_performance_test.cpp b/libs/vr/libpdx/encoder_performance_test.cpp index b7d94b3471..7b477c4ce2 100644 --- a/libs/vr/libpdx/encoder_performance_test.cpp +++ b/libs/vr/libpdx/encoder_performance_test.cpp @@ -158,12 +158,12 @@ std::chrono::nanoseconds SerializeBaseTest(MessageWriter* writer, size_t iterations, ResetFunc* write_reset, void* reset_data, size_t data_size) { - std::vector<uint8_t> dummy_data(data_size); + std::vector<uint8_t> fake_data(data_size); auto start = std::chrono::high_resolution_clock::now(); for (size_t i = 0; i < iterations; i++) { write_reset(reset_data); - memcpy(writer->GetNextWriteBufferSection(dummy_data.size()), - dummy_data.data(), dummy_data.size()); + memcpy(writer->GetNextWriteBufferSection(fake_data.size()), + fake_data.data(), fake_data.size()); } auto stop = std::chrono::high_resolution_clock::now(); return stop - start; @@ -177,17 +177,17 @@ std::chrono::nanoseconds DeserializeBaseTest( MessageReader* reader, MessageWriter* writer, size_t iterations, ResetFunc* read_reset, ResetFunc* write_reset, void* reset_data, size_t data_size) { - std::vector<uint8_t> dummy_data(data_size); + std::vector<uint8_t> fake_data(data_size); write_reset(reset_data); - memcpy(writer->GetNextWriteBufferSection(dummy_data.size()), - dummy_data.data(), dummy_data.size()); + memcpy(writer->GetNextWriteBufferSection(fake_data.size()), fake_data.data(), + fake_data.size()); auto start = std::chrono::high_resolution_clock::now(); for (size_t i = 0; i < iterations; i++) { read_reset(reset_data); auto section = reader->GetNextReadBufferSection(); - memcpy(dummy_data.data(), section.first, dummy_data.size()); + memcpy(fake_data.data(), section.first, fake_data.size()); reader->ConsumeReadBufferSectionData( - AdvancePointer(section.first, dummy_data.size())); + AdvancePointer(section.first, fake_data.size())); } auto stop = std::chrono::high_resolution_clock::now(); return stop - start; diff --git a/libs/vr/libpdx/fuzz/Android.bp b/libs/vr/libpdx/fuzz/Android.bp new file mode 100644 index 0000000000..b36e0deea0 --- /dev/null +++ b/libs/vr/libpdx/fuzz/Android.bp @@ -0,0 +1,62 @@ +cc_fuzz { + name: "libpdx_service_dispatcher_fuzzer", + clang: true, + srcs: [ + "service_dispatcher_fuzzer.cpp", + ], + cflags: [ + "-Wall", + "-Wextra", + "-Werror", + ], + static_libs: [ + "libpdx", + ], + shared_libs: [ + "libutils", + "liblog", + "libcutils" + ], +} + +cc_fuzz { + name: "libpdx_message_fuzzer", + clang: true, + srcs: [ + "message_fuzzer.cpp", + ], + cflags: [ + "-Wall", + "-Wextra", + "-Werror", + ], + static_libs: [ + "libpdx", + ], + shared_libs: [ + "libutils", + "liblog", + "libcutils" + ], +} + +cc_fuzz { + name: "libpdx_serialization_fuzzer", + clang: true, + srcs: [ + "serialization_fuzzer.cpp", + ], + cflags: [ + "-Wall", + "-Wextra", + "-Werror", + ], + static_libs: [ + "libpdx", + ], + shared_libs: [ + "libutils", + "liblog", + "libcutils" + ], +} 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/message_fuzzer.cpp b/libs/vr/libpdx/fuzz/message_fuzzer.cpp new file mode 100644 index 0000000000..b627045ab6 --- /dev/null +++ b/libs/vr/libpdx/fuzz/message_fuzzer.cpp @@ -0,0 +1,175 @@ +/* + * 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; + +// Fuzzer for Message object functions. +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + FuzzedDataProvider fdp = FuzzedDataProvider(data, size); + + FuzzEndpoint* endpoint = new FuzzEndpoint(&fdp); + std::shared_ptr<Service> service( + new Service("FuzzService", std::unique_ptr<Endpoint>(endpoint))); + std::shared_ptr<Channel> channel(nullptr); + + // Generate a random Message object to call functions in. + MessageInfo info; + 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.get(); + 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 = Message(info); + + // A bunch of getters that probably won't do much, but might as well + // get coverage, while we are here. + message.GetProcessId(); + message.GetThreadId(); + message.GetEffectiveUserId(); + message.GetEffectiveGroupId(); + message.GetChannelId(); + message.GetMessageId(); + message.GetOp(); + message.GetFlags(); + message.GetSendLength(); + message.GetReceiveLength(); + message.GetFileDescriptorCount(); + message.ImpulseEnd(); + message.replied(); + message.IsChannelExpired(); + message.IsServiceExpired(); + message.GetState(); + message.GetState(); + + // Some misc. functions. + unsigned int fd = fdp.ConsumeIntegral<unsigned int>(); + int clear_mask = fdp.ConsumeIntegral<int>(); + int set_mask = fdp.ConsumeIntegral<int>(); + Status<void> status = {}; + message.ModifyChannelEvents(clear_mask, set_mask); + + // Fuzz the handle functions. + LocalHandle l_handle = {}; + BorrowedHandle b_handle = {}; + RemoteHandle r_handle = {}; + LocalChannelHandle lc_handle = {}; + BorrowedChannelHandle bc_handle = {}; + RemoteChannelHandle rc_handle = {}; + FileReference f_ref = fdp.ConsumeIntegral<int32_t>(); + ChannelReference c_ref = fdp.ConsumeIntegral<int32_t>(); + + // These don't actually modify any state in the Message or params. + // They can be called in any order. + message.PushFileHandle(b_handle); + message.PushFileHandle(r_handle); + message.PushChannelHandle(lc_handle); + message.PushChannelHandle(bc_handle); + message.PushChannelHandle(rc_handle); + message.GetFileHandle(f_ref, &l_handle); + message.GetChannelHandle(c_ref, &lc_handle); + + // Can only reply once, pick at random. + switch (fdp.ConsumeIntegral<uint8_t>()) { + case 0: + message.ReplyFileDescriptor(fd); + break; + case 1: + message.Reply(status); + break; + case 2: + message.Reply(l_handle); + break; + case 3: + message.Reply(b_handle); + break; + case 4: + message.Reply(r_handle); + break; + case 5: + message.Reply(lc_handle); + break; + case 6: + message.Reply(bc_handle); + break; + case 7: + message.Reply(rc_handle); + } + + // Fuzz the channel functions. + int flags = fdp.ConsumeIntegral<int>(); + int channel_id = 0; + message.PushChannel(flags, channel, &channel_id); + message.CheckChannel(service.get(), c_ref, &channel); + message.CheckChannel(c_ref, &channel); + message.PushChannel(service.get(), flags, channel, &channel_id); + size_t iovec_size = sizeof(iovec); + struct iovec* iovecs = nullptr; + + // Fuzz the read/write functions. Needs at least one iovec, plus one byte. + if (fdp.remaining_bytes() >= iovec_size + 1) { + std::vector<uint8_t> tmp_vec = fdp.ConsumeBytes<uint8_t>(iovec_size); + struct iovec* vector = reinterpret_cast<struct iovec*>(tmp_vec.data()); + std::vector<uint8_t> tmp_buf = + fdp.ConsumeBytes<uint8_t>(fdp.remaining_bytes()); + void* buf = reinterpret_cast<void*>(tmp_buf.data()); + size_t buf_size = fdp.ConsumeIntegral<size_t>(); + + // Capping num_vecs to 1024 so it doesn't allocate too much memory. + size_t num_vecs = fdp.ConsumeIntegralInRange<size_t>(0, 1024); + + if (num_vecs > 0) + iovecs = new struct iovec[num_vecs]; + for (size_t i = 0; i < num_vecs; i++) { + iovecs[i] = *vector; + } + + message.ReadAll(vector, buf_size); + message.WriteAll(buf, buf_size); + message.ReadVectorAll(vector, num_vecs); + message.WriteVectorAll(vector, num_vecs); + message.ReadVector(vector, buf_size); + message.WriteVector(vector, buf_size); + } + + if (iovecs != nullptr) + delete[] iovecs; + return 0; +} diff --git a/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp b/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp new file mode 100644 index 0000000000..afde5f7f32 --- /dev/null +++ b/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp @@ -0,0 +1,111 @@ +/* + * 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 <errno.h> +#include <fcntl.h> +#include <unistd.h> + +#include <memory> +#include <string> +#include <thread> +#include <utility> + +#include <fuzzer/FuzzedDataProvider.h> +#include <pdx/rpc/argument_encoder.h> +#include <pdx/rpc/array_wrapper.h> +#include <pdx/rpc/default_initialization_allocator.h> +#include <pdx/rpc/payload.h> +#include <pdx/rpc/serializable.h> +#include <pdx/rpc/serialization.h> +#include <pdx/rpc/string_wrapper.h> +#include <pdx/utility.h> + +using namespace android::pdx; +using namespace android::pdx::rpc; + +struct FuzzType { + int a; + float b; + std::string c; + + FuzzType() {} + FuzzType(int a, float b, const std::string& c) : a(a), b(b), c(c) {} + + private: + PDX_SERIALIZABLE_MEMBERS(FuzzType, a, b, c); +}; + +// Fuzzer for Serialization operations, this is mostly just lifted from the +// existing test cases to use fuzzed values as inputs. +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + FuzzedDataProvider fdp = FuzzedDataProvider(data, size); + Payload result; + + // Currently, only fuzzing subset of types. In the future, may want + // to add more difficult to generate types like array, map, enum, etc... + bool b_val = fdp.ConsumeBool(); + uint8_t u8_val = fdp.ConsumeIntegral<uint8_t>(); + uint16_t u16_val = fdp.ConsumeIntegral<uint16_t>(); + uint32_t u32_val = fdp.ConsumeIntegral<uint32_t>(); + uint64_t u64_val = fdp.ConsumeIntegral<uint64_t>(); + int8_t i8_val = fdp.ConsumeIntegral<int8_t>(); + int16_t i16_val = fdp.ConsumeIntegral<uint16_t>(); + int32_t i32_val = fdp.ConsumeIntegral<uint32_t>(); + int64_t i64_val = fdp.ConsumeIntegral<uint64_t>(); + float f_val = fdp.ConsumeFloatingPoint<float>(); + double d_val = fdp.ConsumeFloatingPoint<double>(); + std::string s_val = fdp.ConsumeRandomLengthString(fdp.remaining_bytes()); + std::vector<uint8_t> vec_val = + fdp.ConsumeBytes<uint8_t>(fdp.remaining_bytes()); + FuzzType t1_val{reinterpret_cast<int>(i32_val), f_val, s_val}; + + // Types need to be individually fuzzed because code path changes depending + // on which type is being serialized/deserialized. + Serialize(b_val, &result); + Deserialize(&b_val, &result); + Serialize(u8_val, &result); + Deserialize(&u8_val, &result); + Serialize(u16_val, &result); + Deserialize(&u16_val, &result); + Serialize(u32_val, &result); + Deserialize(&u32_val, &result); + Serialize(u64_val, &result); + Deserialize(&u64_val, &result); + Serialize(i8_val, &result); + Deserialize(&i8_val, &result); + Serialize(i16_val, &result); + Deserialize(&i16_val, &result); + Serialize(i32_val, &result); + Deserialize(&i32_val, &result); + Serialize(i64_val, &result); + Deserialize(&i64_val, &result); + Serialize(f_val, &result); + Deserialize(&f_val, &result); + Serialize(d_val, &result); + Deserialize(&d_val, &result); + Serialize(s_val, &result); + Deserialize(&s_val, &result); + Serialize(WrapString(s_val), &result); + Deserialize(&s_val, &result); + Serialize(vec_val, &result); + Deserialize(&vec_val, &result); + Serialize(t1_val, &result); + Deserialize(&t1_val, &result); + + return 0; +} 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/libs/vr/libpdx/private/pdx/rpc/macros.h b/libs/vr/libpdx/private/pdx/rpc/macros.h index aeae9d3e5e..99325b5d65 100644 --- a/libs/vr/libpdx/private/pdx/rpc/macros.h +++ b/libs/vr/libpdx/private/pdx/rpc/macros.h @@ -28,7 +28,7 @@ // Clears any remaining contents wrapped in parentheses. #define _PDX_CLEAR(...) -// Introduces a first dummy argument and _PDX_CLEAR as second argument. +// Introduces a first stub argument and _PDX_CLEAR as second argument. #define _PDX_CLEAR_IF_LAST() _, _PDX_CLEAR // Returns the first argument of a list. @@ -45,7 +45,7 @@ // Returns next_func if the next element is not (), or _PDX_CLEAR // otherwise. // -// _PDX_CLEAR_IF_LAST inserts an extra first dummy argument if peek is (). +// _PDX_CLEAR_IF_LAST inserts an extra first stub argument if peek is (). #define _PDX_NEXT_FUNC(next_element, next_func) \ _PDX_EXPAND_NEXT_FUNC(_PDX_CLEAR_IF_LAST next_element, next_func) diff --git a/libs/vr/libpdx/service_dispatcher.cpp b/libs/vr/libpdx/service_dispatcher.cpp index b112fa30eb..ba0d69c178 100644 --- a/libs/vr/libpdx/service_dispatcher.cpp +++ b/libs/vr/libpdx/service_dispatcher.cpp @@ -92,9 +92,9 @@ int ServiceDispatcher::RemoveService(const std::shared_ptr<Service>& service) { if (thread_count_ > 0) return -EBUSY; - epoll_event dummy; // See BUGS in man 2 epoll_ctl. + epoll_event ee; // See BUGS in man 2 epoll_ctl. if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_DEL, service->endpoint()->epoll_fd(), - &dummy) < 0) { + &ee) < 0) { ALOGE("Failed to remove service from dispatcher because: %s\n", strerror(errno)); return -errno; diff --git a/libs/vr/libpdx_uds/service_endpoint.cpp b/libs/vr/libpdx_uds/service_endpoint.cpp index 9bc70ea9c0..810eb196ca 100644 --- a/libs/vr/libpdx_uds/service_endpoint.cpp +++ b/libs/vr/libpdx_uds/service_endpoint.cpp @@ -334,8 +334,8 @@ Status<void> Endpoint::CloseChannelLocked(int32_t channel_id) { int channel_fd = iter->second.data_fd.Get(); Status<void> status; - epoll_event dummy; // See BUGS in man 2 epoll_ctl. - if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_DEL, channel_fd, &dummy) < 0) { + epoll_event ee; // See BUGS in man 2 epoll_ctl. + if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_DEL, channel_fd, &ee) < 0) { status.SetError(errno); ALOGE( "Endpoint::CloseChannelLocked: Failed to remove channel from endpoint: " diff --git a/libs/vr/libvrflinger/epoll_event_dispatcher.cpp b/libs/vr/libvrflinger/epoll_event_dispatcher.cpp index 1cf5f17f62..0d5eb8080f 100644 --- a/libs/vr/libvrflinger/epoll_event_dispatcher.cpp +++ b/libs/vr/libvrflinger/epoll_event_dispatcher.cpp @@ -68,8 +68,8 @@ pdx::Status<void> EpollEventDispatcher::RemoveEventHandler(int fd) { ALOGD_IF(TRACE, "EpollEventDispatcher::RemoveEventHandler: fd=%d", fd); std::lock_guard<std::mutex> lock(lock_); - epoll_event dummy; // See BUGS in man 2 epoll_ctl. - if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_DEL, fd, &dummy) < 0) { + epoll_event ee; // See BUGS in man 2 epoll_ctl. + if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_DEL, fd, &ee) < 0) { const int error = errno; ALOGE("Failed to remove fd from epoll set because: %s", strerror(error)); return pdx::ErrorStatus(error); diff --git a/opengl/libs/EGL/BlobCache.cpp b/opengl/libs/EGL/BlobCache.cpp index 74fb0194f9..a27c09f0fe 100644 --- a/opengl/libs/EGL/BlobCache.cpp +++ b/opengl/libs/EGL/BlobCache.cpp @@ -78,12 +78,12 @@ void BlobCache::set(const void* key, size_t keySize, const void* value, return; } - std::shared_ptr<Blob> dummyKey(new Blob(key, keySize, false)); - CacheEntry dummyEntry(dummyKey, nullptr); + std::shared_ptr<Blob> cacheKey(new Blob(key, keySize, false)); + CacheEntry cacheEntry(cacheKey, nullptr); while (true) { - auto index = std::lower_bound(mCacheEntries.begin(), mCacheEntries.end(), dummyEntry); - if (index == mCacheEntries.end() || dummyEntry < *index) { + auto index = std::lower_bound(mCacheEntries.begin(), mCacheEntries.end(), cacheEntry); + if (index == mCacheEntries.end() || cacheEntry < *index) { // Create a new cache entry. std::shared_ptr<Blob> keyBlob(new Blob(key, keySize, true)); std::shared_ptr<Blob> valueBlob(new Blob(value, valueSize, true)); @@ -138,10 +138,10 @@ size_t BlobCache::get(const void* key, size_t keySize, void* value, keySize, mMaxKeySize); return 0; } - std::shared_ptr<Blob> dummyKey(new Blob(key, keySize, false)); - CacheEntry dummyEntry(dummyKey, nullptr); - auto index = std::lower_bound(mCacheEntries.begin(), mCacheEntries.end(), dummyEntry); - if (index == mCacheEntries.end() || dummyEntry < *index) { + std::shared_ptr<Blob> cacheKey(new Blob(key, keySize, false)); + CacheEntry cacheEntry(cacheKey, nullptr); + auto index = std::lower_bound(mCacheEntries.begin(), mCacheEntries.end(), cacheEntry); + if (index == mCacheEntries.end() || cacheEntry < *index) { ALOGV("get: no cache entry found for key of size %zu", keySize); return 0; } diff --git a/opengl/libs/EGL/FileBlobCache.cpp b/opengl/libs/EGL/FileBlobCache.cpp index cc42ac7fef..751f3be81a 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$"; @@ -68,7 +70,7 @@ FileBlobCache::FileBlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxT return; } - // Sanity check the size before trying to mmap it. + // Check the size before trying to mmap it. size_t fileSize = statBuf.st_size; if (fileSize > mMaxTotalSize * 2) { ALOGE("cache file is too large: %#" PRIx64, diff --git a/opengl/tests/EGLTest/EGL_test.cpp b/opengl/tests/EGLTest/EGL_test.cpp index 510226d051..bbd786d155 100644 --- a/opengl/tests/EGLTest/EGL_test.cpp +++ b/opengl/tests/EGLTest/EGL_test.cpp @@ -138,7 +138,7 @@ TEST_F(EGLTest, EGLTerminateSucceedsWithRemainingObjects) { }; EXPECT_TRUE(eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs)); - struct DummyConsumer : public BnConsumerListener { + struct MockConsumer : public BnConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -148,7 +148,7 @@ TEST_F(EGLTest, EGLTerminateSucceedsWithRemainingObjects) { sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - consumer->consumerConnect(new DummyConsumer, false); + consumer->consumerConnect(new MockConsumer, false); sp<Surface> mSTC = new Surface(producer); sp<ANativeWindow> mANW = mSTC; @@ -258,7 +258,7 @@ TEST_F(EGLTest, EGLDisplayP3) { EXPECT_EQ(components[2], 8); EXPECT_EQ(components[3], 8); - struct DummyConsumer : public BnConsumerListener { + struct MockConsumer : public BnConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -268,7 +268,7 @@ TEST_F(EGLTest, EGLDisplayP3) { sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - consumer->consumerConnect(new DummyConsumer, false); + consumer->consumerConnect(new MockConsumer, false); sp<Surface> mSTC = new Surface(producer); sp<ANativeWindow> mANW = mSTC; EGLint winAttrs[] = { @@ -306,7 +306,7 @@ TEST_F(EGLTest, EGLDisplayP3Passthrough) { get8BitConfig(config); - struct DummyConsumer : public BnConsumerListener { + struct MockConsumer : public BnConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -316,7 +316,7 @@ TEST_F(EGLTest, EGLDisplayP3Passthrough) { sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - consumer->consumerConnect(new DummyConsumer, false); + consumer->consumerConnect(new MockConsumer, false); sp<Surface> mSTC = new Surface(producer); sp<ANativeWindow> mANW = mSTC; EGLint winAttrs[] = { @@ -398,7 +398,7 @@ TEST_F(EGLTest, EGLDisplayP31010102) { EXPECT_EQ(components[2], 10); EXPECT_EQ(components[3], 2); - struct DummyConsumer : public BnConsumerListener { + struct MockConsumer : public BnConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -408,7 +408,7 @@ TEST_F(EGLTest, EGLDisplayP31010102) { sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - consumer->consumerConnect(new DummyConsumer, false); + consumer->consumerConnect(new MockConsumer, false); sp<Surface> mSTC = new Surface(producer); sp<ANativeWindow> mANW = mSTC; EGLint winAttrs[] = { @@ -570,7 +570,7 @@ TEST_F(EGLTest, EGLBT2020Linear) { ASSERT_NO_FATAL_FAILURE(get8BitConfig(config)); - struct DummyConsumer : public BnConsumerListener { + struct MockConsumer : public BnConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -580,7 +580,7 @@ TEST_F(EGLTest, EGLBT2020Linear) { sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - consumer->consumerConnect(new DummyConsumer, false); + consumer->consumerConnect(new MockConsumer, false); sp<Surface> mSTC = new Surface(producer); sp<ANativeWindow> mANW = mSTC; @@ -622,7 +622,7 @@ TEST_F(EGLTest, EGLBT2020PQ) { ASSERT_NO_FATAL_FAILURE(get8BitConfig(config)); - struct DummyConsumer : public BnConsumerListener { + struct MockConsumer : public BnConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -632,7 +632,7 @@ TEST_F(EGLTest, EGLBT2020PQ) { sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - consumer->consumerConnect(new DummyConsumer, false); + consumer->consumerConnect(new MockConsumer, false); sp<Surface> mSTC = new Surface(producer); sp<ANativeWindow> mANW = mSTC; std::vector<EGLint> winAttrs; @@ -705,7 +705,7 @@ TEST_F(EGLTest, EGLConfigFP16) { EXPECT_GE(components[2], 16); EXPECT_GE(components[3], 16); - struct DummyConsumer : public BnConsumerListener { + struct MockConsumer : public BnConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -714,7 +714,7 @@ TEST_F(EGLTest, EGLConfigFP16) { sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - consumer->consumerConnect(new DummyConsumer, false); + consumer->consumerConnect(new MockConsumer, false); sp<Surface> mSTC = new Surface(producer); sp<ANativeWindow> mANW = mSTC; @@ -734,7 +734,7 @@ TEST_F(EGLTest, EGLNoConfigContext) { ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_KHR_no_config_context")); - struct DummyConsumer : public BnConsumerListener { + struct MockConsumer : public BnConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -809,7 +809,7 @@ TEST_F(EGLTest, EGLConfig1010102) { EXPECT_EQ(components[2], 10); EXPECT_EQ(components[3], 2); - struct DummyConsumer : public BnConsumerListener { + struct MockConsumer : public BnConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -819,7 +819,7 @@ TEST_F(EGLTest, EGLConfig1010102) { sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - consumer->consumerConnect(new DummyConsumer, false); + consumer->consumerConnect(new MockConsumer, false); sp<Surface> mSTC = new Surface(producer); sp<ANativeWindow> mANW = mSTC; @@ -835,7 +835,7 @@ TEST_F(EGLTest, EGLInvalidColorspaceAttribute) { ASSERT_NO_FATAL_FAILURE(get8BitConfig(config)); - struct DummyConsumer : public BnConsumerListener { + struct MockConsumer : public BnConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -845,7 +845,7 @@ TEST_F(EGLTest, EGLInvalidColorspaceAttribute) { sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - consumer->consumerConnect(new DummyConsumer, false); + consumer->consumerConnect(new MockConsumer, false); sp<Surface> mSTC = new Surface(producer); sp<ANativeWindow> mANW = mSTC; @@ -882,7 +882,7 @@ TEST_F(EGLTest, EGLUnsupportedColorspaceFormatCombo) { ASSERT_EQ(EGL_UNSIGNED_TRUE, success); ASSERT_EQ(1, numConfigs); - struct DummyConsumer : public BnConsumerListener { + struct MockConsumer : public BnConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -892,7 +892,7 @@ TEST_F(EGLTest, EGLUnsupportedColorspaceFormatCombo) { sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - consumer->consumerConnect(new DummyConsumer, false); + consumer->consumerConnect(new MockConsumer, false); sp<Surface> mSTC = new Surface(producer); sp<ANativeWindow> mANW = mSTC; @@ -913,7 +913,7 @@ TEST_F(EGLTest, EGLCreateWindowFailAndSucceed) { ASSERT_NO_FATAL_FAILURE(get8BitConfig(config)); - struct DummyConsumer : public BnConsumerListener { + struct MockConsumer : public BnConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -923,7 +923,7 @@ TEST_F(EGLTest, EGLCreateWindowFailAndSucceed) { sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - consumer->consumerConnect(new DummyConsumer, false); + consumer->consumerConnect(new MockConsumer, false); sp<Surface> mSTC = new Surface(producer); sp<ANativeWindow> mANW = mSTC; @@ -953,7 +953,7 @@ TEST_F(EGLTest, EGLCreateWindowTwoColorspaces) { ASSERT_NO_FATAL_FAILURE(get8BitConfig(config)); - struct DummyConsumer : public BnConsumerListener { + struct MockConsumer : public BnConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} @@ -963,7 +963,7 @@ TEST_F(EGLTest, EGLCreateWindowTwoColorspaces) { sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); - consumer->consumerConnect(new DummyConsumer, false); + consumer->consumerConnect(new MockConsumer, false); sp<Surface> mSTC = new Surface(producer); sp<ANativeWindow> mANW = mSTC; 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..7fd9c3a735 100755 --- a/opengl/tools/glgen/gen +++ b/opengl/tools/glgen/gen @@ -1,11 +1,23 @@ #!/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 -# Create dummy Java files for Android APIs that are used by the code we generate. +# Create stub Java files for Android APIs that are used by the code we generate. # This allows us to test the generated code without building the rest of Android. mkdir -p out/javax/microedition/khronos/opengles @@ -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/egl/EGL14cHeader.cpp b/opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp index 93203fd529..b2ea041cd5 100644 --- a/opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp +++ b/opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp @@ -20,7 +20,7 @@ #pragma GCC diagnostic ignored "-Wunused-function" #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <android_runtime/android_view_Surface.h> #include <android_runtime/android_graphics_SurfaceTexture.h> diff --git a/opengl/tools/glgen/stubs/egl/EGL15cHeader.cpp b/opengl/tools/glgen/stubs/egl/EGL15cHeader.cpp index 34cb3e1a99..6dffac5945 100644 --- a/opengl/tools/glgen/stubs/egl/EGL15cHeader.cpp +++ b/opengl/tools/glgen/stubs/egl/EGL15cHeader.cpp @@ -20,7 +20,7 @@ #pragma GCC diagnostic ignored "-Wunused-function" #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <utils/misc.h> diff --git a/opengl/tools/glgen/stubs/egl/EGLExtcHeader.cpp b/opengl/tools/glgen/stubs/egl/EGLExtcHeader.cpp index b3b069082a..be8b3e3977 100644 --- a/opengl/tools/glgen/stubs/egl/EGLExtcHeader.cpp +++ b/opengl/tools/glgen/stubs/egl/EGLExtcHeader.cpp @@ -20,7 +20,7 @@ #pragma GCC diagnostic ignored "-Wunused-function" #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <android_runtime/android_view_Surface.h> #include <android_runtime/android_graphics_SurfaceTexture.h> diff --git a/opengl/tools/glgen/stubs/gles11/common.cpp b/opengl/tools/glgen/stubs/gles11/common.cpp index e763b4e983..d84a693e6c 100644 --- a/opengl/tools/glgen/stubs/gles11/common.cpp +++ b/opengl/tools/glgen/stubs/gles11/common.cpp @@ -1,5 +1,5 @@ #include <jni.h> -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <utils/misc.h> #include <assert.h> diff --git a/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp b/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp index c12efc3795..9cab1d6a59 100644 --- a/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp +++ b/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp @@ -20,7 +20,7 @@ #pragma GCC diagnostic ignored "-Wunused-function" #include "jni.h" -#include <nativehelper/JNIHelp.h> +#include <nativehelper/JNIPlatformHelp.h> #include <android_runtime/AndroidRuntime.h> #include <utils/misc.h> 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/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h index f8d535152e..0fa878759b 100644 --- a/services/inputflinger/include/InputReaderBase.h +++ b/services/inputflinger/include/InputReaderBase.h @@ -335,7 +335,8 @@ public: virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) = 0; /* Gets a pointer controller associated with the specified cursor device (ie. a mouse). */ - virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId) = 0; + virtual std::shared_ptr<PointerControllerInterface> obtainPointerController( + int32_t deviceId) = 0; /* Notifies the input reader policy that some input devices have changed * and provides information about all current input devices. diff --git a/services/inputflinger/include/PointerControllerInterface.h b/services/inputflinger/include/PointerControllerInterface.h index 194c66547f..85d7247915 100644 --- a/services/inputflinger/include/PointerControllerInterface.h +++ b/services/inputflinger/include/PointerControllerInterface.h @@ -33,7 +33,7 @@ namespace android { * The pointer controller is responsible for providing synchronization and for tracking * display orientation changes if needed. */ -class PointerControllerInterface : public virtual RefBase { +class PointerControllerInterface { protected: PointerControllerInterface() { } virtual ~PointerControllerInterface() { } @@ -59,11 +59,11 @@ public: /* Gets the absolute location of the pointer. */ virtual void getPosition(float* outX, float* outY) const = 0; - enum Transition { + enum class Transition { // Fade/unfade immediately. - TRANSITION_IMMEDIATE, + IMMEDIATE, // Fade/unfade gradually. - TRANSITION_GRADUAL, + GRADUAL, }; /* Fades the pointer out now. */ @@ -75,11 +75,11 @@ public: * wants to ensure that the pointer becomes visible again. */ virtual void unfade(Transition transition) = 0; - enum Presentation { + enum class Presentation { // Show the mouse pointer. - PRESENTATION_POINTER, + POINTER, // Show spots and a spot anchor in place of the mouse pointer. - PRESENTATION_SPOT, + SPOT, }; /* Sets the mode of the pointer controller. */ diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp index 657a134865..06e374353c 100644 --- a/services/inputflinger/reader/InputReader.cpp +++ b/services/inputflinger/reader/InputReader.cpp @@ -390,8 +390,9 @@ bool InputReader::shouldDropVirtualKeyLocked(nsecs_t now, int32_t keyCode, int32 } } -sp<PointerControllerInterface> InputReader::getPointerControllerLocked(int32_t deviceId) { - sp<PointerControllerInterface> controller = mPointerController.promote(); +std::shared_ptr<PointerControllerInterface> InputReader::getPointerControllerLocked( + int32_t deviceId) { + std::shared_ptr<PointerControllerInterface> controller = mPointerController.lock(); if (controller == nullptr) { controller = mPolicy->obtainPointerController(deviceId); mPointerController = controller; @@ -401,7 +402,7 @@ sp<PointerControllerInterface> InputReader::getPointerControllerLocked(int32_t d } void InputReader::updatePointerDisplayLocked() { - sp<PointerControllerInterface> controller = mPointerController.promote(); + std::shared_ptr<PointerControllerInterface> controller = mPointerController.lock(); if (controller == nullptr) { return; } @@ -424,9 +425,9 @@ void InputReader::updatePointerDisplayLocked() { } void InputReader::fadePointerLocked() { - sp<PointerControllerInterface> controller = mPointerController.promote(); + std::shared_ptr<PointerControllerInterface> controller = mPointerController.lock(); if (controller != nullptr) { - controller->fade(PointerControllerInterface::TRANSITION_GRADUAL); + controller->fade(PointerControllerInterface::Transition::GRADUAL); } } @@ -725,7 +726,8 @@ void InputReader::ContextImpl::fadePointer() { mReader->fadePointerLocked(); } -sp<PointerControllerInterface> InputReader::ContextImpl::getPointerController(int32_t deviceId) { +std::shared_ptr<PointerControllerInterface> InputReader::ContextImpl::getPointerController( + int32_t deviceId) { // lock is already held by the input loop return mReader->getPointerControllerLocked(deviceId); } diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h index 693ec30b7d..108b9c236c 100644 --- a/services/inputflinger/reader/include/InputReader.h +++ b/services/inputflinger/reader/include/InputReader.h @@ -17,19 +17,20 @@ #ifndef _UI_INPUTREADER_INPUT_READER_H #define _UI_INPUTREADER_INPUT_READER_H -#include "EventHub.h" -#include "InputListener.h" -#include "InputReaderBase.h" -#include "InputReaderContext.h" -#include "InputThread.h" - #include <PointerControllerInterface.h> #include <utils/Condition.h> #include <utils/Mutex.h> +#include <memory> #include <unordered_map> #include <vector> +#include "EventHub.h" +#include "InputListener.h" +#include "InputReaderBase.h" +#include "InputReaderContext.h" +#include "InputThread.h" + namespace android { class InputDevice; @@ -104,7 +105,8 @@ protected: virtual void disableVirtualKeysUntil(nsecs_t time) override; virtual bool shouldDropVirtualKey(nsecs_t now, int32_t keyCode, int32_t scanCode) override; virtual void fadePointer() override; - virtual sp<PointerControllerInterface> getPointerController(int32_t deviceId) override; + virtual std::shared_ptr<PointerControllerInterface> getPointerController( + int32_t deviceId) override; virtual void requestTimeoutAtTime(nsecs_t when) override; virtual int32_t bumpGeneration() override; virtual void getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) override; @@ -160,8 +162,8 @@ private: void dispatchExternalStylusState(const StylusState& state); // The PointerController that is shared among all the input devices that need it. - wp<PointerControllerInterface> mPointerController; - sp<PointerControllerInterface> getPointerControllerLocked(int32_t deviceId); + std::weak_ptr<PointerControllerInterface> mPointerController; + std::shared_ptr<PointerControllerInterface> getPointerControllerLocked(int32_t deviceId); void updatePointerDisplayLocked(); void fadePointerLocked(); diff --git a/services/inputflinger/reader/include/InputReaderContext.h b/services/inputflinger/reader/include/InputReaderContext.h index 85701e4f63..ffb8d8c44a 100644 --- a/services/inputflinger/reader/include/InputReaderContext.h +++ b/services/inputflinger/reader/include/InputReaderContext.h @@ -46,7 +46,7 @@ public: virtual bool shouldDropVirtualKey(nsecs_t now, int32_t keyCode, int32_t scanCode) = 0; virtual void fadePointer() = 0; - virtual sp<PointerControllerInterface> getPointerController(int32_t deviceId) = 0; + virtual std::shared_ptr<PointerControllerInterface> getPointerController(int32_t deviceId) = 0; virtual void requestTimeoutAtTime(nsecs_t when) = 0; virtual int32_t bumpGeneration() = 0; diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp index 887ab53c76..1a4d5517e2 100644 --- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp +++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp @@ -20,6 +20,7 @@ #include "CursorButtonAccumulator.h" #include "CursorScrollAccumulator.h" +#include "PointerControllerInterface.h" #include "TouchCursorInputMapperCommon.h" namespace android { @@ -154,7 +155,7 @@ void CursorInputMapper::configure(nsecs_t when, const InputReaderConfiguration* mParameters.mode = Parameters::MODE_POINTER_RELATIVE; mSource = AINPUT_SOURCE_MOUSE_RELATIVE; // Keep PointerController around in order to preserve the pointer position. - mPointerController->fade(PointerControllerInterface::TRANSITION_IMMEDIATE); + mPointerController->fade(PointerControllerInterface::Transition::IMMEDIATE); } else { ALOGE("Cannot request pointer capture, device is not in MODE_POINTER"); } @@ -316,7 +317,7 @@ void CursorInputMapper::sync(nsecs_t when) { float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION; if (mSource == AINPUT_SOURCE_MOUSE) { if (moved || scrolled || buttonsChanged) { - mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER); + mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER); if (moved) { mPointerController->move(deltaX, deltaY); @@ -326,7 +327,7 @@ void CursorInputMapper::sync(nsecs_t when) { mPointerController->setButtonState(currentButtonState); } - mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE); + mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE); } mPointerController->getPosition(&xCursorPosition, &yCursorPosition); diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.h b/services/inputflinger/reader/mapper/CursorInputMapper.h index f65ac3934a..05bbb26716 100644 --- a/services/inputflinger/reader/mapper/CursorInputMapper.h +++ b/services/inputflinger/reader/mapper/CursorInputMapper.h @@ -106,7 +106,7 @@ private: int32_t mOrientation; - sp<PointerControllerInterface> mPointerController; + std::shared_ptr<PointerControllerInterface> mPointerController; int32_t mButtonState; nsecs_t mDownTime; diff --git a/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h b/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h index 2a3e2637f1..a86443dee1 100644 --- a/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h +++ b/services/inputflinger/reader/mapper/TouchCursorInputMapperCommon.h @@ -17,12 +17,13 @@ #ifndef _UI_INPUTREADER_TOUCH_CURSOR_INPUT_MAPPER_COMMON_H #define _UI_INPUTREADER_TOUCH_CURSOR_INPUT_MAPPER_COMMON_H +#include <input/DisplayViewport.h> +#include <stdint.h> + #include "EventHub.h" #include "InputListener.h" #include "InputReaderContext.h" -#include <stdint.h> - namespace android { // --- Static Definitions --- diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp index 99a572a5fd..efdc84fd8f 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp +++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp @@ -765,7 +765,7 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) { mPointerController = getContext()->getPointerController(getDeviceId()); } } else { - mPointerController.clear(); + mPointerController.reset(); } if (viewportChanged || deviceModeChanged) { @@ -1383,7 +1383,7 @@ void TouchInputMapper::reset(nsecs_t when) { resetExternalStylus(); if (mPointerController != nullptr) { - mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL); + mPointerController->fade(PointerControllerInterface::Transition::GRADUAL); mPointerController->clearSpots(); } @@ -1589,8 +1589,8 @@ void TouchInputMapper::cookAndDispatch(nsecs_t when) { } else { if (mDeviceMode == DEVICE_MODE_DIRECT && mConfig.showTouches && mPointerController != nullptr) { - mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT); - mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL); + mPointerController->setPresentation(PointerControllerInterface::Presentation::SPOT); + mPointerController->fade(PointerControllerInterface::Transition::GRADUAL); mPointerController->setButtonState(mCurrentRawState.buttonState); mPointerController->setSpots(mCurrentCookedState.cookedPointerData.pointerCoords, @@ -2327,7 +2327,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag // Update the pointer presentation and spots. if (mParameters.gestureMode == Parameters::GESTURE_MODE_MULTI_TOUCH) { - mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER); + mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER); if (finishPreviousGesture || cancelPreviousGesture) { mPointerController->clearSpots(); } @@ -2339,7 +2339,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag mPointerController->getDisplayId()); } } else { - mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER); + mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER); } // Show or hide the pointer if needed. @@ -2349,7 +2349,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag if (mParameters.gestureMode == Parameters::GESTURE_MODE_MULTI_TOUCH && mPointerGesture.lastGestureMode == PointerGesture::FREEFORM) { // Remind the user of where the pointer is after finishing a gesture with spots. - mPointerController->unfade(PointerControllerInterface::TRANSITION_GRADUAL); + mPointerController->unfade(PointerControllerInterface::Transition::GRADUAL); } break; case PointerGesture::TAP: @@ -2360,15 +2360,15 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag case PointerGesture::SWIPE: // Unfade the pointer when the current gesture manipulates the // area directly under the pointer. - mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE); + mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE); break; case PointerGesture::FREEFORM: // Fade the pointer when the current gesture manipulates a different // area and there are spots to guide the user experience. if (mParameters.gestureMode == Parameters::GESTURE_MODE_MULTI_TOUCH) { - mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL); + mPointerController->fade(PointerControllerInterface::Transition::GRADUAL); } else { - mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE); + mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE); } break; } @@ -2537,7 +2537,7 @@ void TouchInputMapper::abortPointerGestures(nsecs_t when, uint32_t policyFlags) // Remove any current spots. if (mPointerController != nullptr) { - mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL); + mPointerController->fade(PointerControllerInterface::Transition::GRADUAL); mPointerController->clearSpots(); } } @@ -3396,12 +3396,12 @@ void TouchInputMapper::dispatchPointerSimple(nsecs_t when, uint32_t policyFlags, int32_t displayId = mViewport.displayId; if (down || hovering) { - mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER); + mPointerController->setPresentation(PointerControllerInterface::Presentation::POINTER); mPointerController->clearSpots(); mPointerController->setButtonState(mCurrentRawState.buttonState); - mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE); + mPointerController->unfade(PointerControllerInterface::Transition::IMMEDIATE); } else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) { - mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL); + mPointerController->fade(PointerControllerInterface::Transition::GRADUAL); } displayId = mPointerController->getDisplayId(); diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h index 58bfc5c596..7f811a0e1b 100644 --- a/services/inputflinger/reader/mapper/TouchInputMapper.h +++ b/services/inputflinger/reader/mapper/TouchInputMapper.h @@ -376,7 +376,7 @@ protected: nsecs_t mDownTime; // The pointer controller, or null if the device is not a pointer. - sp<PointerControllerInterface> mPointerController; + std::shared_ptr<PointerControllerInterface> mPointerController; std::vector<VirtualKey> mVirtualKeys; diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index c457a1525f..18bd3d06e1 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -27,12 +27,13 @@ #include <TestInputListener.h> #include <TouchInputMapper.h> #include <UinputDevice.h> - #include <android-base/thread_annotations.h> #include <gtest/gtest.h> #include <inttypes.h> #include <math.h> +#include <memory> + namespace android { using std::chrono_literals::operator""ms; @@ -76,15 +77,14 @@ class FakePointerController : public PointerControllerInterface { int32_t mButtonState; int32_t mDisplayId; -protected: - virtual ~FakePointerController() { } - public: FakePointerController() : mHaveBounds(false), mMinX(0), mMinY(0), mMaxX(0), mMaxY(0), mX(0), mY(0), mButtonState(0), mDisplayId(ADISPLAY_ID_DEFAULT) { } + virtual ~FakePointerController() {} + void setBounds(float minX, float minY, float maxX, float maxY) { mHaveBounds = true; mMinX = minX; @@ -176,7 +176,7 @@ class FakeInputReaderPolicy : public InputReaderPolicyInterface { std::condition_variable mDevicesChangedCondition; InputReaderConfiguration mConfig; - KeyedVector<int32_t, sp<FakePointerController> > mPointerControllers; + std::unordered_map<int32_t, std::shared_ptr<FakePointerController>> mPointerControllers; std::vector<InputDeviceInfo> mInputDevices GUARDED_BY(mLock); bool mInputDevicesChanged GUARDED_BY(mLock){false}; std::vector<DisplayViewport> mViewports; @@ -256,8 +256,8 @@ public: void removeDisabledDevice(int32_t deviceId) { mConfig.disabledDevices.erase(deviceId); } - void setPointerController(int32_t deviceId, const sp<FakePointerController>& controller) { - mPointerControllers.add(deviceId, controller); + void setPointerController(int32_t deviceId, std::shared_ptr<FakePointerController> controller) { + mPointerControllers.insert_or_assign(deviceId, std::move(controller)); } const InputReaderConfiguration* getReaderConfiguration() const { @@ -318,8 +318,8 @@ private: *outConfig = mConfig; } - virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId) { - return mPointerControllers.valueFor(deviceId); + virtual std::shared_ptr<PointerControllerInterface> obtainPointerController(int32_t deviceId) { + return mPointerControllers[deviceId]; } virtual void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) { @@ -847,7 +847,7 @@ class FakeInputReaderContext : public InputReaderContext { bool mUpdateGlobalMetaStateWasCalled; int32_t mGeneration; int32_t mNextId; - wp<PointerControllerInterface> mPointerController; + std::weak_ptr<PointerControllerInterface> mPointerController; public: FakeInputReaderContext(std::shared_ptr<EventHubInterface> eventHub, @@ -876,7 +876,7 @@ public: } void updatePointerDisplay() { - sp<PointerControllerInterface> controller = mPointerController.promote(); + std::shared_ptr<PointerControllerInterface> controller = mPointerController.lock(); if (controller != nullptr) { InputReaderConfiguration config; mPolicy->getReaderConfiguration(&config); @@ -913,8 +913,8 @@ private: virtual bool shouldDropVirtualKey(nsecs_t, int32_t, int32_t) { return false; } - virtual sp<PointerControllerInterface> getPointerController(int32_t deviceId) { - sp<PointerControllerInterface> controller = mPointerController.promote(); + virtual std::shared_ptr<PointerControllerInterface> getPointerController(int32_t deviceId) { + std::shared_ptr<PointerControllerInterface> controller = mPointerController.lock(); if (controller == nullptr) { controller = mPolicy->obtainPointerController(deviceId); mPointerController = controller; @@ -2348,9 +2348,9 @@ protected: ASSERT_NEAR(distance, coords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE), EPSILON); } - static void assertPosition(const sp<FakePointerController>& controller, float x, float y) { + static void assertPosition(const FakePointerController& controller, float x, float y) { float actualX, actualY; - controller->getPosition(&actualX, &actualY); + controller.getPosition(&actualX, &actualY); ASSERT_NEAR(x, actualX, 1); ASSERT_NEAR(y, actualY, 1); } @@ -3021,12 +3021,12 @@ class CursorInputMapperTest : public InputMapperTest { protected: static const int32_t TRACKBALL_MOVEMENT_THRESHOLD; - sp<FakePointerController> mFakePointerController; + std::shared_ptr<FakePointerController> mFakePointerController; virtual void SetUp() override { InputMapperTest::SetUp(); - mFakePointerController = new FakePointerController(); + mFakePointerController = std::make_shared<FakePointerController>(); mFakePolicy->setPointerController(mDevice->getId(), mFakePointerController); } @@ -3682,7 +3682,7 @@ TEST_F(CursorInputMapperTest, Process_WhenModeIsPointer_ShouldMoveThePointerArou ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); - ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f)); + ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f)); } TEST_F(CursorInputMapperTest, Process_PointerCapture) { @@ -3710,7 +3710,7 @@ TEST_F(CursorInputMapperTest, Process_PointerCapture) { ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 10.0f, 20.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); - ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 100.0f, 200.0f)); + ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 100.0f, 200.0f)); // Button press. process(mapper, ARBITRARY_TIME, EV_KEY, BTN_MOUSE, 1); @@ -3749,7 +3749,7 @@ TEST_F(CursorInputMapperTest, Process_PointerCapture) { ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 30.0f, 40.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); - ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 100.0f, 200.0f)); + ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 100.0f, 200.0f)); // Disable pointer capture and check that the device generation got bumped // and events are generated the usual way. @@ -3770,7 +3770,7 @@ TEST_F(CursorInputMapperTest, Process_PointerCapture) { ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); - ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f)); + ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f)); } TEST_F(CursorInputMapperTest, Process_ShouldHandleDisplayId) { @@ -3798,7 +3798,7 @@ TEST_F(CursorInputMapperTest, Process_ShouldHandleDisplayId) { ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); - ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f)); + ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f)); ASSERT_EQ(SECOND_DISPLAY_ID, args.displayId); } @@ -6806,7 +6806,8 @@ TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayPort) { TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) { // Setup for second display. - sp<FakePointerController> fakePointerController = new FakePointerController(); + std::shared_ptr<FakePointerController> fakePointerController = + std::make_shared<FakePointerController>(); fakePointerController->setBounds(0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1); fakePointerController->setPosition(100, 200); fakePointerController->setButtonState(0); @@ -6866,7 +6867,8 @@ TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) { device2->reset(ARBITRARY_TIME); // Setup PointerController. - sp<FakePointerController> fakePointerController = new FakePointerController(); + std::shared_ptr<FakePointerController> fakePointerController = + std::make_shared<FakePointerController>(); mFakePolicy->setPointerController(mDevice->getId(), fakePointerController); mFakePolicy->setPointerController(SECOND_DEVICE_ID, fakePointerController); 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/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp index 07be7916ee..6e4235e409 100644 --- a/services/surfaceflinger/BufferQueueLayer.cpp +++ b/services/surfaceflinger/BufferQueueLayer.cpp @@ -324,9 +324,6 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t } uint64_t bufferID = mQueueItems[0].mGraphicBuffer->getId(); - mFlinger->mFrameTracer->traceFence(layerId, bufferID, currentFrameNumber, - mQueueItems[0].mFenceTime, - FrameTracer::FrameEvent::ACQUIRE_FENCE); mFlinger->mTimeStats->setLatchTime(layerId, currentFrameNumber, latchTime); mFlinger->mFrameTracer->traceTimestamp(layerId, bufferID, currentFrameNumber, latchTime, FrameTracer::FrameEvent::LATCH); @@ -393,8 +390,12 @@ void BufferQueueLayer::onFrameCancelled(const uint64_t bufferId) { void BufferQueueLayer::onFrameAvailable(const BufferItem& item) { const int32_t layerId = getSequence(); - mFlinger->mFrameTracer->traceTimestamp(layerId, item.mGraphicBuffer->getId(), item.mFrameNumber, - systemTime(), FrameTracer::FrameEvent::QUEUE); + const uint64_t bufferId = item.mGraphicBuffer->getId(); + mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, item.mFrameNumber, systemTime(), + FrameTracer::FrameEvent::QUEUE); + mFlinger->mFrameTracer->traceFence(layerId, bufferId, item.mFrameNumber, + std::make_shared<FenceTime>(item.mFence), + FrameTracer::FrameEvent::ACQUIRE_FENCE); ATRACE_CALL(); // Add this buffer from our internal queue tracker @@ -460,8 +461,12 @@ void BufferQueueLayer::onFrameReplaced(const BufferItem& item) { } const int32_t layerId = getSequence(); - mFlinger->mFrameTracer->traceTimestamp(layerId, item.mGraphicBuffer->getId(), item.mFrameNumber, - systemTime(), FrameTracer::FrameEvent::QUEUE); + const uint64_t bufferId = item.mGraphicBuffer->getId(); + mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, item.mFrameNumber, systemTime(), + FrameTracer::FrameEvent::QUEUE); + mFlinger->mFrameTracer->traceFence(layerId, bufferId, item.mFrameNumber, + std::make_shared<FenceTime>(item.mFence), + FrameTracer::FrameEvent::ACQUIRE_FENCE); mConsumer->onBufferAvailable(item); } diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp index e8f54f57b1..34dc53648c 100644 --- a/services/surfaceflinger/CompositionEngine/src/Output.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp @@ -952,7 +952,7 @@ std::vector<LayerFE::LayerSettings> Output::generateClientCompositionRequests( const bool useIdentityTransform = false; bool firstLayer = true; // Used when a layer clears part of the buffer. - Region dummyRegion; + Region stubRegion; for (auto* layer : getOutputLayersOrderedByZ()) { const auto& layerState = layer->getState(); @@ -991,7 +991,7 @@ std::vector<LayerFE::LayerSettings> Output::generateClientCompositionRequests( layer->needsFiltering() || outputState.needsFiltering, outputState.isSecure, supportsProtectedContent, - clientComposition ? clearRegion : dummyRegion, + clientComposition ? clearRegion : stubRegion, outputState.viewport, outputDataspace, realContentIsVisible, diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp index 59ed72e928..7a06400d62 100644 --- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp @@ -3583,15 +3583,15 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqu mLayers[1].mLayerFEState.isOpaque = true; mLayers[2].mLayerFEState.isOpaque = true; Region accumClearRegion(Rect(10, 11, 12, 13)); - Region dummyRegion; + Region stubRegion; compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{ Region(kDisplayFrame), - false, /* identity transform */ - false, /* needs filtering */ - false, /* secure */ - false, /* supports protected content */ - dummyRegion, /* clear region */ + false, /* identity transform */ + false, /* needs filtering */ + false, /* secure */ + false, /* supports protected content */ + stubRegion, /* clear region */ kDisplayViewport, kDisplayDataspace, false /* realContentIsVisible */, 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/surfaceflinger/Scheduler/DispSync.cpp b/services/surfaceflinger/Scheduler/DispSync.cpp index ff91bf7bc0..46112f5cf4 100644 --- a/services/surfaceflinger/Scheduler/DispSync.cpp +++ b/services/surfaceflinger/Scheduler/DispSync.cpp @@ -340,7 +340,7 @@ private: return nextEventTime; } - // Sanity check that the duration is close enough in length to a period without + // Check that the duration is close enough in length to a period without // falling into double-rate vsyncs. bool isCloseToPeriod(nsecs_t duration) { // Ratio of 3/5 is arbitrary, but it must be greater than 1/2. diff --git a/services/surfaceflinger/Scheduler/DispSync.h b/services/surfaceflinger/Scheduler/DispSync.h index 832f08e07b..6fb5654b8a 100644 --- a/services/surfaceflinger/Scheduler/DispSync.h +++ b/services/surfaceflinger/Scheduler/DispSync.h @@ -227,7 +227,7 @@ private: // mZeroErrSamplesCount keeps track of how many times in a row there were // zero timestamps available in the mPresentFences array. - // Used to sanity check that we are able to calculate the model error. + // Used to check that we are able to calculate the model error. size_t mZeroErrSamplesCount; // Whether we have updated the vsync event model since the last resync. diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 07690cbf32..1342cfcb6e 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -57,6 +57,7 @@ #include <gui/LayerMetadata.h> #include <gui/LayerState.h> #include <gui/Surface.h> +#include <hidl/ServiceManagement.h> #include <input/IInputFlinger.h> #include <layerproto/LayerProtoParser.h> #include <log/log.h> @@ -441,7 +442,7 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipI // deriving the setting from the set service name, but it // would be brittle if the name that's not 'default' is used // for production purposes later on. - setenv("TREBLE_TESTING_OVERRIDE", "true", true); + android::hardware::details::setTrebleTestingOverride(true); } useFrameRateApi = use_frame_rate_api(true); diff --git a/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop b/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop index cfc301bd22..7b1f0fb0a8 100644 --- a/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop +++ b/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop @@ -328,7 +328,7 @@ prop { prop { api_name: "refresh_rate_switching" type: Boolean - scope: System + scope: Public access: Readonly prop_name: "ro.surface_flinger.refresh_rate_switching" deprecated: true diff --git a/services/surfaceflinger/tests/BufferGenerator.cpp b/services/surfaceflinger/tests/BufferGenerator.cpp index 293738cfcb..4868c1224a 100644 --- a/services/surfaceflinger/tests/BufferGenerator.cpp +++ b/services/surfaceflinger/tests/BufferGenerator.cpp @@ -88,7 +88,7 @@ private: sp<Surface> mSurface; }; -/* Used to generate valid fences. It is not possible to create a dummy sync +/* Used to generate valid fences. It is not possible to create a placeholder sync * fence for testing. Egl can generate buffers along with a valid fence. * The buffer cannot be guaranteed to be the same format across all devices so * a CPU filled buffer is used instead. The Egl fence is used along with the diff --git a/services/surfaceflinger/tests/LayerTransaction_test.cpp b/services/surfaceflinger/tests/LayerTransaction_test.cpp index 97cba63192..1f8f7ed892 100644 --- a/services/surfaceflinger/tests/LayerTransaction_test.cpp +++ b/services/surfaceflinger/tests/LayerTransaction_test.cpp @@ -118,10 +118,9 @@ TEST_F(LayerTransactionTest, DISABLED_BufferQueueLayerMergeDamageRegionWhenDropp sp<SurfaceControl> layer; ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", width, height)); const auto producer = layer->getIGraphicBufferProducer(); - const sp<IProducerListener> dummyListener(new DummyProducerListener); + const sp<IProducerListener> stubListener(new StubProducerListener); IGraphicBufferProducer::QueueBufferOutput queueBufferOutput; - ASSERT_EQ(OK, - producer->connect(dummyListener, NATIVE_WINDOW_API_CPU, true, &queueBufferOutput)); + ASSERT_EQ(OK, producer->connect(stubListener, NATIVE_WINDOW_API_CPU, true, &queueBufferOutput)); std::map<int, sp<GraphicBuffer>> slotMap; auto slotToBuffer = [&](int slot, sp<GraphicBuffer>* buf) { diff --git a/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.cpp b/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.cpp index 96a7541919..1cea25a80f 100644 --- a/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.cpp +++ b/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.cpp @@ -29,8 +29,8 @@ #include "SurfaceFlinger.h" // Get the name of the service... #include <binder/IServiceManager.h> - #include <cutils/properties.h> +#include <hidl/ServiceManagement.h> #include <iomanip> #include <thread> @@ -173,7 +173,7 @@ void FakeHwcEnvironment::SetUp() { property_set("debug.sf.hwc_service_name", "mock"); // This allows tests/SF to register/load a HIDL service not listed in manifest files. - setenv("TREBLE_TESTING_OVERRIDE", "true", true); + android::hardware::details::setTrebleTestingOverride(true); property_set("debug.sf.treble_testing_override", "true"); } diff --git a/services/surfaceflinger/tests/unittests/FrameTracerTest.cpp b/services/surfaceflinger/tests/unittests/FrameTracerTest.cpp index 68cb52fe87..a119e27d41 100644 --- a/services/surfaceflinger/tests/unittests/FrameTracerTest.cpp +++ b/services/surfaceflinger/tests/unittests/FrameTracerTest.cpp @@ -77,6 +77,22 @@ public: return tracingSession; } + std::vector<perfetto::protos::TracePacket> readGraphicsFramePacketsBlocking( + perfetto::TracingSession* tracingSession) { + std::vector<char> raw_trace = tracingSession->ReadTraceBlocking(); + perfetto::protos::Trace trace; + EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size()))); + + std::vector<perfetto::protos::TracePacket> packets; + for (const auto& packet : trace.packet()) { + if (!packet.has_graphics_frame_event()) { + continue; + } + packets.emplace_back(packet); + } + return packets; + } + std::unique_ptr<FrameTracer> mFrameTracer; FenceToFenceTimeMap fenceFactory; }; @@ -142,40 +158,29 @@ TEST_F(FrameTracerTest, canTraceAfterAddingLayer) { auto tracingSession = getTracingSessionForTest(); tracingSession->StartBlocking(); - // Clean up irrelevant traces. - tracingSession->ReadTraceBlocking(); - mFrameTracer->traceTimestamp(layerId, bufferID, frameNumber, timestamp, type, duration); // Create second trace packet to finalize the previous one. mFrameTracer->traceTimestamp(layerId, 0, 0, 0, FrameTracer::FrameEvent::UNSPECIFIED); tracingSession->StopBlocking(); - std::vector<char> raw_trace = tracingSession->ReadTraceBlocking(); - EXPECT_EQ(raw_trace.size(), 0); + auto packets = readGraphicsFramePacketsBlocking(tracingSession.get()); + EXPECT_EQ(packets.size(), 0); } { auto tracingSession = getTracingSessionForTest(); tracingSession->StartBlocking(); - // Clean up irrelevant traces. - tracingSession->ReadTraceBlocking(); - mFrameTracer->traceNewLayer(layerId, layerName); mFrameTracer->traceTimestamp(layerId, bufferID, frameNumber, timestamp, type, duration); // Create second trace packet to finalize the previous one. mFrameTracer->traceTimestamp(layerId, 0, 0, 0, FrameTracer::FrameEvent::UNSPECIFIED); tracingSession->StopBlocking(); - std::vector<char> raw_trace = tracingSession->ReadTraceBlocking(); - ASSERT_GT(raw_trace.size(), 0); - - perfetto::protos::Trace trace; - ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size()))); - ASSERT_FALSE(trace.packet().empty()); - EXPECT_EQ(trace.packet().size(), 1); + auto packets = readGraphicsFramePacketsBlocking(tracingSession.get()); + EXPECT_EQ(packets.size(), 1); - const auto& packet = trace.packet().Get(0); + const auto& packet = packets[0]; ASSERT_TRUE(packet.has_timestamp()); EXPECT_EQ(packet.timestamp(), timestamp); ASSERT_TRUE(packet.has_graphics_frame_event()); @@ -205,24 +210,21 @@ TEST_F(FrameTracerTest, traceFenceTriggersOnNextTraceAfterFenceFired) { fenceFactory.signalAllForTest(Fence::NO_FENCE, Fence::SIGNAL_TIME_PENDING); auto tracingSession = getTracingSessionForTest(); tracingSession->StartBlocking(); - // Clean up irrelevant traces. - tracingSession->ReadTraceBlocking(); // Trace. mFrameTracer->traceNewLayer(layerId, layerName); mFrameTracer->traceFence(layerId, bufferID, frameNumber, fenceTime, type); // Create extra trace packet to (hopefully not) trigger and finalize the fence packet. mFrameTracer->traceTimestamp(layerId, bufferID, 0, 0, FrameTracer::FrameEvent::UNSPECIFIED); tracingSession->StopBlocking(); - std::vector<char> raw_trace = tracingSession->ReadTraceBlocking(); - EXPECT_EQ(raw_trace.size(), 0); + + auto packets = readGraphicsFramePacketsBlocking(tracingSession.get()); + EXPECT_EQ(packets.size(), 0); } { auto fenceTime = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); auto tracingSession = getTracingSessionForTest(); tracingSession->StartBlocking(); - // Clean up irrelevant traces. - tracingSession->ReadTraceBlocking(); mFrameTracer->traceNewLayer(layerId, layerName); mFrameTracer->traceFence(layerId, bufferID, frameNumber, fenceTime, type); const nsecs_t timestamp = systemTime(); @@ -231,15 +233,10 @@ TEST_F(FrameTracerTest, traceFenceTriggersOnNextTraceAfterFenceFired) { mFrameTracer->traceTimestamp(layerId, bufferID, 0, 0, FrameTracer::FrameEvent::UNSPECIFIED); tracingSession->StopBlocking(); - std::vector<char> raw_trace = tracingSession->ReadTraceBlocking(); - ASSERT_GT(raw_trace.size(), 0); + auto packets = readGraphicsFramePacketsBlocking(tracingSession.get()); + EXPECT_EQ(packets.size(), 2); // Two packets because of the extra trace made above. - perfetto::protos::Trace trace; - ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size()))); - ASSERT_FALSE(trace.packet().empty()); - EXPECT_EQ(trace.packet().size(), 2); // Two packets because of the extra trace made above. - - const auto& packet = trace.packet().Get(1); + const auto& packet = packets[1]; ASSERT_TRUE(packet.has_timestamp()); EXPECT_EQ(packet.timestamp(), timestamp); ASSERT_TRUE(packet.has_graphics_frame_event()); @@ -266,8 +263,6 @@ TEST_F(FrameTracerTest, traceFenceWithStartTimeAfterSignalTime_ShouldHaveNoDurat auto tracingSession = getTracingSessionForTest(); tracingSession->StartBlocking(); - // Clean up irrelevant traces. - tracingSession->ReadTraceBlocking(); mFrameTracer->traceNewLayer(layerId, layerName); // traceFence called after fence signalled. @@ -288,22 +283,17 @@ TEST_F(FrameTracerTest, traceFenceWithStartTimeAfterSignalTime_ShouldHaveNoDurat mFrameTracer->traceTimestamp(layerId, bufferID, 0, 0, FrameTracer::FrameEvent::UNSPECIFIED); tracingSession->StopBlocking(); - std::vector<char> raw_trace = tracingSession->ReadTraceBlocking(); - ASSERT_GT(raw_trace.size(), 0); + auto packets = readGraphicsFramePacketsBlocking(tracingSession.get()); + EXPECT_EQ(packets.size(), 2); - perfetto::protos::Trace trace; - ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size()))); - ASSERT_FALSE(trace.packet().empty()); - EXPECT_EQ(trace.packet().size(), 2); - - const auto& packet1 = trace.packet().Get(0); + const auto& packet1 = packets[0]; ASSERT_TRUE(packet1.has_timestamp()); EXPECT_EQ(packet1.timestamp(), signalTime1); ASSERT_TRUE(packet1.has_graphics_frame_event()); ASSERT_TRUE(packet1.graphics_frame_event().has_buffer_event()); ASSERT_FALSE(packet1.graphics_frame_event().buffer_event().has_duration_ns()); - const auto& packet2 = trace.packet().Get(1); + const auto& packet2 = packets[1]; ASSERT_TRUE(packet2.has_timestamp()); EXPECT_EQ(packet2.timestamp(), signalTime2); ASSERT_TRUE(packet2.has_graphics_frame_event()); @@ -323,8 +313,6 @@ TEST_F(FrameTracerTest, traceFenceOlderThanDeadline_ShouldBeIgnored) { auto fence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE); tracingSession->StartBlocking(); - // Clean up irrelevant traces. - tracingSession->ReadTraceBlocking(); mFrameTracer->traceNewLayer(layerId, layerName); mFrameTracer->traceFence(layerId, bufferID, frameNumber, fence, type); fenceFactory.signalAllForTest(Fence::NO_FENCE, signalTime); @@ -332,8 +320,8 @@ TEST_F(FrameTracerTest, traceFenceOlderThanDeadline_ShouldBeIgnored) { mFrameTracer->traceTimestamp(layerId, bufferID, 0, 0, FrameTracer::FrameEvent::UNSPECIFIED); tracingSession->StopBlocking(); - std::vector<char> raw_trace = tracingSession->ReadTraceBlocking(); - EXPECT_EQ(raw_trace.size(), 0); + auto packets = readGraphicsFramePacketsBlocking(tracingSession.get()); + EXPECT_EQ(packets.size(), 0); } TEST_F(FrameTracerTest, traceFenceWithValidStartTime_ShouldHaveCorrectDuration) { @@ -347,8 +335,6 @@ TEST_F(FrameTracerTest, traceFenceWithValidStartTime_ShouldHaveCorrectDuration) auto tracingSession = getTracingSessionForTest(); tracingSession->StartBlocking(); - // Clean up irrelevant traces. - tracingSession->ReadTraceBlocking(); mFrameTracer->traceNewLayer(layerId, layerName); // traceFence called after fence signalled. @@ -369,15 +355,10 @@ TEST_F(FrameTracerTest, traceFenceWithValidStartTime_ShouldHaveCorrectDuration) mFrameTracer->traceTimestamp(layerId, bufferID, 0, 0, FrameTracer::FrameEvent::UNSPECIFIED); tracingSession->StopBlocking(); - std::vector<char> raw_trace = tracingSession->ReadTraceBlocking(); - ASSERT_GT(raw_trace.size(), 0); - - perfetto::protos::Trace trace; - ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size()))); - ASSERT_FALSE(trace.packet().empty()); - EXPECT_EQ(trace.packet().size(), 2); + auto packets = readGraphicsFramePacketsBlocking(tracingSession.get()); + EXPECT_EQ(packets.size(), 2); - const auto& packet1 = trace.packet().Get(0); + const auto& packet1 = packets[0]; ASSERT_TRUE(packet1.has_timestamp()); EXPECT_EQ(packet1.timestamp(), startTime1); ASSERT_TRUE(packet1.has_graphics_frame_event()); @@ -386,7 +367,7 @@ TEST_F(FrameTracerTest, traceFenceWithValidStartTime_ShouldHaveCorrectDuration) const auto& buffer_event1 = packet1.graphics_frame_event().buffer_event(); EXPECT_EQ(buffer_event1.duration_ns(), duration); - const auto& packet2 = trace.packet().Get(1); + const auto& packet2 = packets[1]; ASSERT_TRUE(packet2.has_timestamp()); EXPECT_EQ(packet2.timestamp(), startTime2); ASSERT_TRUE(packet2.has_graphics_frame_event()); diff --git a/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp b/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp index 63a34af8a2..0a246505ca 100644 --- a/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp +++ b/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp @@ -221,7 +221,7 @@ std::string TimeStatsTest::inputCommand(InputCommand cmd, bool useProto) { } static std::string genLayerName(int32_t layerId) { - return (layerId < 0 ? "PopupWindow:b54fcd1#0" : "com.dummy#") + std::to_string(layerId); + return (layerId < 0 ? "PopupWindow:b54fcd1#0" : "com.example.fake#") + std::to_string(layerId); } void TimeStatsTest::setTimeStamp(TimeStamp type, int32_t id, uint64_t frameNumber, nsecs_t ts) { @@ -424,7 +424,7 @@ TEST_F(TimeStatsTest, canAverageRenderEngineTimings) { std::chrono::duration_cast<std::chrono::nanoseconds>(8ms) .count()); - // Push a dummy present fence to trigger flushing the RenderEngine timings. + // Push a fake present fence to trigger flushing the RenderEngine timings. mTimeStats->setPowerMode(PowerMode::ON); mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>( std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count())); @@ -505,7 +505,7 @@ TEST_F(TimeStatsTest, canInsertGlobalRenderEngineTiming) { ASSERT_TRUE(preFlushProto.ParseFromString(inputCommand(InputCommand::DUMP_ALL, FMT_PROTO))); ASSERT_EQ(0, preFlushProto.render_engine_timing_size()); - // Push a dummy present fence to trigger flushing the RenderEngine timings. + // Push a fake present fence to trigger flushing the RenderEngine timings. mTimeStats->setPowerMode(PowerMode::ON); mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>( std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count())); 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", }}; |