La capa de Android10 Framework agrega servicios del sistema

1. Medio ambiente

Qualcomm 865 Android10

2. Pasos específicos para agregar servicios

1. Agregar archivo de ayuda

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

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

2. Agregue aidl a android.bp

marcos/base/Android.bp

java_predeterminados {

    nombre: "marco-valores predeterminados",

    instalable: cierto,

    origen: [

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

        "núcleo/java/**/*.java",

        "gráficos/java/**/*.java",

        "ubicación/java/**/*.java",

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

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

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

      ],

3. Cree un archivo de servicio, que es la implementación específica de aidl

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

La lógica en el servicio puede ser diferente para todos, aquí está la definición del servicio

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. Agregue MyService.java al administrador de servicios del sistema (es decir, inicie el servicio al inicio)

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

startOtherServices()Agregar el servicio en

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. Cree una interfaz que se pueda usar externamente (el servicio obtenido por getSystemService(String serviceName) en la aplicación llamará a la función en MyServiceManager.java a continuación)

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

paquete android.app;

importar android.util.Log;

importar android.os.IMyService;

importar android.content.Context;

importar java.lang.Exception;

importar android.os.RemoteException;

clase pública MyServiceManager{

    ETIQUETA de cadena final estática pública = "MyServiceManager";

    privado IMyService mService;

    público MyServiceManager(servicio IMyService){

        mServicio = servicio;

    }

    público int getSum(int data1,int data2){

        intentar{

            devuelve mService.getSum(datos1,datos2);

        }atrapar(RemoteException e){

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

            e.printStackTrace();

        }

        devolver 0;

    }

}

6. Configure el nombre de la interfaz en Contexto

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. Registre el servicio (getSystemService() en la aplicación llamará para crear el servicio)

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

3. Después de agregar la nueva API, la API debe actualizarse

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

4. Estrategia de configuración de Selinux (si no hay permiso de configuración, la API relevante en el servicio generará un error para llamadas externas)

1. Agregue el siguiente contenido al sistema de archivos/sepolicy/private/service_contexts

miservicio u:objeto_r:miservicio_servicio:s0

2. Agregue el siguiente contenido en el sistema de archivos/sepolicy/prebuilds/api/29.0/private/service_contexts

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

3. Agregue el siguiente contenido al archivo system/sepolicy/public/service.te

type myservice_service, system_api_service, system_server_service, service_manager_type;

4. Agregue el siguiente contenido en el archivo system/sepolicy/prebuilds/api/29.0/public/service.te

escriba myservice_service, system_api_service, system_server_service, service_manager_type;

Nota: El contenido de los siguientes dos archivos debe ser exactamente el mismo, y una línea más de espacio no funcionará

system/sepolicy/public/service.te

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

Adiciones similares para otras API y 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,上面的没添加编译会报错,最好都添加上

Cinco, compila

6. Verifique si el servicio se agregó con éxito

1. Verifique si el servicio definido existe de acuerdo con el nombre del servicio

El nombre del servicio es el nombre del servicio definido anteriormente en Context.txt

 public static final String MY_SERVICE ="myservice";

2. También puede ver los registros en el servicio en Android Studio a través de la tarjeta de conexión

7. La aplicación utiliza el servicio añadido

编译生成的代码位置:
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);

Supongo que te gusta

Origin blog.csdn.net/banzhuantuqiang/article/details/131062050
Recomendado
Clasificación