Android10 Framework层添加系统服务

一、环境

高通865 Android10

二、添加服务具体步骤

1、添加aidl文件

frameworks/base/core/java/android/os/IMyService.aidl

package android.os;
 
interface IMyService{
   int getSum(int data1,int data2);
}

2、 aidl 添加到 android.bp

frameworks/base/Android.bp

java_defaults {

    name: "framework-defaults",

    installable: true,

    srcs: [

        // From build/make/core/pathmap.mk FRAMEWORK_BASE_SUBDIRS

        "core/java/**/*.java",

        "graphics/java/**/*.java",

        "location/java/**/*.java",

        "lowpan/java/**/*.java",

         ..................

    "core/java/android/os/IMyService.aidl",

      ],

3、创建service文件,也就是aidl的具体实现

 frameworks/base/services/core/java/com/android/server/MyService.java

服务中的逻辑可能每个人的都不同,这里演示服务的定义

package com.android.server;


import android.os.IMyService;
import java.lang.Exception;
import android.os.RemoteException;
import android.util.Log;
import android.content.Intent;
import android.content.Context;
import android.os.SystemProperties;
import android.content.BroadcastReceiver;
import android.content.IntentFilter;
import android.app.AlarmManager;
import java.util.Calendar;
import android.app.PendingIntent;
import android.os.Build;
import android.os.SystemClock;
import android.text.TextUtils;
import java.util.concurrent.TimeUnit;
import java.io.IOException;
import android.os.Handler;

public class MyService extends IMyService.Stub{

    private static final String ACTION_TIME_UPDATE_MINUTE = "com.vclusters.runshell.MINUTE_UPDATE_TIME";	
    private String TAG="MyService";
    private Context mContext;
    private PendingIntent mTimeUpdateIntent;
    private AlarmManager mAlarmManager;
    private boolean mHasRegistered;	

    public MyService(Context context){
        mContext=context;
        Log.d(TAG, "MyService <- is open6...");
        try{
            registerBroadcastReceiver();
            startAlarm();
        }catch (Exception exception){
            Log.e(TAG, "MyService startTimerTask exception:"+exception.getMessage());
        }
    }

    @Override
    public int getSum(int data1,int data2) throws RemoteException{
        return data1+data2;
    }
  

    private void removeTimeUpdateHourlyAlarm() {
        if ((mTimeUpdateIntent != null) && (mAlarmManager != null)) {
           // Log.d(TAG, "[removeTimeUpdateHourlyAlarm]#");
           mAlarmManager.cancel(mTimeUpdateIntent);
        }
    }
	

    private void startAlarm(){
        Intent intent = new Intent();
        intent.setAction(ACTION_TIME_UPDATE_MINUTE);
        mTimeUpdateIntent = PendingIntent.getBroadcast(mContext, 100, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        mAlarmManager= (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                setTimeUpdateHourlyAlarm();
            }
    }, 5000);//注意:服务中调用AlarmManager服务,这里延迟5秒加载,这里有坑,服务中立即使用服务,存在mAppOps还没加载,checkpackage()时报错问题
    }

      private void setTimeUpdateHourlyAlarm() {

        if (mTimeUpdateIntent!=null&&mAlarmManager != null) {
            Log.d(TAG, "[setTimeUpdateHourlyAlarm]#");
			int actionShellTime = 1;
            long triggerAtMills = SystemClock.elapsedRealtime() + TimeUnit.MINUTES.toMillis(actionShellTime);
            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtMills, mTimeUpdateIntent);
            
           
        }
    }
	
    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (TextUtils.equals(action, ACTION_TIME_UPDATE_MINUTE)) {
                Log.d(TAG, "onReceive ACTION_TIME_UPDATE_MINUTE");
                removeTimeUpdateHourlyAlarm();
                setTimeUpdateHourlyAlarm();
            }else if (TextUtils.equals(action, Intent.ACTION_TIME_CHANGED)) {
                Log.d(TAG, "onReceive Intent.ACTION_TIME_CHANGED");
                //removeTimeUpdateHourlyAlarm();
                //setTimeUpdateHourlyAlarm();
            }
        }
    };
	
    private void registerBroadcastReceiver() {
        if (mHasRegistered) {
            return;
        }
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_TIME_CHANGED);
        filter.addAction(ACTION_TIME_UPDATE_MINUTE);
        mContext.registerReceiver(mBroadcastReceiver, filter);
        mHasRegistered = true;
    }

    private void unregisterBroadcastReceiver() {
        if (mHasRegistered) {
            mContext.unregisterReceiver(mBroadcastReceiver);
            mHasRegistered = false;
        }
    }
}

4、将MyService.java 添加到系统服务管理器中(即开机启动服务)

 frameworks/base/services/java/com/android/server/SystemServer.java

startOtherServices()中添加服务

import com.android.server.MyService;

private void startOtherServices(){
 traceBeginAndSlog("StartAlarmManagerService");
            mSystemServiceManager.startService(new AlarmManagerService(context));
            traceEnd();

            traceBeginAndSlog("StartInputManagerService");
            inputManager = new InputManagerService(context);
            traceEnd();
  ...................//上面省略无关代码
  Slog.i(TAG, "addService----MyService");
  try {
            ServiceManager.addService(Context.MY_SERVICE, new MyService(context));
      } catch (Throwable e) {
                Slog.e(TAG, "Failure starting MyService", e);
      }
 // 注意:添加服务最好添加到最后,例如,博主服务MyService.java中用到了AlarmManagerService,所以这//里的注册得放到AlarmManagerService后面,不然编译报错
}

 5、创建可由外部使用的接口(app中getSystemService(String serviceName)获取的服务将调用下面MyServiceManager.java中的函数)

frameworks/base/core/java/android/app/MyServiceManager.java

package android.app;

import android.util.Log;

import android.os.IMyService;

import android.content.Context;

import java.lang.Exception;

import android.os.RemoteException;

public class MyServiceManager{

    public static final String TAG = "MyServiceManager";

    private IMyService mService;

    public MyServiceManager(IMyService service){

        mService = service;

    }

    public int getSum(int data1,int data2){

        try{

            return mService.getSum(data1,data2);

        }catch(RemoteException e){

            Log.e(TAG,"error getSum "+e.toString());

            e.printStackTrace();

        }

        return 0;

    }

}

6、在Context 配置接口名称

frameworks/base/core/java/android/content/Context.java

 public static final String MY_SERVICE ="myservice";
  @StringDef(suffix = { "_SERVICE" }, value = {
            POWER_SERVICE,
            WINDOW_SERVICE,
            LAYOUT_INFLATER_SERVICE,
            ACCOUNT_SERVICE,
            ACTIVITY_SERVICE,
            ALARM_SERVICE,
            NOTIFICATION_SERVICE,
            ACCESSIBILITY_SERVICE,
            CAPTIONING_SERVICE,
            KEYGUARD_SERVICE,
            LOCATION_SERVICE,
            MY_SERVICE,

7、注册服务(app中getSystemService()将调用创建服务)

frameworks/base/core/java/android/app/SystemServiceRegistry.java

import android.os.IMyService;
import android.app.MyServiceManager;

final class SystemServiceRegistry {
    private static final String TAG = "SystemServiceRegistry";

    // Service registry information.
    // This information is never changed once static initialization has completed.
    private static final Map<Class<?>, String> SYSTEM_SERVICE_NAMES =
            new ArrayMap<Class<?>, String>();
    private static final Map<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
            new ArrayMap<String, ServiceFetcher<?>>();
    private static int sServiceCacheSize;

    // Not instantiable.
    private SystemServiceRegistry() {
    }

    static {
        //CHECKSTYLE:OFF IndentationCheck
        registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
                new CachedServiceFetcher<AccessibilityManager>() {
                    @Override
                    public AccessibilityManager createService(ContextImpl ctx) {
                        return AccessibilityManager.getInstance(ctx);
                    }
                });
     ................................//省略中间代码
     
            registerService(Context.MY_SERVICE, MyServiceManager.class,
                new CachedServiceFetcher<MyServiceManager>() {
                    @Override
                    public MyServiceManager createService(ContextImpl ctx) throws                 
                     ServiceNotFoundException {
                        IBinder b = ServiceManager.getServiceOrThrow(Context.MY_SERVICE);
                        if (b == null) {
                            return null;
                        }
                        IMyService service = IMyService.Stub.asInterface(b);
                        return new MyServiceManager(service);
                    }
                });
           }

三、新增api之后需要更新api

1、source build/envsetup.sh
2、lunch kona-userdebug
3、更新api(下面的命令如果没有执行,编译报错的时候会提示类似下面的命令,根据提示的命令执行,
不一定就是这里说的这两个命令去更新api)
make api-stubs-docs-update-current-api
或者make update-api

4、执行完步骤3后,current.txt会自动更新
frameworks/base/api/current.txt
类似下面这种:
field public static final String MY_SERVICE = "myservice";
  public interface IMyService extends android.os.IInterface {
    method public int getSum(int, int) throws android.os.RemoteException;
  }

  public static class IMyService.Default implements android.os.IMyService {
    ctor public IMyService.Default();
    method public android.os.IBinder asBinder();
    method public int getSum(int, int) throws android.os.RemoteException;
  }

  public abstract static class IMyService.Stub extends android.os.Binder implements android.os.IMyService {
    ctor public IMyService.Stub();
    method public android.os.IBinder asBinder();
    method public static android.os.IMyService asInterface(android.os.IBinder);
    method public static android.os.IMyService getDefaultImpl();
    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
    method public static boolean setDefaultImpl(android.os.IMyService);
  }

四、selinux配置策略(没有配置权限的话,服务中相关api供外部调用会提示错误)

1、在文件system/sepolicy/private/service_contexts添加如下内容

myservice                                 u:object_r:myservice_service:s0

2、在文件system/sepolicy/prebuilts/api/29.0/private/service_contexts添加如下内容

system/sepolicy/prebuilts/api/29.0/private/service_contexts

3、在文件system/sepolicy/public/service.te添加如下内容

type myservice_service, system_api_service, system_server_service, service_manager_type;

4、在文件system/sepolicy/prebuilts/api/29.0/public/service.te添加如下内容

type myservice_service, system_api_service, system_server_service, service_manager_type;

注意:如下两个文件中的内容必须完全一致,多一行空格都不行

system/sepolicy/public/service.te

 system/sepolicy/prebuilts/api/29.0/public/service.te

其他api和29.0的类似添加即可:

system/sepolicy/prebuilts/api/28.0/public/service.te
system/sepolicy/prebuilts/api/27.0/public/service.te
system/sepolicy/prebuilts/api/26.0/public/service.te


system/sepolicy/prebuilts/api/28.0/private/service_contexts
system/sepolicy/prebuilts/api/27.0/private/service_contexts
system/sepolicy/prebuilts/api/26.0/private/service_contexts

//经测试,只添加system/sepolicy/29.0,上面的没添加编译会报错,最好都添加上

五、编译

六、查看服务是否添加成功

1、根据服务名称去查看定义的服务是否存在

服务名称为上面在Context.txt中定义的服务名称

 public static final String MY_SERVICE ="myservice";

2、还可以通过连接卡,Android Studio中查看服务中的日志

七、app使用添加的服务

编译生成的代码位置:
out\target\common\obj\JAVA_LIBRARIES\framework_intermediates\classes.jar 包含代码的
out\target\common\obj\JAVA_LIBRARIES\framework_intermediates\classes-header.jar 这个就只有方法名, 不提供内容实现代码
如果不想要把整个framework层代码提供出去,还有一种简单的方法, 自己新建个app,打成jar包,包名和framewrok层写的一样,最后打包成一个jar包,compileOnly files(‘libs\classes.jar’) 这样使用

使用示例:
 MyServiceManager myServiceManager=(MyServiceManager)getSystemService("myservice");
    int sumVlaue=myServiceManager.getSum(2,3);

猜你喜欢

转载自blog.csdn.net/banzhuantuqiang/article/details/131062050