1.编写.aidl文件
存放位置:frameworks/base/core/java/android/os
package android.os;
interface ISystemVoiceServer {
void setHeightVoice(int flag);
void setBassVoice(int flag);
void setReverbVoice(int flag);
}
2.将.aidl文件添加到frameworks/base/Android.bp
filegroup {
name: "framework-core-sources",
srcs: [
"core/java/**/*.java",
"core/java/**/*.aidl",
],
path: "core/java",
}
说明:android.bp文件中默认把core/java/目录下的aidl文件添加到编译文件中,所以这一步不需要操作.
由于Android 11对语法检测比较严格,所以针对我们新增的文件先加入忽略:
// TODO(b/145644363): move this to under StubLibraries.bp or ApiDocs.bp
metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.xml) " +
"--ignore-classes-on-classpath " +
"--hide-package com.android.server " +
"--error UnhiddenSystemApi " +
"--hide RequiresPermission " +
"--hide CallbackInterface " +
"--hide MissingPermission --hide BroadcastBehavior " +
"--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
"--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo " +
"--force-convert-to-warning-nullability-annotations +*:-android.*:+android.icu.*:-dalvik.* " +
"--api-lint-ignore-prefix android.icu. " +
"--api-lint-ignore-prefix java. " +
"--api-lint-ignore-prefix android.os. " + //新增这一行
"--api-lint-ignore-prefix android.app. " + //新增这一行
"--api-lint-ignore-prefix junit. " +
"--api-lint-ignore-prefix org. "
3、Context.java添加服务注册名称, 添加该服务名称, 用于快捷注册和快捷引用
修改位置:frameworks/base/core/java/android/content/
//增加新增定义服务名称
/**
* Use with {@link #getSystemService(String)} to retrieve a
* {@link android.app.SystemVoiceManager} for accessing
* text services.
*
* @see #getSystemService(String)
*/
public static final String SYSTEMVOCIE_SERVICER = "systemvoice";
/** @hide */
@StringDef(suffix = { "_SERVICE" }, value = {
POWER_SERVICE,
SYSTEMVOCIE_SERVICER, //此处新增服务
WINDOW_SERVICE,
LAYOUT_INFLATER_SERVICE,
......}
4、新建SystemVoiceService.java和SystemVoiceManager.java
存放位置:frameworks\base\services\core\java\com\android\server\SystemVoiceService.java
frameworks\base\core\java\android\app\SystemVoiceManager.java
package com.android.server;
import android.app.SystemVoiceManager;
import android.content.Context;
import android.os.ISystemVoiceServer;
import android.os.RemoteException;
import com.android.server.SystemService;
import com.android.internal.app.IAppOpsService;
public class SystemVoiceService extends SystemService {
private final String TAG = "SystemVoiceService";
private Context mContext;
private IAppOpsService mAppOps;
private SystemVoiceManager mManager;
public SystemVoiceService(Context context) {
super(context);
this.mContext = context;
}
public void systemReady(IAppOpsService appOps) {
mAppOps = appOps;
if (mManager == null) {
mManager = (SystemVoiceManager) mContext.getSystemService(Context.SYSTEMVOICE_SERVICE);
}
}
@Override
public void onStart() {
publishBinderService(Context.SYSTEMVOICE_SERVICE, new BinderService());
}
private final class BinderService extends ISystemVoiceServer.Stub {
@Override
public void setHeightVoice(int flag) throws RemoteException {
}
@Override
public void setBassVoice(int flag) throws RemoteException {
}
@Override
public void setReverbVoice(int flag) throws RemoteException {
}
}
}
package android.app;
import android.content.Context;
import android.os.ISystemVoiceServer;
import android.util.Log;
import android.annotation.SystemService;
import android.os.RemoteException;
@SystemService(Context.SYSTEMVOICE_SERVICE)
public class SystemVoiceManager {
private static final String TAG = "SystemVoiceManager";
private ISystemVoiceServer mService;
private Context context;
public SystemVoiceManager(Context ctx, ISystemVoiceServer service) {
mService = service;
context = ctx;
}
public void setHeightVoice(int flag) {
try {
mService.setHeightVoice(flag);
} catch (Exception e) {
e.printStackTrace();
}
}
public void setBassVoice(int flag) {
try {
mService.setBassVoice(flag);
} catch (Exception e) {
e.printStackTrace();
}
}
public void setReverbVoice(int flag) {
try {
mService.setReverbVoice(flag);
} catch (Exception e) {
e.printStackTrace();
}
}
}
5、SystemServer.java 中注册该service
修改位置: frameworks\base\services\java\com\android\server
import com.android.server.SystemVoiceService ;//导包
private SystemVoiceService mSystemVoiceService; //定义
//系统服务加入的位置加入以下内容
t.traceBegin("StartSystemVoiceManager");
mSystemVoiceService = mSystemServiceManager.startService(SystemVoiceService.class);
t.traceEnd();
//系统服务加入的位置加入以下内容
t.traceBegin("MakeSystemVoiceManagerServiceReady");
try {
// TODO: use boot phase
mSystemVoiceService.systemReady(mActivityManagerService.getAppOpsService());
} catch (Throwable e) {
reportWtf("making SystemVoice Manager Service ready", e);
}
t.traceEnd();
6、SystemServiceRegistry的static{}, 并在其中注册该service
修改位置:frameworks\base\core\java\android\app
import android.os.ISystemVoiceServer;//导包
//SystemVoiceManager在同一目录下所以不用导包
registerService(Context.SYSTEMVOICE_SERVICE, SystemVoiceManager.class,
new CachedServiceFetcher<SystemVoiceManager>() {
@Override
public SystemVoiceManager createService(ContextImpl ctx)
throws ServiceNotFoundException {
IBinder b = ServiceManager.getServiceOrThrow(
Context.SYSTEMVOICE_SERVICE);
return new SystemVoiceManager(
ctx.getOuterContext(),ISystemVoiceService.Stub.asInterface(b));
}});
以上步骤完成我们的自定义系统服务就完成了90% 但是我们还有最后一步,也是最重要的一步:
然后我们只需要添加这个自定义服务SystemVoiceService相关的 SELinux 规则。为了方便之后验证,打开selinux
要记住这个命令 adb shell setenforce 1 # 1为打开 #0为关闭
Android 11 的 selinux 规则是放在 system/sepolicy 目录下的:
service.te 和 service_contexts 都要加上SystemVoiceService的配置:
//在以下目录文件
./prebuilts/api/30.0/public/service.te # 需要
./public/service.te # 需要
//添加以下内容
type systemvoice_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
//在以下目录文件
./prebuilts/api/30.0/private/service_contexts # 需要
./private/service_contexts # 需要
//添加以下内容
systemvoice_service u:object_r:isystemvoice_service:s0
添加完配置后,Android11版本还要需要在以下目录修改以下忽略配置,才能正常编译
在以下目录
./prebuilts/api/30.0/private/compat/29.0/29.0.ignore.cil
./prebuilts/api/30.0/private/compat/28.0/28.0.ignore.cil
./prebuilts/api/30.0/private/compat/27.0/27.0.ignore.cil
./prebuilts/api/30.0/private/compat/26.0/26.0.ignore.cil
./private/compat/29.0/29.0.ignore.cil
./private/compat/28.0/28.0.ignore.cil
./private/compat/27.0/27.0.ignore.cil
./private/compat/26.0/26.0.ignore.cil
到此,android 11 系统服务已经添加完成!.
8、验证:
编译完成后,输入adb shell
#service list
查看服务列表中 是否存在有添加服务 :itest
如果不存在 逐步排查 参照上一步看哪一步错误
如果存在 就在代码中验证
找到编译最新生成的class.jar文件,导入Androidstudio(如何导入自行百度)
编译后的class.jar目录\out\target\common\obj\JAVA_LIBRARIES\framework_intermediates
如果未生成 执行下make javac-check-framework 这个命令 就会生成!!!
觉得我写的好的兄弟 动动你发财的小手 点个赞 !!!
你们的认同将是我继续写下去的动力 !!