Loading cmds/sfdo/sfdo.rs +22 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,20 @@ enum Commands { #[command(about = "Force commit ahead of next VSYNC.")] ScheduleCommit, #[command( about = "display_id = i64, Forcibly changes the pacesetter display to specified display, \ which will persist until the display is removed or another ForcePacesetter \ or ResetForcedPacesetter call is made. Valid display IDs can be obtained \ through: adb shell dumpsys SurfaceFlinger --display-ids" )] ForcePacesetter { display_id: i64 }, #[command( about = "Resets the forced pacesetter display selection made by the ForcePacesetter \ call. No-op if there was no forced pacesetter display set." )] ResetForcedPacesetter, } /// sfdo command line tool Loading Loading @@ -146,6 +160,14 @@ fn main() { eprintln!("No state, choices are [enabled | disabled]"); } } Some(Commands::ForcePacesetter { display_id }) => { let res = composer_service.forcePacesetter(*display_id); print_result("forcePacesetter", res); } Some(Commands::ResetForcedPacesetter) => { let res = composer_service.resetForcedPacesetter(); print_result("resetForcedPacesetter", res); } None => { println!("Execute SurfaceFlinger internal commands."); println!("run `adb shell sfdo help` for more to view the commands."); Loading libs/binder/RpcServer.cpp +11 −2 Original line number Diff line number Diff line Loading @@ -231,10 +231,17 @@ status_t RpcServer::recvmsgSocketConnection(const RpcServer& server, RpcTranspor iovec iov{&zero, sizeof(zero)}; std::vector<std::variant<unique_fd, borrowed_fd>> fds; // TODO: this should delegate to RpcState::rpcRec to handle transaction errors // consistently ssize_t num_bytes = binder::os::receiveMessageFromSocket(server.mServer, &iov, 1, &fds); if (num_bytes < 0) { int savedErrno = errno; ALOGE("Failed recvmsg: %s", strerror(savedErrno)); if (savedErrno == ECONNRESET) { return DEAD_OBJECT; } return -savedErrno; } if (num_bytes == 0) { Loading Loading @@ -272,11 +279,13 @@ void RpcServer::join() { RpcTransportFd clientSocket; if ((status = mAcceptFn(*this, &clientSocket)) != OK) { if (status == DEAD_OBJECT) if (status == DEAD_OBJECT) { break; else } else { ALOGE("Accept returned error %s", statusToString(status).c_str()); continue; } } LOG_RPC_DETAIL("accept on fd %d yields fd %d", mServer.fd.get(), clientSocket.fd.get()); Loading libs/binder/ndk/tests/Android.bp +4 −3 Original line number Diff line number Diff line Loading @@ -33,12 +33,12 @@ cc_defaults { }, cflags: [ "-O0", "-g", "-Wall", "-Werror", "-Wextra", "-Wextra-semi", "-Werror", "-Winconsistent-missing-override", "-g", ], } Loading @@ -60,6 +60,7 @@ cc_defaults { "libbase", "libbinder", "libbinder_ndk", "libselinux", "libutils", ], static_libs: [ Loading Loading @@ -97,8 +98,8 @@ cc_test_host { }, static_libs: [ "libbase", "libbinder_ndk", "libbinder", "libbinder_ndk", "libcutils", "libfakeservicemanager", "libgmock", Loading libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <android/binder_process.h> #include <gtest/gtest.h> #include <iface/iface.h> #include <selinux/selinux.h> #include <utils/Looper.h> // warning: this is assuming that libbinder_ndk is using the same copy Loading Loading @@ -1098,7 +1099,8 @@ TEST(NdkBinder, CheckServiceAccessOk) { } TEST(NdkBinder, CheckServiceAccessNotOk) { EXPECT_FALSE(AServiceManager_checkServiceAccess( bool is_enforcing = security_getenforce() == 1; EXPECT_NE(is_enforcing, AServiceManager_checkServiceAccess( "u:r:some_unknown_sid:s0", 0, 0, "adb", AServiceManager_PermissionType::CHECK_ACCESS_PERMISSION_FIND)); } Loading libs/binder/rust/rpcbinder/src/server/trusty.rs +13 −8 Original line number Diff line number Diff line Loading @@ -16,6 +16,11 @@ use alloc::boxed::Box; use binder::{unstable_api::AsNative, SpIBinder}; use binder_rpc_server_bindgen::{ AIBinder, ARpcServerTrusty, ARpcServerTrusty_delete, ARpcServerTrusty_handleChannelCleanup, ARpcServerTrusty_handleConnect, ARpcServerTrusty_handleDisconnect, ARpcServerTrusty_handleMessage, ARpcServerTrusty_newPerSession, }; use libc::size_t; use log::error; use std::ffi::{c_char, c_void}; Loading @@ -38,7 +43,7 @@ impl<T> PerSessionCallback for T where } pub struct RpcServer { inner: *mut binder_rpc_server_bindgen::ARpcServerTrusty, inner: *mut ARpcServerTrusty, } /// SAFETY: The opaque handle points to a heap allocation Loading @@ -52,7 +57,7 @@ impl Drop for RpcServer { // SAFETY: `ARpcServerTrusty_delete` is the correct destructor to call // on pointers returned by `ARpcServerTrusty_new`. unsafe { binder_rpc_server_bindgen::ARpcServerTrusty_delete(self.inner); ARpcServerTrusty_delete(self.inner); } } } Loading @@ -71,7 +76,7 @@ impl RpcServer { 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( ARpcServerTrusty_newPerSession( Some(per_session_callback_wrapper::<F>), Box::into_raw(Box::new(f)).cast(), Some(per_session_callback_deleter::<F>), Loading @@ -85,7 +90,7 @@ unsafe extern "C" fn per_session_callback_wrapper<F: PerSessionCallback>( client_id_ptr: *const c_void, len: size_t, cb_ptr: *mut c_char, ) -> *mut binder_rpc_server_bindgen::AIBinder { ) -> *mut AIBinder { // SAFETY: This callback should only get called while the RpcServer is alive. let cb = unsafe { &mut *cb_ptr.cast::<F>() }; Loading Loading @@ -138,7 +143,7 @@ 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); ARpcServerTrusty_handleChannelCleanup(self.ctx); } } } Loading @@ -163,7 +168,7 @@ impl UnbufferedService for RpcServer { // no concurrent access to `sef.inner`` and other inputs are not freed/deallocated until the // function returns. Correct length of the data pointed to by the pointer is passed in. let rc = unsafe { binder_rpc_server_bindgen::ARpcServerTrusty_handleConnect( ARpcServerTrusty_handleConnect( self.inner, handle.as_raw_fd(), data.as_mut_ptr() as *const c_void, Loading @@ -184,7 +189,7 @@ impl UnbufferedService for RpcServer { _handle: &Handle, _buffer: &mut [u8], ) -> tipc::Result<MessageResult> { let rc = unsafe { binder_rpc_server_bindgen::ARpcServerTrusty_handleMessage(conn.ctx) }; let rc = unsafe { ARpcServerTrusty_handleMessage(conn.ctx) }; if rc < 0 { Err(TipcError::from_uapi(rc.into())) } else { Loading @@ -193,7 +198,7 @@ impl UnbufferedService for RpcServer { } fn on_disconnect(&self, conn: &Self::Connection) { unsafe { binder_rpc_server_bindgen::ARpcServerTrusty_handleDisconnect(conn.ctx) }; unsafe { ARpcServerTrusty_handleDisconnect(conn.ctx) }; } fn on_new_connection( Loading Loading
cmds/sfdo/sfdo.rs +22 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,20 @@ enum Commands { #[command(about = "Force commit ahead of next VSYNC.")] ScheduleCommit, #[command( about = "display_id = i64, Forcibly changes the pacesetter display to specified display, \ which will persist until the display is removed or another ForcePacesetter \ or ResetForcedPacesetter call is made. Valid display IDs can be obtained \ through: adb shell dumpsys SurfaceFlinger --display-ids" )] ForcePacesetter { display_id: i64 }, #[command( about = "Resets the forced pacesetter display selection made by the ForcePacesetter \ call. No-op if there was no forced pacesetter display set." )] ResetForcedPacesetter, } /// sfdo command line tool Loading Loading @@ -146,6 +160,14 @@ fn main() { eprintln!("No state, choices are [enabled | disabled]"); } } Some(Commands::ForcePacesetter { display_id }) => { let res = composer_service.forcePacesetter(*display_id); print_result("forcePacesetter", res); } Some(Commands::ResetForcedPacesetter) => { let res = composer_service.resetForcedPacesetter(); print_result("resetForcedPacesetter", res); } None => { println!("Execute SurfaceFlinger internal commands."); println!("run `adb shell sfdo help` for more to view the commands."); Loading
libs/binder/RpcServer.cpp +11 −2 Original line number Diff line number Diff line Loading @@ -231,10 +231,17 @@ status_t RpcServer::recvmsgSocketConnection(const RpcServer& server, RpcTranspor iovec iov{&zero, sizeof(zero)}; std::vector<std::variant<unique_fd, borrowed_fd>> fds; // TODO: this should delegate to RpcState::rpcRec to handle transaction errors // consistently ssize_t num_bytes = binder::os::receiveMessageFromSocket(server.mServer, &iov, 1, &fds); if (num_bytes < 0) { int savedErrno = errno; ALOGE("Failed recvmsg: %s", strerror(savedErrno)); if (savedErrno == ECONNRESET) { return DEAD_OBJECT; } return -savedErrno; } if (num_bytes == 0) { Loading Loading @@ -272,11 +279,13 @@ void RpcServer::join() { RpcTransportFd clientSocket; if ((status = mAcceptFn(*this, &clientSocket)) != OK) { if (status == DEAD_OBJECT) if (status == DEAD_OBJECT) { break; else } else { ALOGE("Accept returned error %s", statusToString(status).c_str()); continue; } } LOG_RPC_DETAIL("accept on fd %d yields fd %d", mServer.fd.get(), clientSocket.fd.get()); Loading
libs/binder/ndk/tests/Android.bp +4 −3 Original line number Diff line number Diff line Loading @@ -33,12 +33,12 @@ cc_defaults { }, cflags: [ "-O0", "-g", "-Wall", "-Werror", "-Wextra", "-Wextra-semi", "-Werror", "-Winconsistent-missing-override", "-g", ], } Loading @@ -60,6 +60,7 @@ cc_defaults { "libbase", "libbinder", "libbinder_ndk", "libselinux", "libutils", ], static_libs: [ Loading Loading @@ -97,8 +98,8 @@ cc_test_host { }, static_libs: [ "libbase", "libbinder_ndk", "libbinder", "libbinder_ndk", "libcutils", "libfakeservicemanager", "libgmock", Loading
libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <android/binder_process.h> #include <gtest/gtest.h> #include <iface/iface.h> #include <selinux/selinux.h> #include <utils/Looper.h> // warning: this is assuming that libbinder_ndk is using the same copy Loading Loading @@ -1098,7 +1099,8 @@ TEST(NdkBinder, CheckServiceAccessOk) { } TEST(NdkBinder, CheckServiceAccessNotOk) { EXPECT_FALSE(AServiceManager_checkServiceAccess( bool is_enforcing = security_getenforce() == 1; EXPECT_NE(is_enforcing, AServiceManager_checkServiceAccess( "u:r:some_unknown_sid:s0", 0, 0, "adb", AServiceManager_PermissionType::CHECK_ACCESS_PERMISSION_FIND)); } Loading
libs/binder/rust/rpcbinder/src/server/trusty.rs +13 −8 Original line number Diff line number Diff line Loading @@ -16,6 +16,11 @@ use alloc::boxed::Box; use binder::{unstable_api::AsNative, SpIBinder}; use binder_rpc_server_bindgen::{ AIBinder, ARpcServerTrusty, ARpcServerTrusty_delete, ARpcServerTrusty_handleChannelCleanup, ARpcServerTrusty_handleConnect, ARpcServerTrusty_handleDisconnect, ARpcServerTrusty_handleMessage, ARpcServerTrusty_newPerSession, }; use libc::size_t; use log::error; use std::ffi::{c_char, c_void}; Loading @@ -38,7 +43,7 @@ impl<T> PerSessionCallback for T where } pub struct RpcServer { inner: *mut binder_rpc_server_bindgen::ARpcServerTrusty, inner: *mut ARpcServerTrusty, } /// SAFETY: The opaque handle points to a heap allocation Loading @@ -52,7 +57,7 @@ impl Drop for RpcServer { // SAFETY: `ARpcServerTrusty_delete` is the correct destructor to call // on pointers returned by `ARpcServerTrusty_new`. unsafe { binder_rpc_server_bindgen::ARpcServerTrusty_delete(self.inner); ARpcServerTrusty_delete(self.inner); } } } Loading @@ -71,7 +76,7 @@ impl RpcServer { 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( ARpcServerTrusty_newPerSession( Some(per_session_callback_wrapper::<F>), Box::into_raw(Box::new(f)).cast(), Some(per_session_callback_deleter::<F>), Loading @@ -85,7 +90,7 @@ unsafe extern "C" fn per_session_callback_wrapper<F: PerSessionCallback>( client_id_ptr: *const c_void, len: size_t, cb_ptr: *mut c_char, ) -> *mut binder_rpc_server_bindgen::AIBinder { ) -> *mut AIBinder { // SAFETY: This callback should only get called while the RpcServer is alive. let cb = unsafe { &mut *cb_ptr.cast::<F>() }; Loading Loading @@ -138,7 +143,7 @@ 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); ARpcServerTrusty_handleChannelCleanup(self.ctx); } } } Loading @@ -163,7 +168,7 @@ impl UnbufferedService for RpcServer { // no concurrent access to `sef.inner`` and other inputs are not freed/deallocated until the // function returns. Correct length of the data pointed to by the pointer is passed in. let rc = unsafe { binder_rpc_server_bindgen::ARpcServerTrusty_handleConnect( ARpcServerTrusty_handleConnect( self.inner, handle.as_raw_fd(), data.as_mut_ptr() as *const c_void, Loading @@ -184,7 +189,7 @@ impl UnbufferedService for RpcServer { _handle: &Handle, _buffer: &mut [u8], ) -> tipc::Result<MessageResult> { let rc = unsafe { binder_rpc_server_bindgen::ARpcServerTrusty_handleMessage(conn.ctx) }; let rc = unsafe { ARpcServerTrusty_handleMessage(conn.ctx) }; if rc < 0 { Err(TipcError::from_uapi(rc.into())) } else { Loading @@ -193,7 +198,7 @@ impl UnbufferedService for RpcServer { } fn on_disconnect(&self, conn: &Self::Connection) { unsafe { binder_rpc_server_bindgen::ARpcServerTrusty_handleDisconnect(conn.ctx) }; unsafe { ARpcServerTrusty_handleDisconnect(conn.ctx) }; } fn on_new_connection( Loading