注意:源码用的是android10 源码
添加系统服务接口分为两个过程:在framework添加服务及接口,在本地app端添加调用接口
一、framework添加服务及接口
步骤1:添加系统包
在/buildsystem/android/frameworks/base/core/java/android路径下添加文件夹(我自己创建的为lilitest/addapi,包名为android.lilitest.addapi)
步骤2:新建aidl文件
在/buildsystem/android/frameworks/base/core/java/android/lilitest/addapi文件下新建aidl文件(如:IAddApiTest.aidl)
注意:包名为“android.lilitest.addapi”
// IAddApiTest.aidl
package android.lilitest.addapi;
// Declare any non-default types here with import statements
interface IAddApiTest {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void setName(String name);
String getName();
}
步骤3:编写系统级服务
在/buildsystem/android/frameworks/base/core/java/android/lilitest/addapi文件下新建service.java文件(如:AddApiTestService.java)
注意:包名为“android.lilitest.addapi”
package android.lilitest.addapi;
import android.os.RemoteException;
import android.util.Log;
/**
* @ClassName AddApiTestService
* @Description //TODO
* @Author lili
* @DATE 2022/10/21 15:04
*/
public class AddApiTestService extends IAddApiTest.Stub{
private String name;
@Override
public void setName(String name) throws RemoteException {
Log.d("AddApiTestService","setName = " + name);
this.name = name;
}
@Override
public String getName() throws RemoteException {
return name;
}
}
步骤4:定义java接口
在注册之前我们先在buildsystem/android/frameworks/base/core/java/android/content/Context.java中添加一个常量
/**
* liliadd:add API test
*/
public static final String ADD_API_TEST_SERVICE = "add_api_test";
添加常量的目的:就是给服务起一个名字,好比我们再应用层使用服务的时候注册的名字一样,以后使用这个服务的时候都用这个名字就可以了。
在/buildsystem/android/frameworks/base/core/java/android/lilitest/addapi文件下新建manager.java文件(如:AddApiTestManager.java)将新加的服务及接口暴露到客户端。
注意:包名为“android.lilitest.addapi”
package android.lilitest.addapi;
import android.content.Context;
import android.os.Build;
import android.os.RemoteException;
import android.os.ServiceManager;
import java.io.PrintStream;
/**
* @ClassName AddApiTestManager
* @Description //TODO
* @Author lili
* @DATE 2022/10/21 15:54
*/
public class AddApiTestManager {
private IAddApiTest mService;
private static AddApiTestManager mInstance;
private Context mContext;
public AddApiTestManager() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//Context.ADD_API_TEST_SERVICE: add the service name
mService = IAddApiTest.Stub.asInterface(ServiceManager.getService(Context.ADD_API_TEST_SERVICE));
}
}
public static AddApiTestManager getInstance() {
if (mInstance == null) {
synchronized (AddApiTestManager.class) {
if (mInstance == null) {
mInstance = new AddApiTestManager();
}
}
}
return mInstance;
}
public void setName(String name) {
try {
mService.setName(name);
}catch (RemoteException e) {
e.printStackTrace();
}
}
public String getName() {
try {
return mService.getName();
}catch (RemoteException e) {
e.printStackTrace();
return "";
}
}
}
步骤5:配置aidl
在/buildsystem/android/frameworks/base/Android.bp添加新增的adil文件
"core/java/android/lilitest/addapi/IAddApiTest.aidl",
```![在这里插入图片描述](https://img-blog.csdnimg.cn/1ceebb524f0e43e591091895428fa888.png)
添加好之后,使用make update-api命令,查看buildsystem/android/frameworks/base/api/current.txt文件,新增aidl接口说明,证明aidl配置成功。
```csharp
package android.lilitest.addapi {
public class AddApiTestManager {
ctor public AddApiTestManager();
method public static android.lilitest.addapi.AddApiTestManager getInstance();
method public String getName();
method public void setName(String);
}
public class AddApiTestService extends android.lilitest.addapi.IAddApiTest.Stub {
ctor public AddApiTestService();
method public String getName() throws android.os.RemoteException;
method public void setName(String) throws android.os.RemoteException;
}
public interface IAddApiTest extends android.os.IInterface {
method public String getName() throws android.os.RemoteException;
method public void setName(String) throws android.os.RemoteException;
}
public static class IAddApiTest.Default implements android.lilitest.addapi.IAddApiTest {
ctor public IAddApiTest.Default();
method public android.os.IBinder asBinder();
method public String getName() throws android.os.RemoteException;
method public void setName(String) throws android.os.RemoteException;
}
public abstract static class IAddApiTest.Stub extends android.os.Binder implements android.lilitest.addapi.IAddApiTest {
ctor public IAddApiTest.Stub();
method public android.os.IBinder asBinder();
method public static android.lilitest.addapi.IAddApiTest asInterface(android.os.IBinder);
method public static android.lilitest.addapi.IAddApiTest getDefaultImpl();
method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
method public static boolean setDefaultImpl(android.lilitest.addapi.IAddApiTest);
}
}
步骤6:注册服务
在buildsystem/android/frameworks/base/core/java/android/app/SystemServiceRegistry.java文件中添加如下注册代码:
import android.lilitest.addapi.AddApiTestManager;
//liliadd:221024_10_03 start
registerService(Context.ADD_API_TEST_SERVICE, AddApiTestManager.class,
new StaticServiceFetcher<AddApiTestManager>() {
@Override
public AddApiTestManager createService() throws ServiceNotFoundException {
return AddApiTestManager.getInstance();
}});
//liliadd:221024_10_03 end
步骤7:将新增服务添加到SystemServer
在buildsystem/android/frameworks/base/services/java/com/android/server/SystemServer.java文件startOtherServices方法中添加新增服务
import android.lilitest.addapi.AddApiTestService;
import android.util.Log;
//lilitest:add 221024_1045 start
Log.d("lilitest","start lilitest add_api_test service ");
traceBeginAndSlog("start lilitest add_api_test service");//log日志
try {
Slog.i(TAG, "add lilitest add_api_test Service");//log日志
Log.d("lilitest","add lilitest add_api_test Service ");
// Serial port support
AddApiTestService addApiService = new AddApiTestService();//创建service
ServiceManager.addService(Context.ADD_API_TEST_SERVICE, addApiService);//添加Service
} catch (Throwable e) {
Slog.e(TAG, "add lilitest add_api_test Service SerialService", e);
Log.d("lilitest","add lilitest add_api_test Service SerialService");
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
//lilitest:add 221024_1045 end
步骤8:权限策略配置
路径:buildsystem/android/system/sepolicy/private/service_contexts;
buildsystem/android/system/sepolicy/prebuilts/api/29.0/private/service_contexts中添加
addapitest u:object_r:addapitest_service:s0
路径:buildsystem/android/system/sepolicy/private/service.te;
buildsystem/android/system/sepolicy/prebuilts/api/29.0/private/service.te中添加
type addapitest_service, system_api_service, system_server_service, service_manager_type;
二、编写应用层调用代码
//AddApiTestManager.java 注意:应用端该文件包名必须与framework服务端AddApiTestManager.java包名相同
package android.lilitest.addapi;
/**
* @ClassName AddApiTestManager
* @Description //TODO
* @Author lili
* @DATE 2022/10/25 8:42
*/
public class AddApiTestManager {
private static String TAG = "AddApiTestManager";
private static AddApiTestManager mInstance = null;
public static synchronized AddApiTestManager getInstance() {
throw new RuntimeException("API not supported!");
}
public void setName(String name) {
throw new RuntimeException("API not supported!");
}
public String getName() {
throw new RuntimeException("API not supported!");
}
}
//MainActivity.java调用
package android.lilitest.addapi;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import androidx.annotation.Nullable;
import com.htkj.addapi.R;
/**
* @ClassName MainActivity
* @Description //TODO
* @Author lili
* @DATE 2022/10/25 8:50
*/
public class MainActivity extends Activity implements View.OnClickListener {
private Button mBtSetName;
private Button mBtGetName;
private AddApiTestManager mAddApiTestManager;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAddApiTestManager = AddApiTestManager.getInstance();
mBtSetName = findViewById(R.id.bt_setname);
mBtSetName.setOnClickListener(this);
mBtGetName = findViewById(R.id.bt_getname);
mBtGetName.setOnClickListener(this);
}
@Override
public void onClick(View view) {
int id = view.getId();
switch (id) {
case R.id.bt_setname:
mAddApiTestManager.setName("addApiTest11111111");
break;
case R.id.bt_getname:
String name = mAddApiTestManager.getName();
Log.d("mAddApiTestManager","name = " + name);
break;
}
}
}