Skip to content

Commit

Permalink
在fas-rs端提供uperf-patch接口
Browse files Browse the repository at this point in the history
  • Loading branch information
shadow3aaa committed Nov 27, 2023
1 parent e743016 commit 5f508df
Show file tree
Hide file tree
Showing 16 changed files with 381 additions and 41 deletions.
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ thiserror = "1.0.50"
clap = { version = "4.4.6", features = ["derive"] }
inotify = { version = "0.10.2", default-features = false }
libc = "0.2.149"
async-trait = "0.1.74"
binder = { package = "binder_ndk", version = "0.2.0" }
lazy_static = "1.4.0"
once_cell = "1.18.0"

[dependencies.fas-rs-fw]
path = "fas-rs-fw"
Expand Down
7 changes: 0 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,6 @@
- `true` : 永远在配置合并时保持标准配置的profile, 保留本地配置的应用列表, 其它地方和false相同 *
- `false` : 见[配置合并的默认行为](#配置合并)

- **ignore_little**

- 类型 : `Bool`
- `true` : 在机器至少有3个及以上的集簇时, `fas-rs`只控制非小核集簇
- `false` : `fas-rs`始终控制所有集群 *

- `*` : 默认配置

- ### **游戏列表(`game_list`)说明 :**
Expand All @@ -51,7 +45,6 @@

```toml
[config]
ignore_little = false
keep_std = true

[game_list]
Expand Down
3 changes: 3 additions & 0 deletions aidl/IRemoteService.aidl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface IRemoteService {
void writeFreq(long freq, String path);
}
2 changes: 1 addition & 1 deletion fas-rs-fw/aidl/IRemoteService.aidl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
interface IRemoteService {
/** Send data to fas-rs server. */
boolean sendData(long buffer, String Pkg, int pid, long FrameTimeNanos);
void removeBuffer(long buffer, int pid);
}
2 changes: 2 additions & 0 deletions format_codes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# limitations under the License.
cargo fmt -v
shfmt -w -s *.sh
shfmt -w -s fas_rs_fw/*.sh
shfmt -w -s module/*.sh
cd zygisk
shfmt -w -s *.sh
clang-format -i src/*.cpp
Expand Down
2 changes: 2 additions & 0 deletions gen_aidl.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# $ANDROID_SDK_ROOT/build-tools/$version/aidl
aidl --lang=rust aidl/IRemoteService.aidl -o src/cpu_common/binder
2 changes: 2 additions & 0 deletions module/customize.sh
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,6 @@ sh $MODPATH/vtools/init_vtools.sh $(realpath $MODPATH/module.prop)
set_perm_recursive $MODPATH 0 0 0755 0644
set_perm $MODPATH/fas-rs 0 0 0755

resetprop fas_rs_installed true

ui_print "Configuration folder: /sdcard/Android/fas-rs"
1 change: 0 additions & 1 deletion module/games.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
[config]
ignore_little = false
keep_std = true

[game_list]
Expand Down
8 changes: 5 additions & 3 deletions module/service.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@ MERGE_FLAG=$DIR/.need_merge
# update vtools support
sh $MODDIR/vtools/init_vtools.sh $(realpath $MODDIR/module.prop)

resetprop fas_rs_installed true

# wait until the sdcard is decrypted
until [ -d $DIR ]; do
sleep 1
done

# update config
if [ -f $MERGE_FLAG ]; then
$MODDIR/fas-rs --merge --local-profile $DIR/games.toml --std-profile $MODDIR/games.toml >$DIR/.update_games.toml
rm $MERGE_FLAG
mv $DIR/.update_games.toml $DIR/games.toml
$MODDIR/fas-rs --merge --local-profile $DIR/games.toml --std-profile $MODDIR/games.toml >$DIR/.update_games.toml
rm $MERGE_FLAG
mv $DIR/.update_games.toml $DIR/games.toml
fi

# start with user profile
Expand Down
220 changes: 220 additions & 0 deletions src/cpu_common/binder/IRemoteService.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
#![forbid(unsafe_code)]
#![allow(non_upper_case_globals)]
#![allow(non_snake_case)]
#![allow(clippy::all, clippy::pedantic)]
#![allow(dead_code)]

#[allow(unused_imports)]
use binder::binder_impl::IBinderInternal;
use binder::declare_binder_interface;
declare_binder_interface! {
IRemoteService["IRemoteService"] {
native: BnRemoteService(on_transact),
proxy: BpRemoteService {
},
async: IRemoteServiceAsync,
}
}
pub trait IRemoteService: binder::Interface + Send {
fn get_descriptor() -> &'static str
where
Self: Sized,
{
"IRemoteService"
}
fn writeFreq(&self, _arg_freq: i64, _arg_path: &str) -> binder::Result<()>;
fn getDefaultImpl() -> IRemoteServiceDefaultRef
where
Self: Sized,
{
DEFAULT_IMPL.lock().unwrap().clone()
}
fn setDefaultImpl(d: IRemoteServiceDefaultRef) -> IRemoteServiceDefaultRef
where
Self: Sized,
{
std::mem::replace(&mut *DEFAULT_IMPL.lock().unwrap(), d)
}
}
pub trait IRemoteServiceAsync<P>: binder::Interface + Send {
fn get_descriptor() -> &'static str
where
Self: Sized,
{
"IRemoteService"
}
fn writeFreq<'a>(
&'a self,
_arg_freq: i64,
_arg_path: &'a str,
) -> binder::BoxFuture<'a, binder::Result<()>>;
}
#[::async_trait::async_trait]
pub trait IRemoteServiceAsyncServer: binder::Interface + Send {
fn get_descriptor() -> &'static str
where
Self: Sized,
{
"IRemoteService"
}
async fn writeFreq(&self, _arg_freq: i64, _arg_path: &str) -> binder::Result<()>;
}
impl BnRemoteService {
/// Create a new async binder service.
pub fn new_async_binder<T, R>(
inner: T,
rt: R,
features: binder::BinderFeatures,
) -> binder::Strong<dyn IRemoteService>
where
T: IRemoteServiceAsyncServer + binder::Interface + Send + Sync + 'static,
R: binder::binder_impl::BinderAsyncRuntime + Send + Sync + 'static,
{
struct Wrapper<T, R> {
_inner: T,
_rt: R,
}
impl<T, R> binder::Interface for Wrapper<T, R>
where
T: binder::Interface,
R: Send + Sync,
{
fn as_binder(&self) -> binder::SpIBinder {
self._inner.as_binder()
}
fn dump(
&self,
_file: &std::fs::File,
_args: &[&std::ffi::CStr],
) -> std::result::Result<(), binder::StatusCode> {
self._inner.dump(_file, _args)
}
}
impl<T, R> IRemoteService for Wrapper<T, R>
where
T: IRemoteServiceAsyncServer + Send + Sync + 'static,
R: binder::binder_impl::BinderAsyncRuntime + Send + Sync + 'static,
{
fn writeFreq(&self, _arg_freq: i64, _arg_path: &str) -> binder::Result<()> {
self._rt
.block_on(self._inner.writeFreq(_arg_freq, _arg_path))
}
}
let wrapped = Wrapper {
_inner: inner,
_rt: rt,
};
Self::new_binder(wrapped, features)
}
}
pub trait IRemoteServiceDefault: Send + Sync {
fn writeFreq(&self, _arg_freq: i64, _arg_path: &str) -> binder::Result<()> {
Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
}
}
pub mod transactions {
pub const writeFreq: binder::binder_impl::TransactionCode =
binder::binder_impl::FIRST_CALL_TRANSACTION + 0;
}
pub type IRemoteServiceDefaultRef = Option<std::sync::Arc<dyn IRemoteServiceDefault>>;
use lazy_static::lazy_static;
lazy_static! {
static ref DEFAULT_IMPL: std::sync::Mutex<IRemoteServiceDefaultRef> =
std::sync::Mutex::new(None);
}
impl BpRemoteService {
fn build_parcel_writeFreq(
&self,
_arg_freq: i64,
_arg_path: &str,
) -> binder::Result<binder::binder_impl::Parcel> {
let mut aidl_data = self.binder.prepare_transact()?;
aidl_data.write(&_arg_freq)?;
aidl_data.write(_arg_path)?;
Ok(aidl_data)
}
fn read_response_writeFreq(
&self,
_arg_freq: i64,
_arg_path: &str,
_aidl_reply: std::result::Result<binder::binder_impl::Parcel, binder::StatusCode>,
) -> binder::Result<()> {
if matches!(_aidl_reply, Err(binder::StatusCode::UNKNOWN_TRANSACTION)) {
if let Some(_aidl_default_impl) = <Self as IRemoteService>::getDefaultImpl() {
return _aidl_default_impl.writeFreq(_arg_freq, _arg_path);
}
}
let _aidl_reply = _aidl_reply?;
let _aidl_status: binder::Status = _aidl_reply.read()?;
if !_aidl_status.is_ok() {
return Err(_aidl_status);
}
Ok(())
}
}
impl IRemoteService for BpRemoteService {
fn writeFreq(&self, _arg_freq: i64, _arg_path: &str) -> binder::Result<()> {
let _aidl_data = self.build_parcel_writeFreq(_arg_freq, _arg_path)?;
let _aidl_reply = self.binder.submit_transact(
transactions::writeFreq,
_aidl_data,
binder::binder_impl::FLAG_PRIVATE_LOCAL,
);
self.read_response_writeFreq(_arg_freq, _arg_path, _aidl_reply)
}
}
impl<P: binder::BinderAsyncPool> IRemoteServiceAsync<P> for BpRemoteService {
fn writeFreq<'a>(
&'a self,
_arg_freq: i64,
_arg_path: &'a str,
) -> binder::BoxFuture<'a, binder::Result<()>> {
let _aidl_data = match self.build_parcel_writeFreq(_arg_freq, _arg_path) {
Ok(_aidl_data) => _aidl_data,
Err(err) => return Box::pin(std::future::ready(Err(err))),
};
let binder = self.binder.clone();
P::spawn(
move || {
binder.submit_transact(
transactions::writeFreq,
_aidl_data,
binder::binder_impl::FLAG_PRIVATE_LOCAL,
)
},
move |_aidl_reply| async move {
self.read_response_writeFreq(_arg_freq, _arg_path, _aidl_reply)
},
)
}
}
impl IRemoteService for binder::binder_impl::Binder<BnRemoteService> {
fn writeFreq(&self, _arg_freq: i64, _arg_path: &str) -> binder::Result<()> {
self.0.writeFreq(_arg_freq, _arg_path)
}
}
fn on_transact(
_aidl_service: &dyn IRemoteService,
_aidl_code: binder::binder_impl::TransactionCode,
_aidl_data: &binder::binder_impl::BorrowedParcel<'_>,
_aidl_reply: &mut binder::binder_impl::BorrowedParcel<'_>,
) -> std::result::Result<(), binder::StatusCode> {
match _aidl_code {
transactions::writeFreq => {
let _arg_freq: i64 = _aidl_data.read()?;
let _arg_path: String = _aidl_data.read()?;
let _aidl_return = _aidl_service.writeFreq(_arg_freq, &_arg_path);
match &_aidl_return {
Ok(_aidl_return) => {
_aidl_reply.write(&binder::Status::from(binder::StatusCode::OK))?;
}
Err(_aidl_status) => _aidl_reply.write(_aidl_status)?,
}
Ok(())
}
_ => Err(binder::StatusCode::UNKNOWN_TRANSACTION),
}
}
pub mod mangled {
pub use super::IRemoteService as _14_IRemoteService;
}
71 changes: 71 additions & 0 deletions src/cpu_common/binder/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* Copyright 2023 [email protected]
*
* 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. */
#![allow(non_snake_case)]
mod IRemoteService;

use std::{
fs,
os::unix::fs::PermissionsExt,
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
thread,
};

use anyhow::Result;
use binder::{BinderFeatures, Interface};
use log::info;

use IRemoteService::BnRemoteService;

pub struct UperfExtension {
fas_status: Arc<AtomicBool>,
}

impl UperfExtension {
pub fn run_server(fas_status: Arc<AtomicBool>) -> Result<()> {
thread::Builder::new()
.name("BinderServer".into())
.spawn(|| Self::run(fas_status))?;

Ok(())
}

fn run(fas_status: Arc<AtomicBool>) -> Result<()> {
let server = Self { fas_status };
let server = BnRemoteService::new_binder(server, BinderFeatures::default());

binder::add_service("fas_rs_server_uperf", server.as_binder())?;

info!("Binder server started");
binder::ProcessState::join_thread_pool();

Ok(())
}
}

impl Interface for UperfExtension {}

impl IRemoteService::IRemoteService for UperfExtension {
fn writeFreq(&self, freq: i64, path: &str) -> binder::Result<()> {
if !self.fas_status.load(Ordering::Acquire) {
let _ = fs::set_permissions(path, PermissionsExt::from_mode(0o644));
let _ = fs::write(path, freq.to_string());
let _ = fs::set_permissions(path, PermissionsExt::from_mode(0o444));
}

Ok(())
}
}
Loading

0 comments on commit 5f508df

Please sign in to comment.