diff options
-rw-r--r-- | cmds/dumpstate/DumpstateUtil.cpp | 4 | ||||
-rw-r--r-- | cmds/dumpstate/DumpstateUtil.h | 4 | ||||
-rw-r--r-- | cmds/installd/dexopt.h | 5 | ||||
-rw-r--r-- | cmds/installd/otapreopt.cpp | 46 | ||||
-rw-r--r-- | libs/binder/Android.bp | 3 | ||||
-rw-r--r-- | libs/binder/rust/Android.bp | 26 | ||||
-rw-r--r-- | libs/binder/rust/libbinder_ndk_bindgen_flags.txt | 11 | ||||
-rw-r--r-- | libs/binder/rust/src/error.rs | 150 | ||||
-rw-r--r-- | libs/binder/rust/src/lib.rs | 2 | ||||
-rw-r--r-- | libs/gui/OWNERS | 2 | ||||
-rw-r--r-- | libs/renderengine/OWNERS | 2 | ||||
-rw-r--r-- | services/surfaceflinger/OWNERS | 2 |
12 files changed, 218 insertions, 39 deletions
diff --git a/cmds/dumpstate/DumpstateUtil.cpp b/cmds/dumpstate/DumpstateUtil.cpp index 484231225d..615701ccc1 100644 --- a/cmds/dumpstate/DumpstateUtil.cpp +++ b/cmds/dumpstate/DumpstateUtil.cpp @@ -207,9 +207,7 @@ std::string PropertiesHelper::build_type_ = ""; int PropertiesHelper::dry_run_ = -1; int PropertiesHelper::unroot_ = -1; int PropertiesHelper::parallel_run_ = -1; -#if !defined(__ANDROID_VNDK__) int PropertiesHelper::strict_run_ = -1; -#endif bool PropertiesHelper::IsUserBuild() { if (build_type_.empty()) { @@ -240,7 +238,6 @@ bool PropertiesHelper::IsParallelRun() { return parallel_run_ == 1; } -#if !defined(__ANDROID_VNDK__) bool PropertiesHelper::IsStrictRun() { if (strict_run_ == -1) { // Defaults to using stricter timeouts. @@ -248,7 +245,6 @@ bool PropertiesHelper::IsStrictRun() { } return strict_run_ == 1; } -#endif int DumpFileToFd(int out_fd, const std::string& title, const std::string& path) { android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC))); diff --git a/cmds/dumpstate/DumpstateUtil.h b/cmds/dumpstate/DumpstateUtil.h index 6049e3e19d..9e955e3c04 100644 --- a/cmds/dumpstate/DumpstateUtil.h +++ b/cmds/dumpstate/DumpstateUtil.h @@ -198,18 +198,14 @@ class PropertiesHelper { * will default to true. This results in shortened timeouts for flaky * sections. */ -#if !defined(__ANDROID_VNDK__) static bool IsStrictRun(); -#endif private: static std::string build_type_; static int dry_run_; static int unroot_; static int parallel_run_; -#if !defined(__ANDROID_VNDK__) static int strict_run_; -#endif }; /* diff --git a/cmds/installd/dexopt.h b/cmds/installd/dexopt.h index 5cf402c54c..df02588a22 100644 --- a/cmds/installd/dexopt.h +++ b/cmds/installd/dexopt.h @@ -18,6 +18,7 @@ #define DEXOPT_H_ #include "installd_constants.h" +#include "unique_file.h" #include <sys/types.h> @@ -156,6 +157,10 @@ const char* select_execution_binary( // artifacts. int get_odex_visibility(const char* apk_path, const char* instruction_set, const char* oat_dir); +UniqueFile maybe_open_reference_profile(const std::string& pkgname, const std::string& dex_path, + const char* profile_name, bool profile_guided, + bool is_public, int uid, bool is_secondary_dex); + } // namespace installd } // namespace android diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp index 407cb244e3..818fd8066e 100644 --- a/cmds/installd/otapreopt.cpp +++ b/cmds/installd/otapreopt.cpp @@ -14,20 +14,21 @@ ** limitations under the License. */ -#include <algorithm> #include <inttypes.h> -#include <limits> -#include <random> -#include <regex> #include <selinux/android.h> #include <selinux/avc.h> #include <stdlib.h> #include <string.h> #include <sys/capability.h> +#include <sys/mman.h> #include <sys/prctl.h> #include <sys/stat.h> -#include <sys/mman.h> #include <sys/wait.h> +#include <algorithm> +#include <iterator> +#include <limits> +#include <random> +#include <regex> #include <android-base/logging.h> #include <android-base/macros.h> @@ -47,6 +48,7 @@ #include "otapreopt_parameters.h" #include "otapreopt_utils.h" #include "system_properties.h" +#include "unique_file.h" #include "utils.h" #ifndef LOG_TAG @@ -87,6 +89,9 @@ static_assert(DEXOPT_GENERATE_APP_IMAGE == 1 << 12, "DEXOPT_GENERATE_APP_IMAGE u static_assert(DEXOPT_MASK == (0x3dfe | DEXOPT_IDLE_BACKGROUND_JOB), "DEXOPT_MASK unexpected."); +constexpr const char* kAotCompilerFilters[]{ + "space-profile", "space", "speed-profile", "speed", "everything-profile", "everything", +}; template<typename T> static constexpr bool IsPowerOfTwo(T x) { @@ -415,6 +420,32 @@ private: return (strcmp(arg, "!") == 0) ? nullptr : arg; } + bool IsAotCompilation() const { + if (std::find(std::begin(kAotCompilerFilters), std::end(kAotCompilerFilters), + parameters_.compiler_filter) == std::end(kAotCompilerFilters)) { + return false; + } + + int dexopt_flags = parameters_.dexopt_flags; + bool profile_guided = (dexopt_flags & DEXOPT_PROFILE_GUIDED) != 0; + bool is_secondary_dex = (dexopt_flags & DEXOPT_SECONDARY_DEX) != 0; + bool is_public = (dexopt_flags & DEXOPT_PUBLIC) != 0; + + if (profile_guided) { + UniqueFile reference_profile = + maybe_open_reference_profile(parameters_.pkgName, parameters_.apk_path, + parameters_.profile_name, profile_guided, + is_public, parameters_.uid, is_secondary_dex); + struct stat sbuf; + if (reference_profile.fd() == -1 || + (fstat(reference_profile.fd(), &sbuf) != -1 && sbuf.st_size == 0)) { + return false; + } + } + + return true; + } + bool ShouldSkipPreopt() const { // There's one thing we have to be careful about: we may/will be asked to compile an app // living in the system image. This may be a valid request - if the app wasn't compiled, @@ -439,9 +470,12 @@ private: // (This is ugly as it's the only thing where we need to understand the contents // of parameters_, but it beats postponing the decision or using the call- // backs to do weird things.) + + // In addition, no need to preopt for "verify". The existing vdex files in the OTA package + // and the /data partition will still be usable after the OTA update is applied. const char* apk_path = parameters_.apk_path; CHECK(apk_path != nullptr); - if (StartsWith(apk_path, android_root_)) { + if (StartsWith(apk_path, android_root_) || !IsAotCompilation()) { const char* last_slash = strrchr(apk_path, '/'); if (last_slash != nullptr) { std::string path(apk_path, last_slash - apk_path + 1); diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp index deff76b3a5..f634c1dcde 100644 --- a/libs/binder/Android.bp +++ b/libs/binder/Android.bp @@ -190,6 +190,9 @@ cc_defaults { "-performance-move-const-arg", // b/273486801 "portability*", ], + lto: { + thin: true, + }, } cc_library_headers { diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp index d36ebac109..672d6cf5d0 100644 --- a/libs/binder/rust/Android.bp +++ b/libs/binder/rust/Android.bp @@ -97,34 +97,12 @@ rust_bindgen { crate_name: "binder_ndk_bindgen", wrapper_src: "sys/BinderBindings.hpp", source_stem: "bindings", - bindgen_flags: [ + bindgen_flag_files: [ // Unfortunately the only way to specify the rust_non_exhaustive enum // style for a type is to make it the default - "--default-enum-style", - "rust_non_exhaustive", // and then specify constified enums for the enums we don't want // rustified - "--constified-enum", - "android::c_interface::consts::.*", - - "--allowlist-type", - "android::c_interface::.*", - "--allowlist-type", - "AStatus", - "--allowlist-type", - "AIBinder_Class", - "--allowlist-type", - "AIBinder", - "--allowlist-type", - "AIBinder_Weak", - "--allowlist-type", - "AIBinder_DeathRecipient", - "--allowlist-type", - "AParcel", - "--allowlist-type", - "binder_status_t", - "--allowlist-function", - ".*", + "libbinder_ndk_bindgen_flags.txt", ], shared_libs: [ "libbinder_ndk", diff --git a/libs/binder/rust/libbinder_ndk_bindgen_flags.txt b/libs/binder/rust/libbinder_ndk_bindgen_flags.txt new file mode 100644 index 0000000000..551c59f671 --- /dev/null +++ b/libs/binder/rust/libbinder_ndk_bindgen_flags.txt @@ -0,0 +1,11 @@ +--default-enum-style=rust_non_exhaustive +--constified-enum=android::c_interface::consts::.* +--allowlist-type=android::c_interface::.* +--allowlist-type=AStatus +--allowlist-type=AIBinder_Class +--allowlist-type=AIBinder +--allowlist-type=AIBinder_Weak +--allowlist-type=AIBinder_DeathRecipient +--allowlist-type=AParcel +--allowlist-type=binder_status_t +--allowlist-function=.* diff --git a/libs/binder/rust/src/error.rs b/libs/binder/rust/src/error.rs index 8d9ce0e731..eb04cc3153 100644 --- a/libs/binder/rust/src/error.rs +++ b/libs/binder/rust/src/error.rs @@ -370,6 +370,94 @@ unsafe impl AsNative<sys::AStatus> for Status { } } +/// A conversion from `std::result::Result<T, E>` to `binder::Result<T>`. If this type is `Ok(T)`, +/// it's returned as is. If this type is `Err(E)`, `E` is converted into `Status` which can be +/// either a general binder exception, or a service-specific exception. +/// +/// # Examples +/// +/// ``` +/// // std::io::Error is formatted as the exception's message +/// fn file_exists(name: &str) -> binder::Result<bool> { +/// std::fs::metadata(name) +/// .or_service_specific_exception(NOT_FOUND)? +/// } +/// +/// // A custom function is used to create the exception's message +/// fn file_exists(name: &str) -> binder::Result<bool> { +/// std::fs::metadata(name) +/// .or_service_specific_exception_with(NOT_FOUND, +/// |e| format!("file {} not found: {:?}", name, e))? +/// } +/// +/// // anyhow::Error is formatted as the exception's message +/// use anyhow::{Context, Result}; +/// fn file_exists(name: &str) -> binder::Result<bool> { +/// std::fs::metadata(name) +/// .context("file {} not found") +/// .or_service_specific_exception(NOT_FOUND)? +/// } +/// +/// // General binder exceptions can be created similarly +/// fn file_exists(name: &str) -> binder::Result<bool> { +/// std::fs::metadata(name) +/// .or_binder_exception(ExceptionCode::ILLEGAL_ARGUMENT)? +/// } +/// ``` +pub trait IntoBinderResult<T, E> { + /// Converts the embedded error into a general binder exception of code `exception`. The + /// message of the exception is set by formatting the error for debugging. + fn or_binder_exception(self, exception: ExceptionCode) -> result::Result<T, Status>; + + /// Converts the embedded error into a general binder exception of code `exception`. The + /// message of the exception is set by lazily evaluating the `op` function. + fn or_binder_exception_with<M: AsRef<str>, O: FnOnce(E) -> M>( + self, + exception: ExceptionCode, + op: O, + ) -> result::Result<T, Status>; + + /// Converts the embedded error into a service-specific binder exception. `error_code` is used + /// to distinguish different service-specific binder exceptions. The message of the exception + /// is set by formatting the error for debugging. + fn or_service_specific_exception(self, error_code: i32) -> result::Result<T, Status>; + + /// Converts the embedded error into a service-specific binder exception. `error_code` is used + /// to distinguish different service-specific binder exceptions. The message of the exception + /// is set by lazily evaluating the `op` function. + fn or_service_specific_exception_with<M: AsRef<str>, O: FnOnce(E) -> M>( + self, + error_code: i32, + op: O, + ) -> result::Result<T, Status>; +} + +impl<T, E: std::fmt::Debug> IntoBinderResult<T, E> for result::Result<T, E> { + fn or_binder_exception(self, exception: ExceptionCode) -> result::Result<T, Status> { + self.or_binder_exception_with(exception, |e| format!("{:?}", e)) + } + + fn or_binder_exception_with<M: AsRef<str>, O: FnOnce(E) -> M>( + self, + exception: ExceptionCode, + op: O, + ) -> result::Result<T, Status> { + self.map_err(|e| Status::new_exception_str(exception, Some(op(e)))) + } + + fn or_service_specific_exception(self, error_code: i32) -> result::Result<T, Status> { + self.or_service_specific_exception_with(error_code, |e| format!("{:?}", e)) + } + + fn or_service_specific_exception_with<M: AsRef<str>, O: FnOnce(E) -> M>( + self, + error_code: i32, + op: O, + ) -> result::Result<T, Status> { + self.map_err(|e| Status::new_service_specific_error_str(error_code, Some(op(e)))) + } +} + #[cfg(test)] mod tests { use super::*; @@ -406,4 +494,66 @@ mod tests { assert_eq!(status.service_specific_error(), 0); assert_eq!(status.get_description(), "Status(-5, EX_ILLEGAL_STATE): ''".to_string()); } + + #[test] + fn convert_to_service_specific_exception() { + let res: std::result::Result<(), Status> = + Err("message").or_service_specific_exception(-42); + + assert!(res.is_err()); + let status = res.unwrap_err(); + assert_eq!(status.exception_code(), ExceptionCode::SERVICE_SPECIFIC); + assert_eq!(status.service_specific_error(), -42); + assert_eq!( + status.get_description(), + "Status(-8, EX_SERVICE_SPECIFIC): '-42: \"message\"'".to_string() + ); + } + + #[test] + fn convert_to_service_specific_exception_with() { + let res: std::result::Result<(), Status> = Err("message") + .or_service_specific_exception_with(-42, |e| format!("outer message: {:?}", e)); + + assert!(res.is_err()); + let status = res.unwrap_err(); + assert_eq!(status.exception_code(), ExceptionCode::SERVICE_SPECIFIC); + assert_eq!(status.service_specific_error(), -42); + assert_eq!( + status.get_description(), + "Status(-8, EX_SERVICE_SPECIFIC): '-42: outer message: \"message\"'".to_string() + ); + } + + #[test] + fn convert_to_binder_exception() { + let res: std::result::Result<(), Status> = + Err("message").or_binder_exception(ExceptionCode::ILLEGAL_STATE); + + assert!(res.is_err()); + let status = res.unwrap_err(); + assert_eq!(status.exception_code(), ExceptionCode::ILLEGAL_STATE); + assert_eq!(status.service_specific_error(), 0); + assert_eq!( + status.get_description(), + "Status(-5, EX_ILLEGAL_STATE): '\"message\"'".to_string() + ); + } + + #[test] + fn convert_to_binder_exception_with() { + let res: std::result::Result<(), Status> = Err("message") + .or_binder_exception_with(ExceptionCode::ILLEGAL_STATE, |e| { + format!("outer message: {:?}", e) + }); + + assert!(res.is_err()); + let status = res.unwrap_err(); + assert_eq!(status.exception_code(), ExceptionCode::ILLEGAL_STATE); + assert_eq!(status.service_specific_error(), 0); + assert_eq!( + status.get_description(), + "Status(-5, EX_ILLEGAL_STATE): 'outer message: \"message\"'".to_string() + ); + } } diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs index 0c8b48f1f5..8841fe640b 100644 --- a/libs/binder/rust/src/lib.rs +++ b/libs/binder/rust/src/lib.rs @@ -106,7 +106,7 @@ use binder_ndk_sys as sys; pub use crate::binder_async::{BinderAsyncPool, BoxFuture}; pub use binder::{BinderFeatures, FromIBinder, IBinder, Interface, Strong, Weak}; -pub use error::{ExceptionCode, Status, StatusCode}; +pub use error::{ExceptionCode, IntoBinderResult, Status, StatusCode}; pub use native::{ add_service, force_lazy_services_persist, is_handling_transaction, register_lazy_service, LazyServiceGuard, diff --git a/libs/gui/OWNERS b/libs/gui/OWNERS index 826a418aab..070f6bf532 100644 --- a/libs/gui/OWNERS +++ b/libs/gui/OWNERS @@ -1,3 +1,5 @@ +# Bug component: 1075131 + chrisforbes@google.com jreck@google.com diff --git a/libs/renderengine/OWNERS b/libs/renderengine/OWNERS index 5d23a5ef8d..66e1aa1ca1 100644 --- a/libs/renderengine/OWNERS +++ b/libs/renderengine/OWNERS @@ -1,3 +1,5 @@ +# Bug component: 1075131 + adyabr@google.com alecmouri@google.com djsollen@google.com diff --git a/services/surfaceflinger/OWNERS b/services/surfaceflinger/OWNERS index 473409715f..3270e4c95c 100644 --- a/services/surfaceflinger/OWNERS +++ b/services/surfaceflinger/OWNERS @@ -1,3 +1,5 @@ +# Bug component: 1075131 + adyabr@google.com alecmouri@google.com chaviw@google.com |