基本原理就是调用ServiceManager中的接口
/**
* Place a new @a service called @a name into the service
* manager.
*
* @param name the name of the new service
* @param service the service object
*/
public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service, false);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
* Place a new @a service called @a name into the service
* manager.
*
* @param name the name of the new service
* @param service the service object
*/
public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service, false);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
首先,需要写一个aidl,这个接口能生成符合System Service的Stub和Proxy,他们都继承于IBinder
/** @hide */
interface IMyExample {
int checkPermission(String permissionName, int uid);
}
}
这东西被aidl的解释语言搞成了IMyExample.java(./target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/xxxx/IMyExample .java)
/*
* This file is auto-generated. DO NOT MODIFY.
*/
package com.mobvoi;
/** @hide */
package com.mobvoi;
/** @hide */
public interface IMyExample extends
android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.mobvoi.IMobvoiPermissionManager
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.mobvoi.IMobvoiPermissionManager
{
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
{
this.attachInterface(this, DESCRIPTOR);
}
public static com.mobvoi.IMyExample asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.mobvoi.IMyExample ))) {
return ((com.mobvoi.IMyExample )iin);
}
return new com.mobvoi.IMyExample.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_checkPermission:
{
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
int _arg1;
_arg1 = data.readInt();
int _result = this.checkPermission(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_checkPermission:
{
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
int _arg1;
_arg1 = data.readInt();
int _result = this.checkPermission(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class
Proxy implements com.mobvoi.IMyExample
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
/**
* [Permission Controller Functions]
*/
@Override public int checkPermission(java.lang.String permissionName, int uid) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(permissionName);
_data.writeInt(uid);
mRemote.transact(Stub.TRANSACTION_checkPermission, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_checkPermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
/**
* [Permission Controller Functions]
*/
public int checkPermission(java.lang.String permissionName, int uid) throws android.os.RemoteException;
}
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
/**
* [Permission Controller Functions]
*/
@Override public int checkPermission(java.lang.String permissionName, int uid) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(permissionName);
_data.writeInt(uid);
mRemote.transact(Stub.TRANSACTION_checkPermission, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_checkPermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
/**
* [Permission Controller Functions]
*/
public int checkPermission(java.lang.String permissionName, int uid) throws android.os.RemoteException;
}
写一个类去实现这个SystemService
public class MyExample extends IMyExample .Stub {
public MyExample (Context context) {
}
@Override
public int checkPermission(String permissionName, int uid) throws RemoteException {
}
@Override
public int checkPermission(String permissionName, int uid) throws RemoteException {
}
}
在某个地方添加到ServiceManager里面
ServiceManager.addService(“Service Name”, MyExample
);
另外,还要在SELinux中注册一下,这种机制也是为了避免App随便给系统添加服务
sepolicy/service/
service_contexts
Mmsstats u:object_r:system_app_service:s0
MyExample u:object_r:system_app_service:s0
sepolicy/proxy/
service_contexts
TicwearProxyNativeService u:object_r:ticwear_proxy_service:s0
com.mobvoi.ticwear.home.proxy.IMyExample u:object_r:system_server_service:s0