AOSP新增AIDL调用

5 篇文章 0 订阅
1 篇文章 0 订阅

    在做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);
       }});    

注意: 如果你的Manager 有被其它服务调用. 要把这两段定义放在调用者的服务之前. 以免调用的时候出现未初始化的的异常.

这两个类中的 各种服务顺序不要随便改动. 有的存在互相调用关系.

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服务 进行调用就是了.


 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在 Android AOSP 源码的 device 目录下添加自定义的 framework 模块的步骤如下: 1. 创建新的模块目录: 在 device/{vendor_name}/{device_name}/ 目录下创建一个新的子目录,用于存放自定义的 framework 模块。例如,可以创建一个名为 myframework 的目录: ``` mkdir -p device/{vendor_name}/{device_name}/myframework ``` 2. 添加 Android.mk 文件: 在 myframework 目录下创建一个名为 Android.mk 的文件,用于定义自定义的 framework 模块。例如,可以添加以下代码: ``` LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := myframework LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := JAVA_LIBRARIES LOCAL_SRC_FILES := MyFramework.java LOCAL_SDK_VERSION := current LOCAL_JAVA_LIBRARIES := core-libart LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 LOCAL_STATIC_ANDROID_LIBRARIES := libsqlite include $(BUILD_JAVA_LIBRARY) ``` 其中: - LOCAL_MODULE 定义了模块名称; - LOCAL_MODULE_TAGS 定义了模块的标签,optional 表示该模块是可选的; - LOCAL_MODULE_CLASS 定义了模块的类型,JAVA_LIBRARIES 表示该模块是一个 Java 库; - LOCAL_SRC_FILES 定义了该模块中包含的 Java 源代码文件; - LOCAL_JAVA_LIBRARIES 定义了该模块所依赖的 Java 库; - LOCAL_STATIC_JAVA_LIBRARIES 和 LOCAL_STATIC_ANDROID_LIBRARIES 定义了该模块所依赖的静态库和 Android 库。 3. 添加 Android.bp 文件: 在 myframework 目录下创建一个名为 Android.bp 的文件,用于定义自定义的 framework 模块。例如,可以添加以下代码: ``` java_library { name: "myframework", srcs: ["MyFramework.java"], static_libs: [ "core-libart", "android-support-v4", ], shared_libs: [ "libsqlite", ], sdk_version: "current", installable: true, } ``` 其中: - name 定义了模块名称; - srcs 定义了该模块中包含的 Java 源代码文件; - static_libs 定义了该模块所依赖的静态库; - shared_libs 定义了该模块所依赖的共享库; - sdk_version 定义了该模块所需的 Android SDK 版本; - installable 定义了该模块是否可安装。 4. 编译 Android 系统: 在编译 Android 系统之前,需要先执行以下命令: ``` source build/envsetup.sh ``` 然后编译 Android 系统: ``` lunch {device_name}-{build_type} make -j{n} ``` 其中 {device_name} 是设备名称,{build_type} 是编译类型(如 userdebug),{n} 是编译线程数。 编译完成后,就可以在 Android 系统中使用自定义的 framework 模块了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值