Merge "Switch from setSupports... to setBlurAlgorithm" into main
diff --git a/include/android/performance_hint.h b/include/android/performance_hint.h
index 3c82d88..97e4dc0 100644
--- a/include/android/performance_hint.h
+++ b/include/android/performance_hint.h
@@ -114,6 +114,9 @@
* API, the client is expected to call {@link APerformanceHint_reportActualWorkDuration} each
* cycle to report the actual time taken to complete to the system.
*
+ * Note, methods of {@link APerformanceHintSession_*} are not thread safe so callers must
+ * ensure thread safety.
+ *
* All timings should be from `std::chrono::steady_clock` or `clock_gettime(CLOCK_MONOTONIC, ...)`
*/
typedef struct APerformanceHintSession APerformanceHintSession;
diff --git a/libs/binder/rust/rpcbinder/Android.bp b/libs/binder/rust/rpcbinder/Android.bp
index 535ce01..2e46345 100644
--- a/libs/binder/rust/rpcbinder/Android.bp
+++ b/libs/binder/rust/rpcbinder/Android.bp
@@ -18,6 +18,7 @@
"libbinder_ndk_sys",
"libbinder_rpc_unstable_bindgen_sys",
"libbinder_rs",
+ "libcfg_if",
"libdowncast_rs",
"libforeign_types",
"liblibc",
diff --git a/libs/binder/rust/rpcbinder/src/lib.rs b/libs/binder/rust/rpcbinder/src/lib.rs
index 163f000..7e5c9dd 100644
--- a/libs/binder/rust/rpcbinder/src/lib.rs
+++ b/libs/binder/rust/rpcbinder/src/lib.rs
@@ -16,10 +16,10 @@
//! API for RPC Binder services.
-#[cfg(not(target_os = "trusty"))]
mod server;
mod session;
+pub use server::RpcServer;
#[cfg(not(target_os = "trusty"))]
-pub use server::{RpcServer, RpcServerRef};
+pub use server::RpcServerRef;
pub use session::{FileDescriptorTransportMode, RpcSession, RpcSessionRef};
diff --git a/libs/binder/rust/rpcbinder/src/server.rs b/libs/binder/rust/rpcbinder/src/server.rs
index 6fda878..d6bdbd8 100644
--- a/libs/binder/rust/rpcbinder/src/server.rs
+++ b/libs/binder/rust/rpcbinder/src/server.rs
@@ -14,160 +14,12 @@
* limitations under the License.
*/
-use crate::session::FileDescriptorTransportMode;
-use binder::{unstable_api::AsNative, SpIBinder};
-use binder_rpc_unstable_bindgen::ARpcServer;
-use foreign_types::{foreign_type, ForeignType, ForeignTypeRef};
-use std::ffi::CString;
-use std::io::{Error, ErrorKind};
-use std::os::unix::io::{IntoRawFd, OwnedFd};
-
-foreign_type! {
- type CType = binder_rpc_unstable_bindgen::ARpcServer;
- fn drop = binder_rpc_unstable_bindgen::ARpcServer_free;
-
- /// A type that represents a foreign instance of RpcServer.
- #[derive(Debug)]
- pub struct RpcServer;
- /// A borrowed RpcServer.
- pub struct RpcServerRef;
-}
-
-/// SAFETY: The opaque handle can be cloned freely.
-unsafe impl Send for RpcServer {}
-/// SAFETY: The underlying C++ RpcServer class is thread-safe.
-unsafe impl Sync for RpcServer {}
-
-impl RpcServer {
- /// Creates a binder RPC server, serving the supplied binder service implementation on the given
- /// vsock port. Only connections from the given CID are accepted.
- ///
- // Set `cid` to libc::VMADDR_CID_ANY to accept connections from any client.
- // Set `cid` to libc::VMADDR_CID_LOCAL to only bind to the local vsock interface.
- pub fn new_vsock(mut service: SpIBinder, cid: u32, port: u32) -> Result<RpcServer, Error> {
- let service = service.as_native_mut();
-
- // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
- // Plus the binder objects are threadsafe.
- unsafe {
- Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newVsock(
- service, cid, port,
- ))
- }
- }
-
- /// Creates a binder RPC server, serving the supplied binder service implementation on the given
- /// socket file descriptor. The socket should be bound to an address before calling this
- /// function.
- pub fn new_bound_socket(
- mut service: SpIBinder,
- socket_fd: OwnedFd,
- ) -> Result<RpcServer, Error> {
- let service = service.as_native_mut();
-
- // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
- // Plus the binder objects are threadsafe.
- // The server takes ownership of the socket FD.
- unsafe {
- Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newBoundSocket(
- service,
- socket_fd.into_raw_fd(),
- ))
- }
- }
-
- /// Creates a binder RPC server that bootstraps sessions using an existing Unix domain socket
- /// pair, with a given root IBinder object. Callers should create a pair of SOCK_STREAM Unix
- /// domain sockets, pass one to the server and the other to the client. Multiple client session
- /// can be created from the client end of the pair.
- pub fn new_unix_domain_bootstrap(
- mut service: SpIBinder,
- bootstrap_fd: OwnedFd,
- ) -> Result<RpcServer, Error> {
- let service = service.as_native_mut();
-
- // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
- // Plus the binder objects are threadsafe.
- // The server takes ownership of the bootstrap FD.
- unsafe {
- Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newUnixDomainBootstrap(
- service,
- bootstrap_fd.into_raw_fd(),
- ))
- }
- }
-
- /// Creates a binder RPC server, serving the supplied binder service implementation on the given
- /// IP address and port.
- pub fn new_inet(mut service: SpIBinder, address: &str, port: u32) -> Result<RpcServer, Error> {
- let address = match CString::new(address) {
- Ok(s) => s,
- Err(e) => {
- log::error!("Cannot convert {} to CString. Error: {:?}", address, e);
- return Err(Error::from(ErrorKind::InvalidInput));
- }
- };
- let service = service.as_native_mut();
-
- // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
- // Plus the binder objects are threadsafe.
- unsafe {
- Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newInet(
- service,
- address.as_ptr(),
- port,
- ))
- }
- }
-
- unsafe fn checked_from_ptr(ptr: *mut ARpcServer) -> Result<RpcServer, Error> {
- if ptr.is_null() {
- return Err(Error::new(ErrorKind::Other, "Failed to start server"));
- }
- // SAFETY: Our caller must pass us a valid or null pointer, and we've checked that it's not
- // null.
- Ok(unsafe { RpcServer::from_ptr(ptr) })
- }
-}
-
-impl RpcServerRef {
- /// Sets the list of file descriptor transport modes supported by this server.
- pub fn set_supported_file_descriptor_transport_modes(
- &self,
- modes: &[FileDescriptorTransportMode],
- ) {
- // SAFETY: Does not keep the pointer after returning does, nor does it
- // read past its boundary. Only passes the 'self' pointer as an opaque handle.
- unsafe {
- binder_rpc_unstable_bindgen::ARpcServer_setSupportedFileDescriptorTransportModes(
- self.as_ptr(),
- modes.as_ptr(),
- modes.len(),
- )
- }
- }
-
- /// Starts a new background thread and calls join(). Returns immediately.
- pub fn start(&self) {
- // SAFETY: RpcServerRef wraps a valid pointer to an ARpcServer.
- unsafe { binder_rpc_unstable_bindgen::ARpcServer_start(self.as_ptr()) };
- }
-
- /// Joins the RpcServer thread. The call blocks until the server terminates.
- /// This must be called from exactly one thread.
- pub fn join(&self) {
- // SAFETY: RpcServerRef wraps a valid pointer to an ARpcServer.
- unsafe { binder_rpc_unstable_bindgen::ARpcServer_join(self.as_ptr()) };
- }
-
- /// Shuts down the running RpcServer. Can be called multiple times and from
- /// multiple threads. Called automatically during drop().
- pub fn shutdown(&self) -> Result<(), Error> {
- // SAFETY: RpcServerRef wraps a valid pointer to an ARpcServer.
- if unsafe { binder_rpc_unstable_bindgen::ARpcServer_shutdown(self.as_ptr()) } {
- Ok(())
- } else {
- Err(Error::from(ErrorKind::UnexpectedEof))
- }
+cfg_if::cfg_if! {
+ if #[cfg(target_os = "trusty")] {
+ mod trusty;
+ pub use trusty::*;
+ } else {
+ mod android;
+ pub use android::*;
}
}
diff --git a/libs/binder/rust/rpcbinder/src/server/android.rs b/libs/binder/rust/rpcbinder/src/server/android.rs
new file mode 100644
index 0000000..ad0365b
--- /dev/null
+++ b/libs/binder/rust/rpcbinder/src/server/android.rs
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+use crate::session::FileDescriptorTransportMode;
+use binder::{unstable_api::AsNative, SpIBinder};
+use binder_rpc_unstable_bindgen::ARpcServer;
+use foreign_types::{foreign_type, ForeignType, ForeignTypeRef};
+use std::ffi::CString;
+use std::io::{Error, ErrorKind};
+use std::os::unix::io::{IntoRawFd, OwnedFd};
+
+foreign_type! {
+ type CType = binder_rpc_unstable_bindgen::ARpcServer;
+ fn drop = binder_rpc_unstable_bindgen::ARpcServer_free;
+
+ /// A type that represents a foreign instance of RpcServer.
+ #[derive(Debug)]
+ pub struct RpcServer;
+ /// A borrowed RpcServer.
+ pub struct RpcServerRef;
+}
+
+/// SAFETY: The opaque handle can be cloned freely.
+unsafe impl Send for RpcServer {}
+/// SAFETY: The underlying C++ RpcServer class is thread-safe.
+unsafe impl Sync for RpcServer {}
+
+impl RpcServer {
+ /// Creates a binder RPC server, serving the supplied binder service implementation on the given
+ /// vsock port. Only connections from the given CID are accepted.
+ ///
+ // Set `cid` to libc::VMADDR_CID_ANY to accept connections from any client.
+ // Set `cid` to libc::VMADDR_CID_LOCAL to only bind to the local vsock interface.
+ pub fn new_vsock(mut service: SpIBinder, cid: u32, port: u32) -> Result<RpcServer, Error> {
+ let service = service.as_native_mut();
+
+ // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
+ // Plus the binder objects are threadsafe.
+ unsafe {
+ Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newVsock(
+ service, cid, port,
+ ))
+ }
+ }
+
+ /// Creates a binder RPC server, serving the supplied binder service implementation on the given
+ /// socket file descriptor. The socket should be bound to an address before calling this
+ /// function.
+ pub fn new_bound_socket(
+ mut service: SpIBinder,
+ socket_fd: OwnedFd,
+ ) -> Result<RpcServer, Error> {
+ let service = service.as_native_mut();
+
+ // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
+ // Plus the binder objects are threadsafe.
+ // The server takes ownership of the socket FD.
+ unsafe {
+ Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newBoundSocket(
+ service,
+ socket_fd.into_raw_fd(),
+ ))
+ }
+ }
+
+ /// Creates a binder RPC server that bootstraps sessions using an existing Unix domain socket
+ /// pair, with a given root IBinder object. Callers should create a pair of SOCK_STREAM Unix
+ /// domain sockets, pass one to the server and the other to the client. Multiple client session
+ /// can be created from the client end of the pair.
+ pub fn new_unix_domain_bootstrap(
+ mut service: SpIBinder,
+ bootstrap_fd: OwnedFd,
+ ) -> Result<RpcServer, Error> {
+ let service = service.as_native_mut();
+
+ // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
+ // Plus the binder objects are threadsafe.
+ // The server takes ownership of the bootstrap FD.
+ unsafe {
+ Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newUnixDomainBootstrap(
+ service,
+ bootstrap_fd.into_raw_fd(),
+ ))
+ }
+ }
+
+ /// Creates a binder RPC server, serving the supplied binder service implementation on the given
+ /// IP address and port.
+ pub fn new_inet(mut service: SpIBinder, address: &str, port: u32) -> Result<RpcServer, Error> {
+ let address = match CString::new(address) {
+ Ok(s) => s,
+ Err(e) => {
+ log::error!("Cannot convert {} to CString. Error: {:?}", address, e);
+ return Err(Error::from(ErrorKind::InvalidInput));
+ }
+ };
+ let service = service.as_native_mut();
+
+ // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
+ // Plus the binder objects are threadsafe.
+ unsafe {
+ Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newInet(
+ service,
+ address.as_ptr(),
+ port,
+ ))
+ }
+ }
+
+ unsafe fn checked_from_ptr(ptr: *mut ARpcServer) -> Result<RpcServer, Error> {
+ if ptr.is_null() {
+ return Err(Error::new(ErrorKind::Other, "Failed to start server"));
+ }
+ // SAFETY: Our caller must pass us a valid or null pointer, and we've checked that it's not
+ // null.
+ Ok(unsafe { RpcServer::from_ptr(ptr) })
+ }
+}
+
+impl RpcServerRef {
+ /// Sets the list of file descriptor transport modes supported by this server.
+ pub fn set_supported_file_descriptor_transport_modes(
+ &self,
+ modes: &[FileDescriptorTransportMode],
+ ) {
+ // SAFETY: Does not keep the pointer after returning does, nor does it
+ // read past its boundary. Only passes the 'self' pointer as an opaque handle.
+ unsafe {
+ binder_rpc_unstable_bindgen::ARpcServer_setSupportedFileDescriptorTransportModes(
+ self.as_ptr(),
+ modes.as_ptr(),
+ modes.len(),
+ )
+ }
+ }
+
+ /// Starts a new background thread and calls join(). Returns immediately.
+ pub fn start(&self) {
+ // SAFETY: RpcServerRef wraps a valid pointer to an ARpcServer.
+ unsafe { binder_rpc_unstable_bindgen::ARpcServer_start(self.as_ptr()) };
+ }
+
+ /// Joins the RpcServer thread. The call blocks until the server terminates.
+ /// This must be called from exactly one thread.
+ pub fn join(&self) {
+ // SAFETY: RpcServerRef wraps a valid pointer to an ARpcServer.
+ unsafe { binder_rpc_unstable_bindgen::ARpcServer_join(self.as_ptr()) };
+ }
+
+ /// Shuts down the running RpcServer. Can be called multiple times and from
+ /// multiple threads. Called automatically during drop().
+ pub fn shutdown(&self) -> Result<(), Error> {
+ // SAFETY: RpcServerRef wraps a valid pointer to an ARpcServer.
+ if unsafe { binder_rpc_unstable_bindgen::ARpcServer_shutdown(self.as_ptr()) } {
+ Ok(())
+ } else {
+ Err(Error::from(ErrorKind::UnexpectedEof))
+ }
+ }
+}
diff --git a/libs/binder/rust/rpcbinder/src/server/trusty.rs b/libs/binder/rust/rpcbinder/src/server/trusty.rs
new file mode 100644
index 0000000..fe45dec
--- /dev/null
+++ b/libs/binder/rust/rpcbinder/src/server/trusty.rs
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+use binder::{unstable_api::AsNative, SpIBinder};
+use libc::size_t;
+use std::ffi::{c_char, c_void};
+use std::ptr;
+use tipc::{ConnectResult, Handle, MessageResult, PortCfg, TipcError, UnbufferedService, Uuid};
+
+pub trait PerSessionCallback: Fn(Uuid) -> Option<SpIBinder> + Send + Sync + 'static {}
+impl<T> PerSessionCallback for T where T: Fn(Uuid) -> Option<SpIBinder> + Send + Sync + 'static {}
+
+pub struct RpcServer {
+ inner: *mut binder_rpc_server_bindgen::ARpcServerTrusty,
+}
+
+/// SAFETY: The opaque handle points to a heap allocation
+/// that should be process-wide and not tied to the current thread.
+unsafe impl Send for RpcServer {}
+/// SAFETY: The underlying C++ RpcServer class is thread-safe.
+unsafe impl Sync for RpcServer {}
+
+impl Drop for RpcServer {
+ fn drop(&mut self) {
+ // SAFETY: `ARpcServerTrusty_delete` is the correct destructor to call
+ // on pointers returned by `ARpcServerTrusty_new`.
+ unsafe {
+ binder_rpc_server_bindgen::ARpcServerTrusty_delete(self.inner);
+ }
+ }
+}
+
+impl RpcServer {
+ /// Allocates a new RpcServer object.
+ pub fn new(service: SpIBinder) -> RpcServer {
+ Self::new_per_session(move |_uuid| Some(service.clone()))
+ }
+
+ /// Allocates a new per-session RpcServer object.
+ ///
+ /// Per-session objects take a closure that gets called once
+ /// for every new connection. The closure gets the UUID of
+ /// the peer and can accept or reject that connection.
+ pub fn new_per_session<F: PerSessionCallback>(f: F) -> RpcServer {
+ // SAFETY: Takes ownership of the returned handle, which has correct refcount.
+ let inner = unsafe {
+ binder_rpc_server_bindgen::ARpcServerTrusty_newPerSession(
+ Some(per_session_callback_wrapper::<F>),
+ Box::into_raw(Box::new(f)).cast(),
+ Some(per_session_callback_deleter::<F>),
+ )
+ };
+ RpcServer { inner }
+ }
+}
+
+unsafe extern "C" fn per_session_callback_wrapper<F: PerSessionCallback>(
+ uuid_ptr: *const c_void,
+ len: size_t,
+ cb_ptr: *mut c_char,
+) -> *mut binder_rpc_server_bindgen::AIBinder {
+ // SAFETY: This callback should only get called while the RpcServer is alive.
+ let cb = unsafe { &mut *cb_ptr.cast::<F>() };
+
+ if len != std::mem::size_of::<Uuid>() {
+ return ptr::null_mut();
+ }
+
+ // SAFETY: On the previous lines we check that we got exactly the right amount of bytes.
+ let uuid = unsafe {
+ let mut uuid = std::mem::MaybeUninit::<Uuid>::uninit();
+ uuid.as_mut_ptr().copy_from(uuid_ptr.cast(), 1);
+ uuid.assume_init()
+ };
+
+ cb(uuid).map_or_else(ptr::null_mut, |b| {
+ // Prevent AIBinder_decStrong from being called before AIBinder_toPlatformBinder.
+ // The per-session callback in C++ is supposed to call AIBinder_decStrong on the
+ // pointer we return here.
+ std::mem::ManuallyDrop::new(b).as_native_mut().cast()
+ })
+}
+
+unsafe extern "C" fn per_session_callback_deleter<F: PerSessionCallback>(cb: *mut c_char) {
+ // SAFETY: shared_ptr calls this to delete the pointer we gave it.
+ // It should only get called once the last shared reference goes away.
+ unsafe {
+ drop(Box::<F>::from_raw(cb.cast()));
+ }
+}
+
+pub struct RpcServerConnection {
+ ctx: *mut c_void,
+}
+
+impl Drop for RpcServerConnection {
+ fn drop(&mut self) {
+ // We do not need to close handle_fd since we do not own it.
+ unsafe {
+ binder_rpc_server_bindgen::ARpcServerTrusty_handleChannelCleanup(self.ctx);
+ }
+ }
+}
+
+impl UnbufferedService for RpcServer {
+ type Connection = RpcServerConnection;
+
+ fn on_connect(
+ &self,
+ _port: &PortCfg,
+ handle: &Handle,
+ peer: &Uuid,
+ ) -> tipc::Result<ConnectResult<Self::Connection>> {
+ let mut conn = RpcServerConnection { ctx: std::ptr::null_mut() };
+ let rc = unsafe {
+ binder_rpc_server_bindgen::ARpcServerTrusty_handleConnect(
+ self.inner,
+ handle.as_raw_fd(),
+ peer.as_ptr().cast(),
+ &mut conn.ctx,
+ )
+ };
+ if rc < 0 {
+ Err(TipcError::from_uapi(rc.into()))
+ } else {
+ Ok(ConnectResult::Accept(conn))
+ }
+ }
+
+ fn on_message(
+ &self,
+ conn: &Self::Connection,
+ _handle: &Handle,
+ buffer: &mut [u8],
+ ) -> tipc::Result<MessageResult> {
+ assert!(buffer.is_empty());
+ let rc = unsafe { binder_rpc_server_bindgen::ARpcServerTrusty_handleMessage(conn.ctx) };
+ if rc < 0 {
+ Err(TipcError::from_uapi(rc.into()))
+ } else {
+ Ok(MessageResult::MaintainConnection)
+ }
+ }
+
+ fn on_disconnect(&self, conn: &Self::Connection) {
+ unsafe { binder_rpc_server_bindgen::ARpcServerTrusty_handleDisconnect(conn.ctx) };
+ }
+}
diff --git a/libs/binder/trusty/include/binder/ARpcServerTrusty.h b/libs/binder/trusty/include/binder/ARpcServerTrusty.h
new file mode 100644
index 0000000..c82268b
--- /dev/null
+++ b/libs/binder/trusty/include/binder/ARpcServerTrusty.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 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 <lib/tipc/tipc_srv.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+struct AIBinder;
+struct ARpcServerTrusty;
+
+struct ARpcServerTrusty* ARpcServerTrusty_newPerSession(struct AIBinder* (*)(const void*, size_t,
+ char*),
+ char*, void (*)(char*));
+void ARpcServerTrusty_delete(struct ARpcServerTrusty*);
+int ARpcServerTrusty_handleConnect(struct ARpcServerTrusty*, handle_t, const struct uuid*, void**);
+int ARpcServerTrusty_handleMessage(void*);
+void ARpcServerTrusty_handleDisconnect(void*);
+void ARpcServerTrusty_handleChannelCleanup(void*);
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/libs/binder/trusty/include/binder/RpcServerTrusty.h b/libs/binder/trusty/include/binder/RpcServerTrusty.h
index bd1d90f..fe44ea5 100644
--- a/libs/binder/trusty/include/binder/RpcServerTrusty.h
+++ b/libs/binder/trusty/include/binder/RpcServerTrusty.h
@@ -16,6 +16,7 @@
#pragma once
+#include <binder/ARpcServerTrusty.h>
#include <binder/IBinder.h>
#include <binder/RpcServer.h>
#include <binder/RpcSession.h>
@@ -100,6 +101,16 @@
return rpcServer;
}
+ friend struct ::ARpcServerTrusty;
+ friend ::ARpcServerTrusty* ::ARpcServerTrusty_newPerSession(::AIBinder* (*)(const void*, size_t,
+ char*),
+ char*, void (*)(char*));
+ friend void ::ARpcServerTrusty_delete(::ARpcServerTrusty*);
+ friend int ::ARpcServerTrusty_handleConnect(::ARpcServerTrusty*, handle_t, const uuid*, void**);
+ friend int ::ARpcServerTrusty_handleMessage(void*);
+ friend void ::ARpcServerTrusty_handleDisconnect(void*);
+ friend void ::ARpcServerTrusty_handleChannelCleanup(void*);
+
// The Rpc-specific context maintained for every open TIPC channel.
struct ChannelContext {
sp<RpcSession> session;
diff --git a/libs/binder/trusty/rust/binder_rpc_server_bindgen/cpp/ARpcServerTrusty.cpp b/libs/binder/trusty/rust/binder_rpc_server_bindgen/cpp/ARpcServerTrusty.cpp
new file mode 100644
index 0000000..451383a
--- /dev/null
+++ b/libs/binder/trusty/rust/binder_rpc_server_bindgen/cpp/ARpcServerTrusty.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2024 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/binder_libbinder.h>
+#include <binder/RpcServer.h>
+#include <binder/RpcServerTrusty.h>
+#include <binder/RpcSession.h>
+#include <binder/RpcTransportTipcTrusty.h>
+
+using android::RpcServer;
+using android::RpcServerTrusty;
+using android::RpcSession;
+using android::RpcTransportCtxFactoryTipcTrusty;
+using android::sp;
+using android::wp;
+
+struct ARpcServerTrusty {
+ sp<RpcServer> mRpcServer;
+
+ ARpcServerTrusty() = delete;
+ ARpcServerTrusty(sp<RpcServer> rpcServer) : mRpcServer(std::move(rpcServer)) {}
+};
+
+ARpcServerTrusty* ARpcServerTrusty_newPerSession(AIBinder* (*cb)(const void*, size_t, char*),
+ char* cbArg, void (*cbArgDeleter)(char*)) {
+ std::shared_ptr<char> cbArgSp(cbArg, cbArgDeleter);
+
+ auto rpcTransportCtxFactory = RpcTransportCtxFactoryTipcTrusty::make();
+ if (rpcTransportCtxFactory == nullptr) {
+ return nullptr;
+ }
+
+ auto ctx = rpcTransportCtxFactory->newServerCtx();
+ if (ctx == nullptr) {
+ return nullptr;
+ }
+
+ auto rpcServer = RpcServerTrusty::makeRpcServer(std::move(ctx));
+ if (rpcServer == nullptr) {
+ return nullptr;
+ }
+
+ rpcServer->setPerSessionRootObject(
+ [cb, cbArgSp](wp<RpcSession> /*session*/, const void* addrPtr, size_t len) {
+ auto* aib = (*cb)(addrPtr, len, cbArgSp.get());
+ auto b = AIBinder_toPlatformBinder(aib);
+
+ // We have a new sp<IBinder> backed by the same binder, so we can
+ // finally release the AIBinder* from the callback
+ AIBinder_decStrong(aib);
+
+ return b;
+ });
+
+ return new (std::nothrow) ARpcServerTrusty(std::move(rpcServer));
+}
+
+void ARpcServerTrusty_delete(ARpcServerTrusty* rstr) {
+ delete rstr;
+}
+
+int ARpcServerTrusty_handleConnect(ARpcServerTrusty* rstr, handle_t chan, const uuid* peer,
+ void** ctx_p) {
+ return RpcServerTrusty::handleConnectInternal(rstr->mRpcServer.get(), chan, peer, ctx_p);
+}
+
+int ARpcServerTrusty_handleMessage(void* ctx) {
+ return RpcServerTrusty::handleMessageInternal(ctx);
+}
+
+void ARpcServerTrusty_handleDisconnect(void* ctx) {
+ RpcServerTrusty::handleDisconnectInternal(ctx);
+}
+
+void ARpcServerTrusty_handleChannelCleanup(void* ctx) {
+ RpcServerTrusty::handleChannelCleanup(ctx);
+}
diff --git a/libs/binder/trusty/rust/binder_rpc_server_bindgen/cpp/rules.mk b/libs/binder/trusty/rust/binder_rpc_server_bindgen/cpp/rules.mk
new file mode 100644
index 0000000..6def634
--- /dev/null
+++ b/libs/binder/trusty/rust/binder_rpc_server_bindgen/cpp/rules.mk
@@ -0,0 +1,29 @@
+# Copyright (C) 2024 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.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+LIBBINDER_DIR := $(LOCAL_DIR)/../../../..
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_SRCS := \
+ $(LOCAL_DIR)/ARpcServerTrusty.cpp \
+
+MODULE_LIBRARY_DEPS += \
+ $(LIBBINDER_DIR)/trusty \
+ $(LIBBINDER_DIR)/trusty/ndk \
+ trusty/user/base/lib/libstdc++-trusty \
+
+include make/library.mk
diff --git a/libs/binder/trusty/rust/binder_rpc_server_bindgen/lib.rs b/libs/binder/trusty/rust/binder_rpc_server_bindgen/lib.rs
new file mode 100644
index 0000000..2e8b3ec
--- /dev/null
+++ b/libs/binder/trusty/rust/binder_rpc_server_bindgen/lib.rs
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+//! Generated Rust bindings to binder_rpc_server
+
+#[allow(bad_style)]
+mod sys {
+ include!(env!("BINDGEN_INC_FILE"));
+}
+
+pub use sys::*;
diff --git a/libs/binder/trusty/rust/binder_rpc_server_bindgen/rules.mk b/libs/binder/trusty/rust/binder_rpc_server_bindgen/rules.mk
new file mode 100644
index 0000000..4ee333f
--- /dev/null
+++ b/libs/binder/trusty/rust/binder_rpc_server_bindgen/rules.mk
@@ -0,0 +1,37 @@
+# Copyright (C) 2024 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.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+LIBBINDER_DIR := $(LOCAL_DIR)/../../..
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_SRCS := $(LOCAL_DIR)/lib.rs
+
+MODULE_CRATE_NAME := binder_rpc_server_bindgen
+
+MODULE_LIBRARY_DEPS += \
+ $(LOCAL_DIR)/cpp \
+ trusty/user/base/lib/libstdc++-trusty \
+ trusty/user/base/lib/trusty-sys \
+
+MODULE_BINDGEN_SRC_HEADER := \
+ $(LIBBINDER_DIR)/trusty/include/binder/ARpcServerTrusty.h
+
+MODULE_BINDGEN_FLAGS += \
+ --allowlist-type="ARpcServerTrusty" \
+ --allowlist-function="ARpcServerTrusty_.*" \
+
+include make/library.mk
diff --git a/libs/binder/trusty/rust/binder_rpc_test/main.rs b/libs/binder/trusty/rust/binder_rpc_test/main.rs
index a71ce2c..3c1e784 100644
--- a/libs/binder/trusty/rust/binder_rpc_test/main.rs
+++ b/libs/binder/trusty/rust/binder_rpc_test/main.rs
@@ -23,14 +23,21 @@
test::init!();
const SERVICE_PORT: &str = "com.android.trusty.binderRpcTestService.V1";
+const RUST_SERVICE_PORT: &str = "com.android.trusty.rust.binderRpcTestService.V1";
-fn get_service() -> Strong<dyn IBinderRpcTest> {
- let port = CString::try_new(SERVICE_PORT).expect("Failed to allocate port name");
+fn get_service(port: &str) -> Strong<dyn IBinderRpcTest> {
+ let port = CString::try_new(port).expect("Failed to allocate port name");
RpcSession::new().setup_trusty_client(port.as_c_str()).expect("Failed to create session")
}
#[test]
fn ping() {
- let srv = get_service();
+ let srv = get_service(SERVICE_PORT);
+ assert_eq!(srv.as_binder().ping_binder(), Ok(()));
+}
+
+#[test]
+fn ping_rust() {
+ let srv = get_service(RUST_SERVICE_PORT);
assert_eq!(srv.as_binder().ping_binder(), Ok(()));
}
diff --git a/libs/binder/trusty/rust/binder_rpc_test/service/main.rs b/libs/binder/trusty/rust/binder_rpc_test/service/main.rs
new file mode 100644
index 0000000..b9a86bf
--- /dev/null
+++ b/libs/binder/trusty/rust/binder_rpc_test/service/main.rs
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+use binder::{BinderFeatures, Interface, ParcelFileDescriptor, SpIBinder, Status, Strong};
+use binder_rpc_test_aidl::aidl::IBinderRpcCallback::IBinderRpcCallback;
+use binder_rpc_test_aidl::aidl::IBinderRpcSession::IBinderRpcSession;
+use binder_rpc_test_aidl::aidl::IBinderRpcTest::{BnBinderRpcTest, IBinderRpcTest};
+use rpcbinder::RpcServer;
+use std::rc::Rc;
+use tipc::{service_dispatcher, wrap_service, Manager, PortCfg};
+
+const RUST_SERVICE_PORT: &str = "com.android.trusty.rust.binderRpcTestService.V1";
+
+#[derive(Debug, Default)]
+struct TestService;
+
+impl Interface for TestService {}
+
+impl IBinderRpcTest for TestService {
+ fn sendString(&self, _: &str) -> Result<(), Status> {
+ todo!()
+ }
+ fn doubleString(&self, _: &str) -> Result<String, Status> {
+ todo!()
+ }
+ fn getClientPort(&self) -> Result<i32, Status> {
+ todo!()
+ }
+ fn countBinders(&self) -> Result<Vec<i32>, Status> {
+ todo!()
+ }
+ fn getNullBinder(&self) -> Result<SpIBinder, Status> {
+ todo!()
+ }
+ fn pingMe(&self, _: &SpIBinder) -> Result<i32, Status> {
+ todo!()
+ }
+ fn repeatBinder(&self, _: Option<&SpIBinder>) -> Result<Option<SpIBinder>, Status> {
+ todo!()
+ }
+ fn holdBinder(&self, _: Option<&SpIBinder>) -> Result<(), Status> {
+ todo!()
+ }
+ fn getHeldBinder(&self) -> Result<Option<SpIBinder>, Status> {
+ todo!()
+ }
+ fn nestMe(&self, _: &Strong<(dyn IBinderRpcTest + 'static)>, _: i32) -> Result<(), Status> {
+ todo!()
+ }
+ fn alwaysGiveMeTheSameBinder(&self) -> Result<SpIBinder, Status> {
+ todo!()
+ }
+ fn openSession(&self, _: &str) -> Result<Strong<(dyn IBinderRpcSession + 'static)>, Status> {
+ todo!()
+ }
+ fn getNumOpenSessions(&self) -> Result<i32, Status> {
+ todo!()
+ }
+ fn lock(&self) -> Result<(), Status> {
+ todo!()
+ }
+ fn unlockInMsAsync(&self, _: i32) -> Result<(), Status> {
+ todo!()
+ }
+ fn lockUnlock(&self) -> Result<(), Status> {
+ todo!()
+ }
+ fn sleepMs(&self, _: i32) -> Result<(), Status> {
+ todo!()
+ }
+ fn sleepMsAsync(&self, _: i32) -> Result<(), Status> {
+ todo!()
+ }
+ fn doCallback(
+ &self,
+ _: &Strong<(dyn IBinderRpcCallback + 'static)>,
+ _: bool,
+ _: bool,
+ _: &str,
+ ) -> Result<(), Status> {
+ todo!()
+ }
+ fn doCallbackAsync(
+ &self,
+ _: &Strong<(dyn IBinderRpcCallback + 'static)>,
+ _: bool,
+ _: bool,
+ _: &str,
+ ) -> Result<(), Status> {
+ todo!()
+ }
+ fn die(&self, _: bool) -> Result<(), Status> {
+ todo!()
+ }
+ fn scheduleShutdown(&self) -> Result<(), Status> {
+ todo!()
+ }
+ fn useKernelBinderCallingId(&self) -> Result<(), Status> {
+ todo!()
+ }
+ fn echoAsFile(&self, _: &str) -> Result<ParcelFileDescriptor, Status> {
+ todo!()
+ }
+ fn concatFiles(&self, _: &[ParcelFileDescriptor]) -> Result<ParcelFileDescriptor, Status> {
+ todo!()
+ }
+ fn blockingSendFdOneway(&self, _: &ParcelFileDescriptor) -> Result<(), Status> {
+ todo!()
+ }
+ fn blockingRecvFd(&self) -> Result<ParcelFileDescriptor, Status> {
+ todo!()
+ }
+ fn blockingSendIntOneway(&self, _: i32) -> Result<(), Status> {
+ todo!()
+ }
+ fn blockingRecvInt(&self) -> Result<i32, Status> {
+ todo!()
+ }
+}
+
+wrap_service!(TestRpcServer(RpcServer: UnbufferedService));
+
+service_dispatcher! {
+ enum TestDispatcher {
+ TestRpcServer,
+ }
+}
+
+fn main() {
+ let mut dispatcher = TestDispatcher::<1>::new().expect("Could not create test dispatcher");
+
+ let service = BnBinderRpcTest::new_binder(TestService::default(), BinderFeatures::default());
+ let rpc_server =
+ TestRpcServer::new(RpcServer::new_per_session(move |_uuid| Some(service.as_binder())));
+
+ let cfg = PortCfg::new(RUST_SERVICE_PORT)
+ .expect("Could not create port config")
+ .allow_ta_connect()
+ .allow_ns_connect();
+ dispatcher.add_service(Rc::new(rpc_server), cfg).expect("Could not add service to dispatcher");
+
+ Manager::<_, _, 1, 4>::new_with_dispatcher(dispatcher, [])
+ .expect("Could not create service manager")
+ .run_event_loop()
+ .expect("Test event loop failed");
+}
diff --git a/libs/binder/trusty/rust/binder_rpc_test/service/manifest.json b/libs/binder/trusty/rust/binder_rpc_test/service/manifest.json
new file mode 100644
index 0000000..121ba11
--- /dev/null
+++ b/libs/binder/trusty/rust/binder_rpc_test/service/manifest.json
@@ -0,0 +1,10 @@
+{
+ "uuid": "4741fc65-8b65-4893-ba55-b182c003c8b7",
+ "app_name": "rust_binder_rpc_test_service",
+ "min_heap": 16384,
+ "min_stack": 16384,
+ "mgmt_flags": {
+ "non_critical_app": true,
+ "restart_on_exit": true
+ }
+}
diff --git a/libs/binder/trusty/rust/binder_rpc_test/service/rules.mk b/libs/binder/trusty/rust/binder_rpc_test/service/rules.mk
new file mode 100644
index 0000000..1ddc382
--- /dev/null
+++ b/libs/binder/trusty/rust/binder_rpc_test/service/rules.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2023 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.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+LIBBINDER_DIR := $(LOCAL_DIR)/../../../..
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_SRCS := $(LOCAL_DIR)/main.rs
+
+MODULE_CRATE_NAME := binder_rpc_test_service
+
+MODULE_LIBRARY_DEPS += \
+ $(LIBBINDER_DIR)/trusty/rust \
+ $(LIBBINDER_DIR)/trusty/rust/rpcbinder \
+ $(LOCAL_DIR)/../aidl \
+ trusty/user/base/lib/tipc/rust \
+
+MANIFEST := $(LOCAL_DIR)/manifest.json
+
+include make/trusted_app.mk
diff --git a/libs/binder/trusty/rust/rpcbinder/rules.mk b/libs/binder/trusty/rust/rpcbinder/rules.mk
index 76f3b94..97f5c03 100644
--- a/libs/binder/trusty/rust/rpcbinder/rules.mk
+++ b/libs/binder/trusty/rust/rpcbinder/rules.mk
@@ -28,6 +28,8 @@
$(LIBBINDER_DIR)/trusty/rust \
$(LIBBINDER_DIR)/trusty/rust/binder_ndk_sys \
$(LIBBINDER_DIR)/trusty/rust/binder_rpc_unstable_bindgen \
+ $(LIBBINDER_DIR)/trusty/rust/binder_rpc_server_bindgen \
+ external/rust/crates/cfg-if \
external/rust/crates/foreign-types \
trusty/user/base/lib/tipc/rust \
trusty/user/base/lib/trusty-sys \
diff --git a/libs/binder/trusty/usertests-inc.mk b/libs/binder/trusty/usertests-inc.mk
index 241e668..833d209 100644
--- a/libs/binder/trusty/usertests-inc.mk
+++ b/libs/binder/trusty/usertests-inc.mk
@@ -16,6 +16,7 @@
TRUSTY_USER_TESTS += \
frameworks/native/libs/binder/trusty/binderRpcTest \
frameworks/native/libs/binder/trusty/binderRpcTest/service \
+ frameworks/native/libs/binder/trusty/rust/binder_rpc_test/service \
TRUSTY_RUST_USER_TESTS += \
frameworks/native/libs/binder/trusty/rust/binder_rpc_test \
diff --git a/libs/gui/LayerStatePermissions.cpp b/libs/gui/LayerStatePermissions.cpp
index 28697ca..c467cfd 100644
--- a/libs/gui/LayerStatePermissions.cpp
+++ b/libs/gui/LayerStatePermissions.cpp
@@ -23,31 +23,31 @@
#include <gui/LayerState.h>
namespace android {
-std::unordered_map<std::string, int> LayerStatePermissions::mPermissionMap = {
+std::vector<std::pair<String16, int>> LayerStatePermissions::mPermissionMap = {
// If caller has ACCESS_SURFACE_FLINGER, they automatically get ROTATE_SURFACE_FLINGER
// permission, as well
- {"android.permission.ACCESS_SURFACE_FLINGER",
+ {String16("android.permission.ACCESS_SURFACE_FLINGER"),
layer_state_t::Permission::ACCESS_SURFACE_FLINGER |
layer_state_t::Permission::ROTATE_SURFACE_FLINGER},
- {"android.permission.ROTATE_SURFACE_FLINGER",
+ {String16("android.permission.ROTATE_SURFACE_FLINGER"),
layer_state_t::Permission::ROTATE_SURFACE_FLINGER},
- {"android.permission.INTERNAL_SYSTEM_WINDOW",
+ {String16("android.permission.INTERNAL_SYSTEM_WINDOW"),
layer_state_t::Permission::INTERNAL_SYSTEM_WINDOW},
};
-static bool callingThreadHasPermission(const std::string& permission __attribute__((unused)),
+static bool callingThreadHasPermission(const String16& permission __attribute__((unused)),
int pid __attribute__((unused)),
int uid __attribute__((unused))) {
#ifndef __ANDROID_VNDK__
return uid == AID_GRAPHICS || uid == AID_SYSTEM ||
- PermissionCache::checkPermission(String16(permission.c_str()), pid, uid);
+ PermissionCache::checkPermission(permission, pid, uid);
#endif // __ANDROID_VNDK__
return false;
}
uint32_t LayerStatePermissions::getTransactionPermissions(int pid, int uid) {
uint32_t permissions = 0;
- for (auto [permissionName, permissionVal] : mPermissionMap) {
+ for (const auto& [permissionName, permissionVal] : mPermissionMap) {
if (callingThreadHasPermission(permissionName, pid, uid)) {
permissions |= permissionVal;
}
diff --git a/libs/gui/include/gui/LayerStatePermissions.h b/libs/gui/include/gui/LayerStatePermissions.h
index a90f30c..b6588a2 100644
--- a/libs/gui/include/gui/LayerStatePermissions.h
+++ b/libs/gui/include/gui/LayerStatePermissions.h
@@ -15,15 +15,14 @@
*/
#include <stdint.h>
-#include <string>
-#include <unordered_map>
-
+#include <utils/String16.h>
+#include <vector>
namespace android {
class LayerStatePermissions {
public:
static uint32_t getTransactionPermissions(int pid, int uid);
private:
- static std::unordered_map<std::string, int> mPermissionMap;
+ static std::vector<std::pair<String16, int>> mPermissionMap;
};
} // namespace android
\ No newline at end of file
diff --git a/libs/gui/rust/aidl_types/src/lib.rs b/libs/gui/rust/aidl_types/src/lib.rs
index 4e86ed6..fead018 100644
--- a/libs/gui/rust/aidl_types/src/lib.rs
+++ b/libs/gui/rust/aidl_types/src/lib.rs
@@ -20,13 +20,11 @@
StatusCode,
};
-#[allow(dead_code)]
macro_rules! stub_unstructured_parcelable {
($name:ident) => {
/// Unimplemented stub parcelable.
- #[allow(dead_code)]
#[derive(Debug, Default)]
- pub struct $name(Option<()>);
+ pub struct $name(());
impl UnstructuredParcelable for $name {
fn write_to_parcel(&self, _parcel: &mut BorrowedParcel) -> Result<(), StatusCode> {
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index 00a6213..69e7b88 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -50,6 +50,11 @@
#define PROPERTY_DEBUG_RENDERENGINE_CAPTURE_FILENAME "debug.renderengine.capture_filename"
/**
+ * Switches the cross-window background blur algorithm.
+ */
+#define PROPERTY_DEBUG_RENDERENGINE_BLUR_ALGORITHM "debug.renderengine.blur_algorithm"
+
+/**
* Allows recording of Skia drawing commands with systrace.
*/
#define PROPERTY_SKIA_ATRACE_ENABLED "debug.renderengine.skia_atrace_enabled"
@@ -107,6 +112,12 @@
GRAPHITE,
};
+ enum class BlurAlgorithm {
+ NONE,
+ GAUSSIAN,
+ KAWASE,
+ };
+
static std::unique_ptr<RenderEngine> create(const RenderEngineCreationArgs& args);
static bool canSupport(GraphicsApi);
@@ -258,7 +269,7 @@
bool useColorManagement;
bool enableProtectedContext;
bool precacheToneMapperShaderOnly;
- bool supportsBackgroundBlur;
+ RenderEngine::BlurAlgorithm blurAlgorithm;
RenderEngine::ContextPriority contextPriority;
RenderEngine::Threaded threaded;
RenderEngine::GraphicsApi graphicsApi;
@@ -270,7 +281,7 @@
// must be created by Builder via constructor with full argument list
RenderEngineCreationArgs(int _pixelFormat, uint32_t _imageCacheSize,
bool _enableProtectedContext, bool _precacheToneMapperShaderOnly,
- bool _supportsBackgroundBlur,
+ RenderEngine::BlurAlgorithm _blurAlgorithm,
RenderEngine::ContextPriority _contextPriority,
RenderEngine::Threaded _threaded,
RenderEngine::GraphicsApi _graphicsApi,
@@ -279,7 +290,7 @@
imageCacheSize(_imageCacheSize),
enableProtectedContext(_enableProtectedContext),
precacheToneMapperShaderOnly(_precacheToneMapperShaderOnly),
- supportsBackgroundBlur(_supportsBackgroundBlur),
+ blurAlgorithm(_blurAlgorithm),
contextPriority(_contextPriority),
threaded(_threaded),
graphicsApi(_graphicsApi),
@@ -306,8 +317,8 @@
this->precacheToneMapperShaderOnly = precacheToneMapperShaderOnly;
return *this;
}
- Builder& setSupportsBackgroundBlur(bool supportsBackgroundBlur) {
- this->supportsBackgroundBlur = supportsBackgroundBlur;
+ Builder& setBlurAlgorithm(RenderEngine::BlurAlgorithm blurAlgorithm) {
+ this->blurAlgorithm = blurAlgorithm;
return *this;
}
Builder& setContextPriority(RenderEngine::ContextPriority contextPriority) {
@@ -328,7 +339,7 @@
}
RenderEngineCreationArgs build() const {
return RenderEngineCreationArgs(pixelFormat, imageCacheSize, enableProtectedContext,
- precacheToneMapperShaderOnly, supportsBackgroundBlur,
+ precacheToneMapperShaderOnly, blurAlgorithm,
contextPriority, threaded, graphicsApi, skiaBackend);
}
@@ -338,7 +349,7 @@
uint32_t imageCacheSize = 0;
bool enableProtectedContext = false;
bool precacheToneMapperShaderOnly = false;
- bool supportsBackgroundBlur = false;
+ RenderEngine::BlurAlgorithm blurAlgorithm = RenderEngine::BlurAlgorithm::NONE;
RenderEngine::ContextPriority contextPriority = RenderEngine::ContextPriority::MEDIUM;
RenderEngine::Threaded threaded = RenderEngine::Threaded::YES;
RenderEngine::GraphicsApi graphicsApi = RenderEngine::GraphicsApi::GL;
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 61369ae..9d3d98e 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -271,7 +271,7 @@
EGLContext ctxt, EGLSurface placeholder,
EGLContext protectedContext, EGLSurface protectedPlaceholder)
: SkiaRenderEngine(args.threaded, static_cast<PixelFormat>(args.pixelFormat),
- args.supportsBackgroundBlur),
+ args.blurAlgorithm),
mEGLDisplay(display),
mEGLContext(ctxt),
mPlaceholderSurface(placeholder),
diff --git a/libs/renderengine/skia/SkiaRenderEngine.cpp b/libs/renderengine/skia/SkiaRenderEngine.cpp
index 2484650..4641cb9 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaRenderEngine.cpp
@@ -273,12 +273,25 @@
}
SkiaRenderEngine::SkiaRenderEngine(Threaded threaded, PixelFormat pixelFormat,
- bool supportsBackgroundBlur)
+ BlurAlgorithm blurAlgorithm)
: RenderEngine(threaded), mDefaultPixelFormat(pixelFormat) {
- if (supportsBackgroundBlur) {
- ALOGD("Background Blurs Enabled");
- mBlurFilter = new KawaseBlurFilter();
+ switch (blurAlgorithm) {
+ case BlurAlgorithm::GAUSSIAN: {
+ ALOGD("Background Blurs Enabled (Gaussian algorithm)");
+ mBlurFilter = new GaussianBlurFilter();
+ break;
+ }
+ case BlurAlgorithm::KAWASE: {
+ ALOGD("Background Blurs Enabled (Kawase algorithm)");
+ mBlurFilter = new KawaseBlurFilter();
+ break;
+ }
+ default: {
+ mBlurFilter = nullptr;
+ break;
+ }
}
+
mCapture = std::make_unique<SkiaCapture>();
}
diff --git a/libs/renderengine/skia/SkiaRenderEngine.h b/libs/renderengine/skia/SkiaRenderEngine.h
index d7b4910..ed50029 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.h
+++ b/libs/renderengine/skia/SkiaRenderEngine.h
@@ -59,7 +59,7 @@
class SkiaRenderEngine : public RenderEngine {
public:
static std::unique_ptr<SkiaRenderEngine> create(const RenderEngineCreationArgs& args);
- SkiaRenderEngine(Threaded, PixelFormat pixelFormat, bool supportsBackgroundBlur);
+ SkiaRenderEngine(Threaded, PixelFormat pixelFormat, BlurAlgorithm);
~SkiaRenderEngine() override;
std::future<void> primeCache(bool shouldPrimeUltraHDR) override final;
diff --git a/libs/renderengine/skia/SkiaVkRenderEngine.cpp b/libs/renderengine/skia/SkiaVkRenderEngine.cpp
index fd71332..406fd81 100644
--- a/libs/renderengine/skia/SkiaVkRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaVkRenderEngine.cpp
@@ -85,7 +85,7 @@
SkiaVkRenderEngine::SkiaVkRenderEngine(const RenderEngineCreationArgs& args)
: SkiaRenderEngine(args.threaded, static_cast<PixelFormat>(args.pixelFormat),
- args.supportsBackgroundBlur) {}
+ args.blurAlgorithm) {}
SkiaVkRenderEngine::~SkiaVkRenderEngine() {
finishRenderingAndAbandonContext();
diff --git a/libs/renderengine/skia/debug/SkiaCapture.cpp b/libs/renderengine/skia/debug/SkiaCapture.cpp
index 48dc77e..e778884 100644
--- a/libs/renderengine/skia/debug/SkiaCapture.cpp
+++ b/libs/renderengine/skia/debug/SkiaCapture.cpp
@@ -30,7 +30,7 @@
#include "SkCanvas.h"
#include "SkRect.h"
#include "SkTypeface.h"
-#include "src/utils/SkMultiPictureDocument.h"
+#include "include/docs/SkMultiPictureDocument.h"
#include <sys/stat.h>
namespace android {
@@ -196,7 +196,7 @@
// procs doesn't need to outlive this Make call
// The last argument is a callback for the endPage behavior.
// See SkSharingProc.h for more explanation of this callback.
- mMultiPic = SkMakeMultiPictureDocument(
+ mMultiPic = SkMultiPictureDocument::Make(
mOpenMultiPicStream.get(), &procs,
[sharingCtx = mSerialContext.get()](const SkPicture* pic) {
SkSharingSerialContext::collectNonTextureImagesFromPicture(pic, sharingCtx);
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index 9f614bd..640c434 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -116,7 +116,7 @@
.setImageCacheSize(1)
.setEnableProtectedContext(false)
.setPrecacheToneMapperShaderOnly(false)
- .setSupportsBackgroundBlur(true)
+ .setBlurAlgorithm(renderengine::RenderEngine::BlurAlgorithm::KAWASE)
.setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
.setThreaded(renderengine::RenderEngine::Threaded::NO)
.setGraphicsApi(graphicsApi())
diff --git a/libs/ui/DebugUtils.cpp b/libs/ui/DebugUtils.cpp
index 8675f14..bee58e5 100644
--- a/libs/ui/DebugUtils.cpp
+++ b/libs/ui/DebugUtils.cpp
@@ -22,14 +22,12 @@
#include <android-base/stringprintf.h>
#include <string>
-using android::base::StringAppendF;
using android::base::StringPrintf;
using android::ui::ColorMode;
using android::ui::RenderIntent;
-std::string decodeStandard(android_dataspace dataspace) {
- const uint32_t dataspaceSelect = (dataspace & HAL_DATASPACE_STANDARD_MASK);
- switch (dataspaceSelect) {
+std::string decodeStandardOnly(uint32_t dataspaceStandard) {
+ switch (dataspaceStandard) {
case HAL_DATASPACE_STANDARD_BT709:
return std::string("BT709");
@@ -62,63 +60,44 @@
case HAL_DATASPACE_STANDARD_ADOBE_RGB:
return std::string("AdobeRGB");
-
- case 0:
- switch (dataspace & 0xffff) {
- case HAL_DATASPACE_JFIF:
- return std::string("(deprecated) JFIF (BT601_625)");
-
- case HAL_DATASPACE_BT601_625:
- return std::string("(deprecated) BT601_625");
-
- case HAL_DATASPACE_BT601_525:
- return std::string("(deprecated) BT601_525");
-
- case HAL_DATASPACE_SRGB_LINEAR:
- case HAL_DATASPACE_SRGB:
- return std::string("(deprecated) sRGB");
-
- case HAL_DATASPACE_BT709:
- return std::string("(deprecated) BT709");
-
- case HAL_DATASPACE_ARBITRARY:
- return std::string("ARBITRARY");
-
- case HAL_DATASPACE_UNKNOWN:
- // Fallthrough
- default:
- return StringPrintf("Unknown deprecated dataspace code %d", dataspace);
- }
}
- return StringPrintf("Unknown dataspace code %d", dataspaceSelect);
+ return StringPrintf("Unknown dataspace code %d", dataspaceStandard);
}
-std::string decodeTransfer(android_dataspace dataspace) {
- const uint32_t dataspaceSelect = (dataspace & HAL_DATASPACE_STANDARD_MASK);
- if (dataspaceSelect == 0) {
+std::string decodeStandard(android_dataspace dataspace) {
+ const uint32_t dataspaceStandard = (dataspace & HAL_DATASPACE_STANDARD_MASK);
+ if (dataspaceStandard == 0) {
switch (dataspace & 0xffff) {
case HAL_DATASPACE_JFIF:
+ return std::string("(deprecated) JFIF (BT601_625)");
+
case HAL_DATASPACE_BT601_625:
+ return std::string("(deprecated) BT601_625");
+
case HAL_DATASPACE_BT601_525:
- case HAL_DATASPACE_BT709:
- return std::string("SMPTE_170M");
+ return std::string("(deprecated) BT601_525");
case HAL_DATASPACE_SRGB_LINEAR:
- case HAL_DATASPACE_ARBITRARY:
- return std::string("Linear");
-
case HAL_DATASPACE_SRGB:
- return std::string("sRGB");
+ return std::string("(deprecated) sRGB");
+
+ case HAL_DATASPACE_BT709:
+ return std::string("(deprecated) BT709");
+
+ case HAL_DATASPACE_ARBITRARY:
+ return std::string("ARBITRARY");
case HAL_DATASPACE_UNKNOWN:
// Fallthrough
default:
- return std::string("");
+ return StringPrintf("Unknown deprecated dataspace code %d", dataspace);
}
}
+ return decodeStandardOnly(dataspaceStandard);
+}
- const uint32_t dataspaceTransfer = (dataspace & HAL_DATASPACE_TRANSFER_MASK);
+std::string decodeTransferOnly(uint32_t dataspaceTransfer) {
switch (dataspaceTransfer) {
case HAL_DATASPACE_TRANSFER_UNSPECIFIED:
return std::string("Unspecified");
@@ -151,6 +130,52 @@
return StringPrintf("Unknown dataspace transfer %d", dataspaceTransfer);
}
+std::string decodeTransfer(android_dataspace dataspace) {
+ const uint32_t dataspaceSelect = (dataspace & HAL_DATASPACE_STANDARD_MASK);
+ if (dataspaceSelect == 0) {
+ switch (dataspace & 0xffff) {
+ case HAL_DATASPACE_JFIF:
+ case HAL_DATASPACE_BT601_625:
+ case HAL_DATASPACE_BT601_525:
+ case HAL_DATASPACE_BT709:
+ return std::string("SMPTE_170M");
+
+ case HAL_DATASPACE_SRGB_LINEAR:
+ case HAL_DATASPACE_ARBITRARY:
+ return std::string("Linear");
+
+ case HAL_DATASPACE_SRGB:
+ return std::string("sRGB");
+
+ case HAL_DATASPACE_UNKNOWN:
+ // Fallthrough
+ default:
+ return std::string("");
+ }
+ }
+
+ const uint32_t dataspaceTransfer = (dataspace & HAL_DATASPACE_TRANSFER_MASK);
+ return decodeTransferOnly(dataspaceTransfer);
+}
+
+std::string decodeRangeOnly(uint32_t dataspaceRange) {
+ switch (dataspaceRange) {
+ case HAL_DATASPACE_RANGE_UNSPECIFIED:
+ return std::string("Range Unspecified");
+
+ case HAL_DATASPACE_RANGE_FULL:
+ return std::string("Full range");
+
+ case HAL_DATASPACE_RANGE_LIMITED:
+ return std::string("Limited range");
+
+ case HAL_DATASPACE_RANGE_EXTENDED:
+ return std::string("Extended range");
+ }
+
+ return StringPrintf("Unknown dataspace range %d", dataspaceRange);
+}
+
std::string decodeRange(android_dataspace dataspace) {
const uint32_t dataspaceSelect = (dataspace & HAL_DATASPACE_STANDARD_MASK);
if (dataspaceSelect == 0) {
@@ -174,21 +199,7 @@
}
const uint32_t dataspaceRange = (dataspace & HAL_DATASPACE_RANGE_MASK);
- switch (dataspaceRange) {
- case HAL_DATASPACE_RANGE_UNSPECIFIED:
- return std::string("Range Unspecified");
-
- case HAL_DATASPACE_RANGE_FULL:
- return std::string("Full range");
-
- case HAL_DATASPACE_RANGE_LIMITED:
- return std::string("Limited range");
-
- case HAL_DATASPACE_RANGE_EXTENDED:
- return std::string("Extended range");
- }
-
- return StringPrintf("Unknown dataspace range %d", dataspaceRange);
+ return decodeRangeOnly(dataspaceRange);
}
std::string dataspaceDetails(android_dataspace dataspace) {
diff --git a/libs/ui/include/ui/DebugUtils.h b/libs/ui/include/ui/DebugUtils.h
index 18cd487..7c4ac42 100644
--- a/libs/ui/include/ui/DebugUtils.h
+++ b/libs/ui/include/ui/DebugUtils.h
@@ -27,8 +27,11 @@
}
std::string decodeStandard(android_dataspace dataspace);
+std::string decodeStandardOnly(uint32_t dataspaceStandard);
std::string decodeTransfer(android_dataspace dataspace);
+std::string decodeTransferOnly(uint32_t dataspaceTransfer);
std::string decodeRange(android_dataspace dataspace);
+std::string decodeRangeOnly(uint32_t dataspaceRange);
std::string dataspaceDetails(android_dataspace dataspace);
std::string decodeColorMode(android::ui::ColorMode colormode);
std::string decodeColorTransform(android_color_transform colorTransform);
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index dc86577..3446f58 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -461,16 +461,18 @@
// is pre-Q, still permit delivering events to the app even if permission isn't granted
// (since this permission was only introduced in Q)
if ((event.type == SENSOR_TYPE_STEP_COUNTER || event.type == SENSOR_TYPE_STEP_DETECTOR) &&
- mTargetSdk > 0 && mTargetSdk <= __ANDROID_API_P__) {
+ mTargetSdk > 0 && mTargetSdk <= __ANDROID_API_P__) {
+ success = true;
+ } else if (mUid == AID_SYSTEM) {
+ // Allow access if it is requested from system.
success = true;
} else {
int32_t sensorHandle = event.sensor;
String16 noteMsg("Sensor event (");
noteMsg.append(String16(mService->getSensorStringType(sensorHandle)));
noteMsg.append(String16(")"));
- int32_t appOpMode = mService->sAppOpsManager.noteOp(iter->second, mUid,
- mOpPackageName, mAttributionTag,
- noteMsg);
+ int32_t appOpMode = mService->sAppOpsManager.noteOp(iter->second, mUid, mOpPackageName,
+ mAttributionTag, noteMsg);
success = (appOpMode == AppOpsManager::MODE_ALLOWED);
}
}
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index e1c43c6..69e4309 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -2302,11 +2302,16 @@
// requirement to hold the AR permission to access Step Counter and Step Detector events
// was introduced.
canAccess = true;
+ } else if (IPCThreadState::self()->getCallingUid() == AID_SYSTEM) {
+ // Allow access if it is requested from system.
+ canAccess = true;
} else if (hasPermissionForSensor(sensor)) {
- // Ensure that the AppOp is allowed, or that there is no necessary app op for the sensor
+ // Ensure that the AppOp is allowed, or that there is no necessary app op
+ // for the sensor
if (opCode >= 0) {
- const int32_t appOpMode = sAppOpsManager.checkOp(opCode,
- IPCThreadState::self()->getCallingUid(), opPackageName);
+ const int32_t appOpMode =
+ sAppOpsManager.checkOp(opCode, IPCThreadState::self()->getCallingUid(),
+ opPackageName);
canAccess = (appOpMode == AppOpsManager::MODE_ALLOWED);
} else {
canAccess = true;
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index 575a30e..4612117 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -126,6 +126,7 @@
const std::unordered_map<std::string, bool>&());
MOCK_CONST_METHOD1(dump, void(std::string&));
+ MOCK_CONST_METHOD1(dumpOverlayProperties, void(std::string&));
MOCK_CONST_METHOD0(getComposer, android::Hwc2::Composer*());
MOCK_METHOD(hal::HWDisplayId, getPrimaryHwcDisplayId, (), (const, override));
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 776bcd3..21d49f8 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -77,9 +77,7 @@
using aidl::android::hardware::graphics::common::HdrConversionStrategy;
using aidl::android::hardware::graphics::composer3::Capability;
using aidl::android::hardware::graphics::composer3::DisplayCapability;
-using aidl::android::hardware::graphics::composer3::VrrConfig;
using namespace std::string_literals;
-namespace hal = android::hardware::graphics::composer::hal;
namespace android {
@@ -964,8 +962,45 @@
return mSupportedLayerGenericMetadata;
}
+void HWComposer::dumpOverlayProperties(std::string& result) const {
+ // dump overlay properties
+ result.append("OverlayProperties:\n");
+ base::StringAppendF(&result, "supportMixedColorSpaces: %d\n",
+ mOverlayProperties.supportMixedColorSpaces);
+ base::StringAppendF(&result, "SupportedBufferCombinations(%zu entries)\n",
+ mOverlayProperties.combinations.size());
+ for (const auto& combination : mOverlayProperties.combinations) {
+ result.append(" pixelFormats=\n");
+ for (const auto& pixelFormat : combination.pixelFormats) {
+ base::StringAppendF(&result, " %s (%d)\n",
+ decodePixelFormat(static_cast<PixelFormat>(pixelFormat)).c_str(),
+ static_cast<uint32_t>(pixelFormat));
+ }
+ result.append(" standards=\n");
+ for (const auto& standard : combination.standards) {
+ base::StringAppendF(&result, " %s (%d)\n",
+ decodeStandard(static_cast<android_dataspace>(standard)).c_str(),
+ static_cast<uint32_t>(standard));
+ }
+ result.append(" transfers=\n");
+ for (const auto& transfer : combination.transfers) {
+ base::StringAppendF(&result, " %s (%d)\n",
+ decodeTransferOnly(static_cast<uint32_t>(transfer)).c_str(),
+ static_cast<uint32_t>(transfer));
+ }
+ result.append(" ranges=\n");
+ for (const auto& range : combination.ranges) {
+ base::StringAppendF(&result, " %s (%d)\n",
+ decodeRangeOnly(static_cast<uint32_t>(range)).c_str(),
+ static_cast<uint32_t>(range));
+ }
+ result.append("\n");
+ }
+}
+
void HWComposer::dump(std::string& result) const {
result.append(mComposer->dumpDebugInfo());
+ dumpOverlayProperties(result);
}
std::optional<PhysicalDisplayId> HWComposer::toPhysicalDisplayId(
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 7fbbb1a..bc32cda 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -269,6 +269,8 @@
virtual void dump(std::string& out) const = 0;
+ virtual void dumpOverlayProperties(std::string& out) const = 0;
+
virtual Hwc2::Composer* getComposer() const = 0;
// Returns the first display connected at boot. Its connection via HWComposer::onHotplug,
@@ -468,6 +470,7 @@
// for debugging ----------------------------------------------------------
void dump(std::string& out) const override;
+ void dumpOverlayProperties(std::string& out) const override;
Hwc2::Composer* getComposer() const override { return mComposer.get(); }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 21f1cb3..b3f83f0 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -821,6 +821,23 @@
}
}
+/**
+ * Choose a suggested blurring algorithm if supportsBlur is true. By default Kawase will be
+ * suggested as it's faster than a full Gaussian blur and looks close enough.
+ */
+renderengine::RenderEngine::BlurAlgorithm chooseBlurAlgorithm(bool supportsBlur) {
+ if (!supportsBlur) {
+ return renderengine::RenderEngine::BlurAlgorithm::NONE;
+ }
+
+ auto const algorithm = base::GetProperty(PROPERTY_DEBUG_RENDERENGINE_BLUR_ALGORITHM, "");
+ if (algorithm == "gaussian") {
+ return renderengine::RenderEngine::BlurAlgorithm::GAUSSIAN;
+ } else {
+ return renderengine::RenderEngine::BlurAlgorithm::KAWASE;
+ }
+}
+
void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) {
ATRACE_CALL();
ALOGI( "SurfaceFlinger's main thread ready to run. "
@@ -836,7 +853,7 @@
.setImageCacheSize(maxFrameBufferAcquiredBuffers)
.setEnableProtectedContext(enable_protected_contents(false))
.setPrecacheToneMapperShaderOnly(false)
- .setSupportsBackgroundBlur(mSupportsBlur)
+ .setBlurAlgorithm(chooseBlurAlgorithm(mSupportsBlur))
.setContextPriority(
useContextPriority
? renderengine::RenderEngine::ContextPriority::REALTIME
diff --git a/services/surfaceflinger/tests/OWNERS b/services/surfaceflinger/tests/OWNERS
new file mode 100644
index 0000000..1878326
--- /dev/null
+++ b/services/surfaceflinger/tests/OWNERS
@@ -0,0 +1,5 @@
+per-file HdrSdrRatioOverlay_test.cpp = set noparent
+per-file HdrSdrRatioOverlay_test.cpp = alecmouri@google.com, sallyqi@google.com, jreck@google.com
+
+per-file Layer* = set noparent
+per-file Layer* = pdwilliams@google.com, vishnun@google.com, melodymhsu@google.com
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyPowerBoostTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyPowerBoostTest.cpp
index 22b72f9..f2e2c8a 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyPowerBoostTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyPowerBoostTest.cpp
@@ -33,24 +33,45 @@
TEST_F(DisplayTransactionTest, notifyPowerBoostNotifiesTouchEvent) {
using namespace std::chrono_literals;
+ std::mutex timerMutex;
+ std::condition_variable cv;
+
injectDefaultInternalDisplay([](FakeDisplayDeviceInjector&) {});
- mFlinger.scheduler()->replaceTouchTimer(100);
- std::this_thread::sleep_for(10ms); // wait for callback to be triggered
+ std::unique_lock lock(timerMutex);
+ bool didReset = false; // keeps track of what the most recent call was
+
+ auto waitForTimerReset = [&] { cv.wait_for(lock, 100ms, [&] { return didReset; }); };
+ auto waitForTimerExpired = [&] { cv.wait_for(lock, 100ms, [&] { return !didReset; }); };
+
+ // Add extra logic to unblock the test when the timer callbacks get called
+ mFlinger.scheduler()->replaceTouchTimer(10, [&](bool isReset) {
+ {
+ std::unique_lock lock(timerMutex); // guarantee we're waiting on the cv
+ didReset = isReset;
+ }
+ cv.notify_one(); // wake the cv
+ std::unique_lock lock(timerMutex); // guarantee we finished the cv logic
+ });
+
+ waitForTimerReset();
EXPECT_TRUE(mFlinger.scheduler()->isTouchActive()); // Starting timer activates touch
- std::this_thread::sleep_for(110ms); // wait for reset touch timer to expire and trigger callback
- EXPECT_FALSE(mFlinger.scheduler()->isTouchActive());
+ waitForTimerExpired();
+ EXPECT_FALSE(mFlinger.scheduler()->isTouchActive()); // Stopping timer deactivates touch
EXPECT_EQ(NO_ERROR, mFlinger.notifyPowerBoost(static_cast<int32_t>(Boost::CAMERA_SHOT)));
- std::this_thread::sleep_for(10ms); // wait for callback to maybe be triggered
- EXPECT_FALSE(mFlinger.scheduler()->isTouchActive());
- std::this_thread::sleep_for(110ms); // wait for reset touch timer to expire and trigger callback
+ EXPECT_FALSE(mFlinger.scheduler()->isTouchActive());
+ // Wait for the timer to start just in case
+ waitForTimerReset();
+ EXPECT_FALSE(mFlinger.scheduler()->isTouchActive());
+ // Wait for the timer to stop, again just in case
+ waitForTimerExpired();
EXPECT_FALSE(mFlinger.scheduler()->isTouchActive());
EXPECT_EQ(NO_ERROR, mFlinger.notifyPowerBoost(static_cast<int32_t>(Boost::INTERACTION)));
- std::this_thread::sleep_for(10ms); // wait for callback to be triggered.
+ waitForTimerReset();
EXPECT_TRUE(mFlinger.scheduler()->isTouchActive());
}
diff --git a/services/surfaceflinger/tests/unittests/TestableScheduler.h b/services/surfaceflinger/tests/unittests/TestableScheduler.h
index 1472ebf..1e02c67 100644
--- a/services/surfaceflinger/tests/unittests/TestableScheduler.h
+++ b/services/surfaceflinger/tests/unittests/TestableScheduler.h
@@ -140,14 +140,25 @@
return mLayerHistory.mActiveLayerInfos.size();
}
- void replaceTouchTimer(int64_t millis) {
+ void replaceTouchTimer(int64_t millis,
+ std::function<void(bool isReset)>&& testCallback = nullptr) {
if (mTouchTimer) {
mTouchTimer.reset();
}
mTouchTimer.emplace(
"Testable Touch timer", std::chrono::milliseconds(millis),
- [this] { touchTimerCallback(TimerState::Reset); },
- [this] { touchTimerCallback(TimerState::Expired); });
+ [this, testCallback] {
+ touchTimerCallback(TimerState::Reset);
+ if (testCallback != nullptr) {
+ testCallback(true);
+ }
+ },
+ [this, testCallback] {
+ touchTimerCallback(TimerState::Expired);
+ if (testCallback != nullptr) {
+ testCallback(false);
+ }
+ });
mTouchTimer->start();
}