diff options
24 files changed, 263 insertions, 179 deletions
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp index a999c9f22e..7ab2a8d03f 100644 --- a/cmds/dumpstate/dumpstate.cpp +++ b/cmds/dumpstate/dumpstate.cpp @@ -3027,11 +3027,14 @@ void Dumpstate::MaybeSnapshotSystemTrace() { } void Dumpstate::MaybeSnapshotWinTrace() { - RunCommand( - // Empty name because it's not intended to be classified as a bugreport section. - // Actual tracing files can be found in "/data/misc/wmtrace/" in the bugreport. - "", {"cmd", "window", "tracing", "save-for-bugreport"}, - CommandOptions::WithTimeout(10).Always().DropRoot().RedirectStderr().Build()); + // Currently WindowManagerService and InputMethodManagerSerivice support WinScope protocol. + for (const auto& service : {"window", "input_method"}) { + RunCommand( + // Empty name because it's not intended to be classified as a bugreport section. + // Actual tracing files can be found in "/data/misc/wmtrace/" in the bugreport. + "", {"cmd", service, "tracing", "save-for-bugreport"}, + CommandOptions::WithTimeout(10).Always().DropRoot().RedirectStderr().Build()); + } } void Dumpstate::onUiIntensiveBugreportDumpsFinished(int32_t calling_uid) { diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs index d53a88f726..3899d47bd6 100644 --- a/libs/binder/rust/src/binder.rs +++ b/libs/binder/rust/src/binder.rs @@ -33,13 +33,13 @@ use std::ptr; /// Binder action to perform. /// -/// This must be a number between [`IBinder::FIRST_CALL_TRANSACTION`] and -/// [`IBinder::LAST_CALL_TRANSACTION`]. +/// This must be a number between [`FIRST_CALL_TRANSACTION`] and +/// [`LAST_CALL_TRANSACTION`]. pub type TransactionCode = u32; /// Additional operation flags. /// -/// `IBinder::FLAG_*` values. +/// `FLAG_*` values. pub type TransactionFlags = u32; /// Super-trait for Binder interfaces. @@ -85,20 +85,22 @@ pub trait Remotable: Send + Sync { fn get_class() -> InterfaceClass; } -/// Interface of binder local or remote objects. -/// -/// This trait corresponds to the interface of the C++ `IBinder` class. -pub trait IBinder { - /// First transaction code available for user commands (inclusive) - const FIRST_CALL_TRANSACTION: TransactionCode = sys::FIRST_CALL_TRANSACTION; - /// Last transaction code available for user commands (inclusive) - const LAST_CALL_TRANSACTION: TransactionCode = sys::LAST_CALL_TRANSACTION; +/// First transaction code available for user commands (inclusive) +pub const FIRST_CALL_TRANSACTION: TransactionCode = sys::FIRST_CALL_TRANSACTION; +/// Last transaction code available for user commands (inclusive) +pub const LAST_CALL_TRANSACTION: TransactionCode = sys::LAST_CALL_TRANSACTION; - /// Corresponds to TF_ONE_WAY -- an asynchronous call. - const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY; - /// Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call is made. - const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF; +/// Corresponds to TF_ONE_WAY -- an asynchronous call. +pub const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY; +/// Corresponds to TF_CLEAR_BUF -- clear transaction buffers after call is made. +pub const FLAG_CLEAR_BUF: TransactionFlags = sys::FLAG_CLEAR_BUF; +/// Internal interface of binder local or remote objects for making +/// transactions. +/// +/// This trait corresponds to the parts of the interface of the C++ `IBinder` +/// class which are internal implementation details. +pub trait IBinderInternal: IBinder { /// Is this object still alive? fn is_binder_alive(&self) -> bool; @@ -122,19 +124,24 @@ pub trait IBinder { /// * `data` - [`Parcel`] with input data /// * `reply` - Optional [`Parcel`] for reply data /// * `flags` - Transaction flags, e.g. marking the transaction as - /// asynchronous ([`FLAG_ONEWAY`](IBinder::FLAG_ONEWAY)) + /// asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)) fn transact<F: FnOnce(&mut Parcel) -> Result<()>>( &self, code: TransactionCode, flags: TransactionFlags, input_callback: F, ) -> Result<Parcel>; +} +/// Interface of binder local or remote objects. +/// +/// This trait corresponds to the parts of the interface of the C++ `IBinder` +/// class which are public. +pub trait IBinder { /// Register the recipient for a notification if this binder /// goes away. If this binder object unexpectedly goes away /// (typically because its hosting process has been killed), - /// then DeathRecipient::binder_died() will be called with a reference - /// to this. + /// then the `DeathRecipient`'s callback will be called. /// /// You will only receive death notifications for remote binders, /// as local binders by definition can't die without you dying as well. @@ -142,11 +149,6 @@ pub trait IBinder { /// INVALID_OPERATION code being returned and nothing happening. /// /// This link always holds a weak reference to its recipient. - /// - /// You will only receive a weak reference to the dead - /// binder. You should not try to promote this to a strong reference. - /// (Nor should you need to, as there is nothing useful you can - /// directly do with it now that it has passed on.) fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>; /// Remove a previously registered death notification. @@ -222,7 +224,8 @@ impl InterfaceClass { // the number of u16 elements before the null terminator. let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0); - CStr::from_ptr(raw_descriptor).to_str() + CStr::from_ptr(raw_descriptor) + .to_str() .expect("Expected valid UTF-8 string from AIBinder_Class_getDescriptor") .into() } diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs index 43a237abf9..5bbd2a3870 100644 --- a/libs/binder/rust/src/lib.rs +++ b/libs/binder/rust/src/lib.rs @@ -107,8 +107,9 @@ use binder_ndk_sys as sys; pub mod parcel; pub use crate::binder::{ - FromIBinder, IBinder, Interface, InterfaceClass, Remotable, Strong, TransactionCode, - TransactionFlags, Weak, + FromIBinder, IBinder, IBinderInternal, Interface, InterfaceClass, Remotable, Strong, + TransactionCode, TransactionFlags, Weak, FIRST_CALL_TRANSACTION, FLAG_CLEAR_BUF, FLAG_ONEWAY, + LAST_CALL_TRANSACTION, }; pub use error::{status_t, ExceptionCode, Result, Status, StatusCode}; pub use native::add_service; @@ -123,8 +124,8 @@ pub mod public_api { pub use super::parcel::ParcelFileDescriptor; pub use super::{add_service, get_interface}; pub use super::{ - ExceptionCode, Interface, ProcessState, SpIBinder, Status, StatusCode, Strong, ThreadState, - Weak, WpIBinder, + DeathRecipient, ExceptionCode, IBinder, Interface, ProcessState, SpIBinder, Status, + StatusCode, Strong, ThreadState, Weak, WpIBinder, }; /// Binder result containing a [`Status`] on error. diff --git a/libs/binder/rust/src/proxy.rs b/libs/binder/rust/src/proxy.rs index 132e0758e1..52036f5312 100644 --- a/libs/binder/rust/src/proxy.rs +++ b/libs/binder/rust/src/proxy.rs @@ -17,7 +17,8 @@ //! Rust API for interacting with a remote binder service. use crate::binder::{ - AsNative, FromIBinder, IBinder, Interface, InterfaceClass, Strong, TransactionCode, TransactionFlags, + AsNative, FromIBinder, IBinder, IBinderInternal, Interface, InterfaceClass, Strong, + TransactionCode, TransactionFlags, }; use crate::error::{status_result, Result, StatusCode}; use crate::parcel::{ @@ -26,8 +27,8 @@ use crate::parcel::{ }; use crate::sys; -use std::convert::TryInto; use std::cmp::Ordering; +use std::convert::TryInto; use std::ffi::{c_void, CString}; use std::fmt; use std::os::unix::io::AsRawFd; @@ -211,7 +212,7 @@ impl Drop for SpIBinder { } } -impl<T: AsNative<sys::AIBinder>> IBinder for T { +impl<T: AsNative<sys::AIBinder>> IBinderInternal for T { /// Perform a binder transaction fn transact<F: FnOnce(&mut Parcel) -> Result<()>>( &self, @@ -300,9 +301,7 @@ impl<T: AsNative<sys::AIBinder>> IBinder for T { } fn set_requesting_sid(&mut self, enable: bool) { - unsafe { - sys::AIBinder_setRequestingSid(self.as_native_mut(), enable) - }; + unsafe { sys::AIBinder_setRequestingSid(self.as_native_mut(), enable) }; } fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()> { @@ -351,7 +350,9 @@ impl<T: AsNative<sys::AIBinder>> IBinder for T { status_result(status)?; Ok(ibinder) } +} +impl<T: AsNative<sys::AIBinder>> IBinder for T { fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> { status_result(unsafe { // Safety: `SpIBinder` guarantees that `self` always contains a @@ -472,7 +473,10 @@ impl Clone for WpIBinder { // WpIBinder object from it. sys::AIBinder_Weak_clone(self.0) }; - assert!(!ptr.is_null(), "Unexpected null pointer from AIBinder_Weak_clone"); + assert!( + !ptr.is_null(), + "Unexpected null pointer from AIBinder_Weak_clone" + ); Self(ptr) } } diff --git a/libs/binder/rust/tests/integration.rs b/libs/binder/rust/tests/integration.rs index 719229c9b7..60e3502759 100644 --- a/libs/binder/rust/tests/integration.rs +++ b/libs/binder/rust/tests/integration.rs @@ -18,7 +18,10 @@ use binder::declare_binder_interface; use binder::parcel::Parcel; -use binder::{Binder, IBinder, Interface, SpIBinder, StatusCode, ThreadState, TransactionCode}; +use binder::{ + Binder, IBinderInternal, Interface, StatusCode, ThreadState, TransactionCode, + FIRST_CALL_TRANSACTION, +}; use std::convert::{TryFrom, TryInto}; /// Name of service runner. @@ -83,7 +86,7 @@ struct TestService { #[repr(u32)] enum TestTransactionCode { - Test = SpIBinder::FIRST_CALL_TRANSACTION, + Test = FIRST_CALL_TRANSACTION, GetSelinuxContext, } @@ -196,7 +199,6 @@ impl ITestSameDescriptor for BpTestSameDescriptor {} impl ITestSameDescriptor for Binder<BnTestSameDescriptor> {} - #[cfg(test)] mod tests { use selinux_bindgen as selinux_sys; @@ -209,9 +211,12 @@ mod tests { use std::thread; use std::time::Duration; - use binder::{Binder, DeathRecipient, FromIBinder, IBinder, Interface, SpIBinder, StatusCode, Strong}; + use binder::{ + Binder, DeathRecipient, FromIBinder, IBinder, IBinderInternal, Interface, SpIBinder, + StatusCode, Strong, + }; - use super::{BnTest, ITest, ITestSameDescriptor, RUST_SERVICE_BINARY, TestService}; + use super::{BnTest, ITest, ITestSameDescriptor, TestService, RUST_SERVICE_BINARY}; pub struct ScopedServiceProcess(Child); @@ -290,7 +295,9 @@ mod tests { }; assert_eq!( test_client.get_selinux_context().unwrap(), - expected_context.to_str().expect("context was invalid UTF-8"), + expected_context + .to_str() + .expect("context was invalid UTF-8"), ); } @@ -479,18 +486,22 @@ mod tests { // This should succeed although we will have to treat the service as // remote. - let _interface: Strong<dyn ITestSameDescriptor> = FromIBinder::try_from(service.as_binder()) - .expect("Could not re-interpret service as the ITestSameDescriptor interface"); + let _interface: Strong<dyn ITestSameDescriptor> = + FromIBinder::try_from(service.as_binder()) + .expect("Could not re-interpret service as the ITestSameDescriptor interface"); } /// Test that we can round-trip a rust service through a generic IBinder #[test] fn reassociate_rust_binder() { let service_name = "testing_service"; - let service_ibinder = BnTest::new_binder(TestService { s: service_name.to_string() }) - .as_binder(); + let service_ibinder = BnTest::new_binder(TestService { + s: service_name.to_string(), + }) + .as_binder(); - let service: Strong<dyn ITest> = service_ibinder.into_interface() + let service: Strong<dyn ITest> = service_ibinder + .into_interface() .expect("Could not reassociate the generic ibinder"); assert_eq!(service.test().unwrap(), service_name); @@ -499,7 +510,9 @@ mod tests { #[test] fn weak_binder_upgrade() { let service_name = "testing_service"; - let service = BnTest::new_binder(TestService { s: service_name.to_string() }); + let service = BnTest::new_binder(TestService { + s: service_name.to_string(), + }); let weak = Strong::downgrade(&service); @@ -512,7 +525,9 @@ mod tests { fn weak_binder_upgrade_dead() { let service_name = "testing_service"; let weak = { - let service = BnTest::new_binder(TestService { s: service_name.to_string() }); + let service = BnTest::new_binder(TestService { + s: service_name.to_string(), + }); Strong::downgrade(&service) }; @@ -523,7 +538,9 @@ mod tests { #[test] fn weak_binder_clone() { let service_name = "testing_service"; - let service = BnTest::new_binder(TestService { s: service_name.to_string() }); + let service = BnTest::new_binder(TestService { + s: service_name.to_string(), + }); let weak = Strong::downgrade(&service); let cloned = weak.clone(); @@ -539,8 +556,12 @@ mod tests { #[test] #[allow(clippy::eq_op)] fn binder_ord() { - let service1 = BnTest::new_binder(TestService { s: "testing_service1".to_string() }); - let service2 = BnTest::new_binder(TestService { s: "testing_service2".to_string() }); + let service1 = BnTest::new_binder(TestService { + s: "testing_service1".to_string(), + }); + let service2 = BnTest::new_binder(TestService { + s: "testing_service2".to_string(), + }); assert!(!(service1 < service1)); assert!(!(service1 > service1)); diff --git a/libs/gui/FrameTimelineInfo.cpp b/libs/gui/FrameTimelineInfo.cpp index f40077403a..9231a570fc 100644 --- a/libs/gui/FrameTimelineInfo.cpp +++ b/libs/gui/FrameTimelineInfo.cpp @@ -21,6 +21,7 @@ #include <android/os/IInputConstants.h> #include <gui/FrameTimelineInfo.h> #include <gui/LayerState.h> +#include <private/gui/ParcelUtils.h> #include <utils/Errors.h> #include <cmath> diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index bb8124b65e..ceab6ec542 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -28,6 +28,7 @@ #include <gui/ISurfaceComposerClient.h> #include <gui/LayerDebugInfo.h> #include <gui/LayerState.h> +#include <private/gui/ParcelUtils.h> #include <stdint.h> #include <sys/types.h> #include <system/graphics.h> diff --git a/libs/gui/ITransactionCompletedListener.cpp b/libs/gui/ITransactionCompletedListener.cpp index 9b5be1f15a..b42793b8ac 100644 --- a/libs/gui/ITransactionCompletedListener.cpp +++ b/libs/gui/ITransactionCompletedListener.cpp @@ -17,9 +17,10 @@ #define LOG_TAG "ITransactionCompletedListener" //#define LOG_NDEBUG 0 -#include <gui/LayerState.h> #include <gui/ISurfaceComposer.h> #include <gui/ITransactionCompletedListener.h> +#include <gui/LayerState.h> +#include <private/gui/ParcelUtils.h> namespace android { diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 7a18ca61fe..665086f6ed 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -23,6 +23,7 @@ #include <gui/IGraphicBufferProducer.h> #include <gui/ISurfaceComposerClient.h> #include <gui/LayerState.h> +#include <private/gui/ParcelUtils.h> #include <utils/Errors.h> #include <cmath> diff --git a/libs/gui/ScreenCaptureResults.cpp b/libs/gui/ScreenCaptureResults.cpp index f3849bcdcd..e91f74f3d3 100644 --- a/libs/gui/ScreenCaptureResults.cpp +++ b/libs/gui/ScreenCaptureResults.cpp @@ -16,6 +16,8 @@ #include <gui/ScreenCaptureResults.h> +#include <private/gui/ParcelUtils.h> + namespace android::gui { status_t ScreenCaptureResults::writeToParcel(android::Parcel* parcel) const { diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 11fe49039d..7dc5e85c4d 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -39,6 +39,7 @@ #include <gui/LayerState.h> #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> +#include <private/gui/ParcelUtils.h> #include <ui/DisplayMode.h> #include <ui/DynamicDisplayInfo.h> @@ -470,9 +471,8 @@ SurfaceComposerClient::Transaction::Transaction(const Transaction& other) mForceSynchronous(other.mForceSynchronous), mTransactionNestCount(other.mTransactionNestCount), mAnimation(other.mAnimation), - mEarlyWakeup(other.mEarlyWakeup), - mExplicitEarlyWakeupStart(other.mExplicitEarlyWakeupStart), - mExplicitEarlyWakeupEnd(other.mExplicitEarlyWakeupEnd), + mEarlyWakeupStart(other.mEarlyWakeupStart), + mEarlyWakeupEnd(other.mEarlyWakeupEnd), mContainsBuffer(other.mContainsBuffer), mDesiredPresentTime(other.mDesiredPresentTime), mIsAutoTimestamp(other.mIsAutoTimestamp), @@ -501,9 +501,8 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel const uint32_t forceSynchronous = parcel->readUint32(); const uint32_t transactionNestCount = parcel->readUint32(); const bool animation = parcel->readBool(); - const bool earlyWakeup = parcel->readBool(); - const bool explicitEarlyWakeupStart = parcel->readBool(); - const bool explicitEarlyWakeupEnd = parcel->readBool(); + const bool earlyWakeupStart = parcel->readBool(); + const bool earlyWakeupEnd = parcel->readBool(); const bool containsBuffer = parcel->readBool(); const int64_t desiredPresentTime = parcel->readInt64(); const bool isAutoTimestamp = parcel->readBool(); @@ -578,9 +577,8 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel mForceSynchronous = forceSynchronous; mTransactionNestCount = transactionNestCount; mAnimation = animation; - mEarlyWakeup = earlyWakeup; - mExplicitEarlyWakeupStart = explicitEarlyWakeupStart; - mExplicitEarlyWakeupEnd = explicitEarlyWakeupEnd; + mEarlyWakeupStart = earlyWakeupStart; + mEarlyWakeupEnd = earlyWakeupEnd; mContainsBuffer = containsBuffer; mDesiredPresentTime = desiredPresentTime; mIsAutoTimestamp = isAutoTimestamp; @@ -610,9 +608,8 @@ status_t SurfaceComposerClient::Transaction::writeToParcel(Parcel* parcel) const parcel->writeUint32(mForceSynchronous); parcel->writeUint32(mTransactionNestCount); parcel->writeBool(mAnimation); - parcel->writeBool(mEarlyWakeup); - parcel->writeBool(mExplicitEarlyWakeupStart); - parcel->writeBool(mExplicitEarlyWakeupEnd); + parcel->writeBool(mEarlyWakeupStart); + parcel->writeBool(mEarlyWakeupEnd); parcel->writeBool(mContainsBuffer); parcel->writeInt64(mDesiredPresentTime); parcel->writeBool(mIsAutoTimestamp); @@ -690,9 +687,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Tr mInputWindowCommands.merge(other.mInputWindowCommands); mContainsBuffer |= other.mContainsBuffer; - mEarlyWakeup = mEarlyWakeup || other.mEarlyWakeup; - mExplicitEarlyWakeupStart = mExplicitEarlyWakeupStart || other.mExplicitEarlyWakeupStart; - mExplicitEarlyWakeupEnd = mExplicitEarlyWakeupEnd || other.mExplicitEarlyWakeupEnd; + mEarlyWakeupStart = mEarlyWakeupStart || other.mEarlyWakeupStart; + mEarlyWakeupEnd = mEarlyWakeupEnd || other.mEarlyWakeupEnd; mApplyToken = other.mApplyToken; mFrameTimelineInfo.merge(other.mFrameTimelineInfo); @@ -710,9 +706,8 @@ void SurfaceComposerClient::Transaction::clear() { mForceSynchronous = 0; mTransactionNestCount = 0; mAnimation = false; - mEarlyWakeup = false; - mExplicitEarlyWakeupStart = false; - mExplicitEarlyWakeupEnd = false; + mEarlyWakeupStart = false; + mEarlyWakeupEnd = false; mDesiredPresentTime = 0; mIsAutoTimestamp = true; mFrameTimelineInfo.clear(); @@ -831,17 +826,14 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { if (mAnimation) { flags |= ISurfaceComposer::eAnimation; } - if (mEarlyWakeup) { - flags |= ISurfaceComposer::eEarlyWakeup; - } - // If both mExplicitEarlyWakeupStart and mExplicitEarlyWakeupEnd are set + // If both mEarlyWakeupStart and mEarlyWakeupEnd are set // it is equivalent for none - if (mExplicitEarlyWakeupStart && !mExplicitEarlyWakeupEnd) { - flags |= ISurfaceComposer::eExplicitEarlyWakeupStart; + if (mEarlyWakeupStart && !mEarlyWakeupEnd) { + flags |= ISurfaceComposer::eEarlyWakeupStart; } - if (mExplicitEarlyWakeupEnd && !mExplicitEarlyWakeupStart) { - flags |= ISurfaceComposer::eExplicitEarlyWakeupEnd; + if (mEarlyWakeupEnd && !mEarlyWakeupStart) { + flags |= ISurfaceComposer::eEarlyWakeupEnd; } sp<IBinder> applyToken = mApplyToken @@ -892,16 +884,12 @@ void SurfaceComposerClient::Transaction::setAnimationTransaction() { mAnimation = true; } -void SurfaceComposerClient::Transaction::setEarlyWakeup() { - mEarlyWakeup = true; -} - -void SurfaceComposerClient::Transaction::setExplicitEarlyWakeupStart() { - mExplicitEarlyWakeupStart = true; +void SurfaceComposerClient::Transaction::setEarlyWakeupStart() { + mEarlyWakeupStart = true; } -void SurfaceComposerClient::Transaction::setExplicitEarlyWakeupEnd() { - mExplicitEarlyWakeupEnd = true; +void SurfaceComposerClient::Transaction::setEarlyWakeupEnd() { + mEarlyWakeupEnd = true; } layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp<SurfaceControl>& sc) { diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index 1dcfe2e804..7e2f8f9d36 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -39,6 +39,7 @@ #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> #include <gui/SurfaceControl.h> +#include <private/gui/ParcelUtils.h> namespace android { diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 2a9e3f7923..35990d171a 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -90,18 +90,15 @@ public: eSynchronous = 0x01, eAnimation = 0x02, - // DEPRECATED - use eExplicitEarlyWakeup[Start|End] - eEarlyWakeup = 0x04, - // Explicit indication that this transaction and others to follow will likely result in a // lot of layers being composed, and thus, SurfaceFlinger should wake-up earlier to avoid // missing frame deadlines. In this case SurfaceFlinger will wake up at // (sf vsync offset - debug.sf.early_phase_offset_ns). SurfaceFlinger will continue to be - // in the early configuration until it receives eExplicitEarlyWakeupEnd. These flags are + // in the early configuration until it receives eEarlyWakeupEnd. These flags are // expected to be used by WindowManager only and are guarded by // android.permission.ACCESS_SURFACE_FLINGER - eExplicitEarlyWakeupStart = 0x08, - eExplicitEarlyWakeupEnd = 0x10, + eEarlyWakeupStart = 0x08, + eEarlyWakeupEnd = 0x10, }; enum VsyncSource { diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index d68a9cfa4a..99b3ea5250 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -16,23 +16,7 @@ #ifndef ANDROID_SF_LAYER_STATE_H #define ANDROID_SF_LAYER_STATE_H -#define SAFE_PARCEL(FUNC, ...) \ - { \ - status_t error = FUNC(__VA_ARGS__); \ - if (error) { \ - ALOGE("ERROR(%d). Failed to call parcel %s(%s)", error, #FUNC, #__VA_ARGS__); \ - return error; \ - } \ - } - -#define SAFE_PARCEL_READ_SIZE(FUNC, COUNT, SIZE) \ - { \ - SAFE_PARCEL(FUNC, COUNT); \ - if (static_cast<unsigned int>(*COUNT) > SIZE) { \ - ALOGE("ERROR(BAD_VALUE). %s was greater than dataSize", #COUNT); \ - return BAD_VALUE; \ - } \ - } + #include <stdint.h> #include <sys/types.h> diff --git a/libs/gui/include/gui/ScreenCaptureResults.h b/libs/gui/include/gui/ScreenCaptureResults.h index 0ccc6e8b8a..99c35c1a3d 100644 --- a/libs/gui/include/gui/ScreenCaptureResults.h +++ b/libs/gui/include/gui/ScreenCaptureResults.h @@ -16,15 +16,6 @@ #pragma once -#define SAFE_PARCEL(FUNC, ...) \ - { \ - status_t error = FUNC(__VA_ARGS__); \ - if (error) { \ - ALOGE("ERROR(%d). Failed to call parcel %s(%s)", error, #FUNC, #__VA_ARGS__); \ - return error; \ - } \ - } - #include <binder/Parcel.h> #include <binder/Parcelable.h> #include <ui/Fence.h> diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index f29983cef7..a91de9c645 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -353,9 +353,8 @@ public: uint32_t mForceSynchronous = 0; uint32_t mTransactionNestCount = 0; bool mAnimation = false; - bool mEarlyWakeup = false; - bool mExplicitEarlyWakeupStart = false; - bool mExplicitEarlyWakeupEnd = false; + bool mEarlyWakeupStart = false; + bool mEarlyWakeupEnd = false; // Indicates that the Transaction contains a buffer that should be cached bool mContainsBuffer = false; @@ -567,9 +566,8 @@ public: const Rect& layerStackRect, const Rect& displayRect); void setDisplaySize(const sp<IBinder>& token, uint32_t width, uint32_t height); void setAnimationTransaction(); - void setEarlyWakeup(); - void setExplicitEarlyWakeupStart(); - void setExplicitEarlyWakeupEnd(); + void setEarlyWakeupStart(); + void setEarlyWakeupEnd(); }; status_t clearLayerFrameStats(const sp<IBinder>& token) const; diff --git a/libs/gui/include/private/gui/ParcelUtils.h b/libs/gui/include/private/gui/ParcelUtils.h new file mode 100644 index 0000000000..1cdd07e36e --- /dev/null +++ b/libs/gui/include/private/gui/ParcelUtils.h @@ -0,0 +1,38 @@ +/* + * Copyright 2021 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 <cstring> + +#define SAFE_PARCEL(FUNC, ...) \ + { \ + status_t error = FUNC(__VA_ARGS__); \ + if (error) { \ + ALOGE("ERROR(%s, %d). Failed to call parcel %s(%s)", strerror(-error), error, #FUNC, \ + #__VA_ARGS__); \ + return error; \ + } \ + } + +#define SAFE_PARCEL_READ_SIZE(FUNC, COUNT, SIZE) \ + { \ + SAFE_PARCEL(FUNC, COUNT); \ + if (static_cast<unsigned int>(*COUNT) > SIZE) { \ + ALOGE("ERROR(BAD_VALUE). %s was greater than dataSize", #COUNT); \ + return BAD_VALUE; \ + } \ + }
\ No newline at end of file diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp index 908aae3c15..afdcd76552 100644 --- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp +++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp @@ -298,11 +298,9 @@ SkiaGLRenderEngine::SkiaGLRenderEngine(const RenderEngineCreationArgs& args, EGL } SkiaGLRenderEngine::~SkiaGLRenderEngine() { - std::lock_guard<std::mutex> lock(mRenderingMutex); - mRuntimeEffects.clear(); - mProtectedTextureCache.clear(); - mTextureCache.clear(); + cleanFramebufferCache(); + std::lock_guard<std::mutex> lock(mRenderingMutex); if (mBlurFilter) { delete mBlurFilter; } @@ -1143,7 +1141,14 @@ EGLSurface SkiaGLRenderEngine::createPlaceholderEglPbufferSurface(EGLDisplay dis return eglCreatePbufferSurface(display, placeholderConfig, attributes.data()); } -void SkiaGLRenderEngine::cleanFramebufferCache() {} +void SkiaGLRenderEngine::cleanFramebufferCache() { + // TODO(b/180767535) Remove this method and use b/180767535 instead, which would allow + // SF to control texture lifecycle more tightly rather than through custom hooks into RE. + std::lock_guard<std::mutex> lock(mRenderingMutex); + mRuntimeEffects.clear(); + mProtectedTextureCache.clear(); + mTextureCache.clear(); +} int SkiaGLRenderEngine::getContextPriority() { int value; diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index 89dfb6fb6b..b8aad61312 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -404,7 +404,16 @@ bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence mCurrentState.desiredPresentTime = desiredPresentTime; mCurrentState.isAutoTimestamp = isAutoTimestamp; - mFlinger->mScheduler->recordLayerHistory(this, isAutoTimestamp ? 0 : desiredPresentTime, + const nsecs_t presentTime = [&] { + if (!isAutoTimestamp) return desiredPresentTime; + + const auto prediction = + mFlinger->mFrameTimeline->getTokenManager()->getPredictionsForToken(info.vsyncId); + if (prediction.has_value()) return prediction->presentTime; + + return static_cast<nsecs_t>(0); + }(); + mFlinger->mScheduler->recordLayerHistory(this, presentTime, LayerHistory::LayerUpdateType::Buffer); addFrameEvent(acquireFence, postTime, isAutoTimestamp ? 0 : desiredPresentTime); diff --git a/services/surfaceflinger/Scheduler/VsyncModulator.cpp b/services/surfaceflinger/Scheduler/VsyncModulator.cpp index 1f821be504..194d808836 100644 --- a/services/surfaceflinger/Scheduler/VsyncModulator.cpp +++ b/services/surfaceflinger/Scheduler/VsyncModulator.cpp @@ -50,24 +50,23 @@ VsyncModulator::VsyncConfigOpt VsyncModulator::setTransactionSchedule( TransactionSchedule schedule) { switch (schedule) { case Schedule::EarlyStart: - ALOGW_IF(mExplicitEarlyWakeup, "%s: Duplicate EarlyStart", __FUNCTION__); - mExplicitEarlyWakeup = true; + ALOGW_IF(mEarlyWakeup, "%s: Duplicate EarlyStart", __FUNCTION__); + mEarlyWakeup = true; break; case Schedule::EarlyEnd: - ALOGW_IF(!mExplicitEarlyWakeup, "%s: Unexpected EarlyEnd", __FUNCTION__); - mExplicitEarlyWakeup = false; + ALOGW_IF(!mEarlyWakeup, "%s: Unexpected EarlyEnd", __FUNCTION__); + mEarlyWakeup = false; break; - case Schedule::Early: case Schedule::Late: - // No change to mExplicitEarlyWakeup for non-explicit states. + // No change to mEarlyWakeup for non-explicit states. break; } if (mTraceDetailedInfo) { - ATRACE_INT("mExplicitEarlyWakeup", mExplicitEarlyWakeup); + ATRACE_INT("mEarlyWakeup", mEarlyWakeup); } - if (!mExplicitEarlyWakeup && (schedule == Schedule::Early || schedule == Schedule::EarlyEnd)) { + if (!mEarlyWakeup && schedule == Schedule::EarlyEnd) { mEarlyTransactionFrames = MIN_EARLY_TRANSACTION_FRAMES; mEarlyTransactionStartTime = mNow(); } @@ -129,8 +128,8 @@ VsyncModulator::VsyncConfig VsyncModulator::getVsyncConfig() const { const VsyncModulator::VsyncConfig& VsyncModulator::getNextVsyncConfig() const { // Early offsets are used if we're in the middle of a refresh rate // change, or if we recently begin a transaction. - if (mExplicitEarlyWakeup || mTransactionSchedule == Schedule::EarlyEnd || - mEarlyTransactionFrames > 0 || mRefreshRateChangePending) { + if (mEarlyWakeup || mTransactionSchedule == Schedule::EarlyEnd || mEarlyTransactionFrames > 0 || + mRefreshRateChangePending) { return mVsyncConfigSet.early; } else if (mEarlyGpuFrames > 0) { return mVsyncConfigSet.earlyGpu; diff --git a/services/surfaceflinger/Scheduler/VsyncModulator.h b/services/surfaceflinger/Scheduler/VsyncModulator.h index 355a14adf8..fcde279070 100644 --- a/services/surfaceflinger/Scheduler/VsyncModulator.h +++ b/services/surfaceflinger/Scheduler/VsyncModulator.h @@ -30,7 +30,6 @@ namespace android::scheduler { // fixed number of frames, respectively. enum class TransactionSchedule { Late, // Default. - Early, // Deprecated. EarlyStart, EarlyEnd }; @@ -114,7 +113,7 @@ private: using Schedule = TransactionSchedule; std::atomic<Schedule> mTransactionSchedule = Schedule::Late; - std::atomic<bool> mExplicitEarlyWakeup = false; + std::atomic<bool> mEarlyWakeup = false; std::atomic<bool> mRefreshRateChangePending = false; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 61cc8a2ff0..ed27783679 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -23,6 +23,7 @@ #define ATRACE_TAG ATRACE_TAG_GRAPHICS #include "SurfaceFlinger.h" +#include "TraceUtils.h" #include <android-base/properties.h> #include <android/configuration.h> @@ -79,7 +80,6 @@ #include <utils/String16.h> #include <utils/String8.h> #include <utils/Timers.h> -#include <utils/Trace.h> #include <utils/misc.h> #include <algorithm> @@ -1689,7 +1689,12 @@ nsecs_t SurfaceFlinger::calculateExpectedPresentTime(DisplayStatInfo stats) cons } void SurfaceFlinger::onMessageReceived(int32_t what, int64_t vsyncId, nsecs_t expectedVSyncTime) { - ATRACE_CALL(); + const auto vsyncIn = [&] { + if (!ATRACE_ENABLED()) return 0.f; + return (expectedVSyncTime - systemTime()) / 1e6f; + }(); + + ATRACE_FORMAT("onMessageReceived %" PRId64 " vsyncIn %.2fms", vsyncId, vsyncIn); switch (what) { case MessageQueue::INVALIDATE: { onMessageInvalidate(vsyncId, expectedVSyncTime); @@ -2975,7 +2980,7 @@ void SurfaceFlinger::initScheduler(const DisplayDeviceState& displayState) { mRefreshRateConfigs = std::make_unique< scheduler::RefreshRateConfigs>(displayState.physical->supportedModes, displayState.physical->activeMode->getId(), - android::sysprop::enable_frame_rate_override(true)); + android::sysprop::enable_frame_rate_override(false)); const auto currRefreshRate = displayState.physical->activeMode->getFps(); mRefreshRateStats = std::make_unique<scheduler::RefreshRateStats>(*mTimeStats, currRefreshRate, hal::PowerMode::OFF); @@ -3471,9 +3476,8 @@ void SurfaceFlinger::queueTransaction(TransactionState& state) { ATRACE_INT("TransactionQueue", mTransactionQueue.size()); const auto schedule = [](uint32_t flags) { - if (flags & eEarlyWakeup) return TransactionSchedule::Early; - if (flags & eExplicitEarlyWakeupEnd) return TransactionSchedule::EarlyEnd; - if (flags & eExplicitEarlyWakeupStart) return TransactionSchedule::EarlyStart; + if (flags & eEarlyWakeupEnd) return TransactionSchedule::EarlyEnd; + if (flags & eEarlyWakeupStart) return TransactionSchedule::EarlyStart; return TransactionSchedule::Late; }(state.flags); @@ -3525,15 +3529,10 @@ status_t SurfaceFlinger::setTransactionState( permissions |= Permission::ROTATE_SURFACE_FLINGER; } - // TODO(b/159125966): Remove eEarlyWakeup completely as no client should use this flag - if (flags & eEarlyWakeup) { - ALOGW("eEarlyWakeup is deprecated. Use eExplicitEarlyWakeup[Start|End]"); - } - if (!(permissions & Permission::ACCESS_SURFACE_FLINGER) && - (flags & (eExplicitEarlyWakeupStart | eExplicitEarlyWakeupEnd))) { - ALOGE("Only WindowManager is allowed to use eExplicitEarlyWakeup[Start|End] flags"); - flags &= ~(eExplicitEarlyWakeupStart | eExplicitEarlyWakeupEnd); + (flags & (eEarlyWakeupStart | eEarlyWakeupEnd))) { + ALOGE("Only WindowManager is allowed to use eEarlyWakeup[Start|End] flags"); + flags &= ~(eEarlyWakeupStart | eEarlyWakeupEnd); } const int64_t postTime = systemTime(); diff --git a/services/surfaceflinger/TraceUtils.h b/services/surfaceflinger/TraceUtils.h new file mode 100644 index 0000000000..90a34a5ed8 --- /dev/null +++ b/services/surfaceflinger/TraceUtils.h @@ -0,0 +1,56 @@ +/* + * Copyright 2021 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. + */ + +// TODO(b/183120308): This file is a copy of f/b/libs/hwui/utils/TraceUtils.h +// It should be migrated to a common place where both SF and hwui could use it. + +#pragma once + +#include <cutils/trace.h> +#include <utils/Trace.h> + +#define ATRACE_FORMAT(fmt, ...) \ + TraceUtils::TraceEnder __traceEnder = \ + (TraceUtils::atraceFormatBegin(fmt, ##__VA_ARGS__), TraceUtils::TraceEnder()) + +#define ATRACE_FORMAT_BEGIN(fmt, ...) TraceUtils::atraceFormatBegin(fmt, ##__VA_ARGS__) + +namespace android { + +class TraceUtils { +public: + class TraceEnder { + public: + ~TraceEnder() { ATRACE_END(); } + }; + + static void atraceFormatBegin(const char* fmt, ...) { + if (CC_LIKELY(!ATRACE_ENABLED())) return; + + const int BUFFER_SIZE = 256; + va_list ap; + char buf[BUFFER_SIZE]; + + va_start(ap, fmt); + vsnprintf(buf, BUFFER_SIZE, fmt, ap); + va_end(ap); + + ATRACE_BEGIN(buf); + } + +}; // class TraceUtils + +} /* namespace android */ diff --git a/services/surfaceflinger/tests/unittests/VsyncModulatorTest.cpp b/services/surfaceflinger/tests/unittests/VsyncModulatorTest.cpp index 106da81076..17648d532e 100644 --- a/services/surfaceflinger/tests/unittests/VsyncModulatorTest.cpp +++ b/services/surfaceflinger/tests/unittests/VsyncModulatorTest.cpp @@ -101,24 +101,6 @@ TEST_F(VsyncModulatorTest, EarlyStart) { CHECK_REFRESH(1, kLate, kLate); } -TEST_F(VsyncModulatorTest, EarlyStartWithEarly) { - EXPECT_EQ(kEarly, mVsyncModulator.setTransactionSchedule(Schedule::EarlyStart)); - - CHECK_COMMIT(kEarly, kEarly); - CHECK_REFRESH(5 * MIN_EARLY_TRANSACTION_FRAMES, std::nullopt, kEarly); - - EXPECT_EQ(kEarly, mVsyncModulator.setTransactionSchedule(Schedule::Early)); - - CHECK_COMMIT(kEarly, kEarly); - CHECK_REFRESH(5 * MIN_EARLY_TRANSACTION_FRAMES, std::nullopt, kEarly); - - EXPECT_EQ(kEarly, mVsyncModulator.setTransactionSchedule(Schedule::EarlyEnd)); - - CHECK_COMMIT(kEarly, kEarly); - CHECK_REFRESH(MIN_EARLY_TRANSACTION_FRAMES - 1, kEarly, kEarly); - CHECK_REFRESH(1, kLate, kLate); -} - TEST_F(VsyncModulatorTest, EarlyStartWithMoreTransactions) { EXPECT_EQ(kEarly, mVsyncModulator.setTransactionSchedule(Schedule::EarlyStart)); |