最近在做的一个功能:实现app去替换按键映射到新的键值(以及后续可能添加按键功能等需求). 想到直接新增System Service,提供Binder服务,起到桥梁作用,来实现这个功能.
关于binder机制,有很多blog说这个问题,这里就不多说了,此篇文章主要实现api定制中出现的问题,以及用androidStudio写app使用定制的api时遇到的问题解决方法等.
- add service
frameworks/base/services/core/java/com/android/server/MaskService.java
package com.android.server;
import android.util.Log;
import android.content.Context;
import android.app.IMaskManager;
public class MaskService extends IMaskManager.Stub{
private static final String TAG = "MaskService";
private final Context mContext;
public MaskService(Context context) {
mContext = context;
}
@Override
public int func1(int code){
int key = 0;
//TODO:
Log.i(TAG,"-------func1---------");
return key;
}
@Override
public void func2(String str1,int num,String str2){
//TODO:
Log.i(TAG,"-------func2---------");
}
@Override
public boolean func3(boolean b){
boolean result = false;
//TODO:
Log.i(TAG,"-------func3---------");
return result;
}
}
- add Context
frameworks/base/core/java/android/content/Context.java
@@ -3494,6 +3494,8 @@ public abstract class Context {
//@hide: TIME_ZONE_DETECTOR_SERVICE,
PERMISSION_SERVICE,
LIGHTS_SERVICE,
+ MASK_SERVICE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ServiceName {}
@@ -5163,6 +5165,10 @@ public abstract class Context {
*/
public static final String LIGHTS_SERVICE = "lights";
+ public static final String MASK_SERVICE = "mask";
+
- add manager
frameworks/base/core/java/android/app/MaskManager.java
package android.app;
import android.app.IMaskManager;
import android.annotation.SystemService;
import android.content.Context;
import android.os.RemoteException;
@SystemService(Context.MASK_SERVICE)
public class MaskManager {
private final IMaskManager mService;
private Context mContext;
public MaskManager(Context context,IMaskManager service){
mContext = context;
mService = service;
}
public int func1(int code){
int key = 0;
try{
key = mService.func1(code);
}catch (RemoteException e){
throw e.rethrowFromSystemServer();
}
return key;
}
public void func2(String str1,int num,String str2){
try{
mService.func2(str1,num,str2);
}catch (RemoteException e){
throw e.rethrowFromSystemServer();
}
}
public boolean func3(boolean b){
boolean result = false;
try{
result = mService.func3(b);
}catch (RemoteException e){
throw e.rethrowFromSystemServer();
}
return result;
}
}
- add AIDL
frameworks/base/core/java/android/app/IMaskManager.aidl
package android.app;
interface IMaskManager {
int func1(int code);
void func2(String str1,int num,String str2);
boolean func3(boolean b);
}
- add bp编译文件
frameworks/base/Android.bp
添加 --api-lint-ignore-prefix android.app. 是由于Android11开启了lint代码检查,所以要在bp里忽略代码检查.
--- a/Android.bp
+++ b/Android.bp
@@ -42,6 +42,8 @@ filegroup {
srcs: [
+ "core/java/android/app/IMaskManager.aidl",
@@ -403,7 +405,8 @@ java_defaults {
generate_get_transaction_name: true,
},
exclude_srcs: [
// See comment on framework-atb-backward-compatibility module below
@@ -1223,6 +1226,7 @@ metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.x
+ "--api-lint-ignore-prefix android.app. " +
- 权限
system/sepolicy
modified: prebuilts/api/26.0/private/service_contexts modified: prebuilts/api/26.0/public/service.te modified: prebuilts/api/27.0/private/service_contexts modified: prebuilts/api/27.0/public/service.te modified: prebuilts/api/28.0/private/service_contexts modified: prebuilts/api/28.0/public/service.te modified: prebuilts/api/29.0/private/service_contexts modified: prebuilts/api/29.0/public/service.te modified: prebuilts/api/30.0/private/service_contexts modified: prebuilts/api/30.0/public/service.te modified: private/service_contexts modified: public/service.te service.te 中添加: +type mask_service, system_api_service, system_server_service, service_manager_type; service_contexts 中添加: +mask u:object_r:mask_service:s0
- 将MaskService添加到系统服务
frameworks/base/services/java/com/android/server/SystemServer.java
( startOtherServices)
+import com.android.server.MaskService;
public final class SystemServer {
@@ -1049,6 +1051,8 @@ public final class SystemServer {
HardwarePropertiesManagerService hardwarePropertiesService = null;
+ MaskService mMask = null;
+ // Serivce for MaskService. add by suntianhai 2022.05.26
+ t.traceBegin("StartMaskService");
+ mMask = new MaskService(context);
+ ServiceManager.addService(Context.MASK_SERVICE, mMask);
+ t.traceEnd();
- registerService
frameworks/base/core/java/android/app/SystemServiceRegistry.java
@@ -1369,6 +1369,26 @@ public final class SystemServiceRegistry {
}});
+ registerService(Context.MASK_SERVICE, MaskManager.class,
+ new CachedServiceFetcher() {
+ @Override
+ public MaskManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ IBinder b = ServiceManager.getServiceOrThrow(Context.MASK_SERVICE);
+ return new MaskManager(ctx,
+ IMaskManager.Stub.asInterface(b));
+ }});
+
- 更新api
不更新api编译的话会报错如下 谷歌对于所有的类和API,分为开放和非开放两种,而开放的类和API可以通过“javadoc标签”与源码同步生成“程序的开发文档”;当我们修改或者添加一个新的API时,我们有两种方法可以避免出现上述错误,第一种是将该接口加上非公开的标签:/*{@hide}/;再者可以在修改后执行:make update-api(公开),将修改内容与API的doc文件更新到一致。
make update-api
make api-stubs-docs-update-current-api
- 将项目整编,拿到编译完的outtargetcommonobjJAVA_LIBRARIESframework_intermediatesclasses.jar包,(我把它重命名为framework-r.jar)
将framework-r.jar放到AS项目的libs下.如果整编完没有在outtargetcommonobjJAVA_LIBRARIESframework_intermediates下找到classes.jar,可以make javac-check-framework重新生成:
[100% 509/509] Copy: out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
- 在项目的build.gradle里添加
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << '-Xbootclasspath/p:app/libs/framework-r.jar'
}
}
- 在app的build.gradle里添加:
dependencies {
compileOnly files('libs/framework-r.jar')
app直接调用就好了
mMaskManager = (MaskManager)getSystemService(Context.MASK_SERVICE);
出现编译Context.MASK_SERVICE错误的话 就在app的build.gradle里添加:
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
Set fileSet = options.bootstrapClasspath.getFiles()
List newFileList = new ArrayList<>();
//JAVA语法,可连续调用,输入参数建议为相对路径
newFileList.add(new File("libs/framework-r.jar"))
//最后将原始参数添加
newFileList.addAll(fileSet)
options.bootstrapClasspath = files(
newFileList.toArray()
)
}
}



