AOSP新增AIDL调用

    在做AOSP开发的时候可能会遇到这种情况,上层的APP需要调用Api做一些操作,但是这些操作App是没有权限去做的,只有系统进程才有权限去做. 该怎么样实现呢, 其实很简单,仿照其它的Manager去做即可.

    1. 写一个AIDL接口文件. 放在framewrok /base/core 包下任意目录, 建议放在android.os包下面.  可以参照里面其它的aidl文件来写就是了. 可以不用 parcelable     

package android.os;

/**
  * 该接口中定义你要做的操作.
  */ 
interface IDeviceVoManager {

    String readAndroidId(int userId);

}

      

    2. 写一个Service类. 建议放到 frameworks/base/services/core/java/com/android/server/ 目录下   该Service需要继承上面写的AIDL文件   

/**
 * 该类中的一些操作 可以以system权限来执行. 可以做很多上层被限制了的操作.
 */
public class DeviceVoManagerService extends IDeviceVoManager.Stub {

    private static final String TAG = "DeviceVoManagerService";

    private Context mContext;


    /** @hide **/
    public DeviceVoManagerService() {
        this.mContext = null;

    }
    /** @hide **/
    public DeviceVoManagerService(Context context) {
        Context appContext = context.getApplicationContext();
        if (appContext != null) {
            mContext = appContext;
        } else {
            mContext = context;
        }
    }

    /**
     * 实现AIDL 接口文件中的方法
     */   
    @Override
    public String readAndroidId(int userId) throws RemoteException {
      
        return "ea8323ea26522";
    }
   

 3. 写一个类来调用 Service层 . 注意  DEVICE_VO_SERVICE 是我们自己在Context类中定义的名字.  

 frameworks/base/core/java/android/content/Context.java 类中修改

 
 public static final String DEVICE_VO_SERVICE="xxxxx";

 
 @StringDef({
    //在该注解中加入Service的名字 方便根据名字调用
    .. 
    DEVICE_VO_SERVICE
    ..
 })  
 @Retention(RetentionPolicy.SOURCE)
 public @interface ServiceName {}
@SystemService(Context.DEVICE_VO_SERVICE)
public final class DeviceVoManager  {

    private static final String TAG = "DeviceVoManager";

    private final IDeviceVoManager mService;

    private final Context mContext;

    private static final String UNKNOWN = "UNKNOWN";
    
  
    /** @hide */
    public static DeviceVoManager get(Context context) {
        return (DeviceVoManager) context.getSystemService(Context.DEVICE_VO_SERVICE);
    }

    /** @hide */
    public DeviceVoManager(Context context, IDeviceVoManager service) {
        mService = service;
        mContext = context.getApplicationContext();
        Log.i(TAG,"===DeviceVoManager===");
    }
    
}

4. 在frameworks/base/services/java/com/android/server/SystemServer.java 中添加如下片段

 try {
    //新增加服务 DeviceVoManagerService
    traceBeginAndSlog("DeviceVoService");
    ServiceManager.addService(Context.DEVICE_VO_SERVICE,new DeviceVoManagerService());
    traceEnd();   
 }catch (Throwable e){
    Slog.i("SystemServer","Start DeviceVoManagerService failed !");
 }   

    在 frameworks/base/core/java/android/app/SystemServiceRegistry.java 中添加如下

 //注册服务
 registerService(Context.DEVICE_VO_SERVICE, DeviceVoManager.class,
           new CachedServiceFetcher<DeviceVoManager>() {
       @Override
       public DeviceVoManager createService(ContextImpl ctx) {
            IBinder b = ServiceManager.getService(Context.DEVICE_VO_SERVICE);
            IDeviceVoManager service = IDeviceVoManager.Stub.asInterface(b);
            return new DeviceVoManager(ctx, service);
       }});    

5. 在frameworks/base/Android.mk 文件中将我们的aidl文件路径加进去.可以看到很多AIDL文件都在此处.

6. 很重要的一步.  在system/sepolicy 中需要加入相应的SE限制

  /system/sepolicy/private/service_contexts 文件中增加如下
  //注意 xxxx 指的是 在Context.java类中定义的Service的名字 不要乱写
  
  private/service_contexts:xxxx                u:object_r:xxxx_service:s0
  
   
  public/servicemanager.te文件中新增加如下

  allow untrusted_app xxxx_service:service_manager {find };


  
  public/service.te 文件中新增加如下
  
  type xxxx_service,app_api_service, ephemeral_app_api_service, system_server_service, 
    service_manager_type;

OK, 到此流程就完成了.

仿照其它的Manager服务 进行调用就是了.


 

猜你喜欢

转载自blog.csdn.net/SpHinner/article/details/84950589