android7.0如何自定义添加系统服务

由于项目需要,我这边需要在framework层增加一个语音唤醒服务来实现拉通hal层以及android应用层,实现语音黑屏唤醒以及亮屏唤醒的功能,这里我们只看在android7.0和9.0上是怎么增加一个自定义系统服务,其实对着葫芦画瓢就可以了。

下面主要说基于android7.0的添加系统服务,9.0的编译方式改了,改下bp文件就可以了,没什么大的区别,这里删了些复杂的接口,只留了几个比较简单的接口,方便阅读。

1.编写与声明aidl文件

1.1.编写aidl文件

在frameworks/base/core/java/android/新增ovum/ai/IAIManager.aidl文件

package android.ovum.ai;
/**
* {@hide}
*/
interface IAIManager {
    byte[] getAudioData();
    int getWakeupDoa();
    void stopAudioData();
    void wakeupAppStarted(String callerPackage);
    boolean setEnabled(boolean enabled, String callerPackage);
    boolean isEnabled(String callerPackage);
    boolean isRecording(String callerPackage);
}

1.2.注册aidl文件

实现完成后需要在frameworks/base/Android.mk 声明我们需要的aidl文件,这个经常忘记了。

core/java/android/ovum/ai/IAIManager.aidl \
core/java/android/ovum/performanceobserver/IPerformanceObserverService.aidl \

1.3.封装aidl的接口实现

实现AIManager的接口封装

package android.ovum.ai;

import android.content.Context;
import android.os.RemoteException;
import android.util.Log;

/**
 * {@hide}
 */
public class AIManager {
    private static final String TAG = "AIManager";

    private final Context mContext;
    private final IAIManager mService;

    public AIManager(Context context, IAIManager service) {
        Log.v(TAG, "AIManager()");
        mContext = context;
        mService = service;
    }

    public void stopAudioData() {
        try {
            mService.stopAudioData();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    public int getWakeupDoa() {
        try {
            return mService.getWakeupDoa();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return 0;
    }

    public byte[] getAudioData() {
        try {
            return mService.getAudioData();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return null;
    }

    public void wakeupAppStarted() {
        try {
            mService.wakeupAppStarted(mContext.getOpPackageName());
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
    public boolean setEnabled(boolean enabled) {
        try {
            return mService.setEnabled(enabled, mContext.getOpPackageName());
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return false;
    }

    public boolean isEnabled() {
        try {
            return mService.isEnabled(mContext.getOpPackageName());
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return false;
    }

    public boolean isRecording() {
        try {
            return mService.isRecording(mContext.getOpPackageName());
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return false;
    }


}

2.实现AIManagerService

package com.android.server.ovum;
import android.content.Context;
import android.media.AudioFormat;
import android.os.RemoteException;
import android.ovum.ai.IAIManager;
import android.util.Slog;
import android.media.MediaRecorder;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.PowerManager;
import android.media.AudioManager;
import android.media.AudioSystem;
import android.app.ActivityManagerInternal;
import com.android.server.LocalServices;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import java.util.concurrent.ArrayBlockingQueue;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.File;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Parcelable;
import android.content.BroadcastReceiver;
import android.provider.Settings;

public class AIManagerService extends IAIManager.Stub {
    private static final String TAG = "AIManagerService";
    private Context mContext;
    private static boolean LOG_DEBUG = true;
    private boolean mIsEnabled = true;

    public AIManagerService(final Context context) {
        Slog.d(TAG, "AIManagerService()");
        mContext = context;
    }

    public void handleOnBootPhase() {
        Slog.d(TAG, "handleOnBootPhase");
    }

    @Override
    public void stopAudioData() throws RemoteException {
        Slog.d(TAG, "stopAudioData!\n");

    }

    @Override
    public int getWakeupDoa() throws RemoteException {
        return 0;
    }

    @Override
    public byte[] getAudioData() throws RemoteException {
        return null;
    }


    @Override
    public void wakeupAppStarted(String callerPackage) throws RemoteException {
        Slog.d(TAG, "wakeupAppStarted caller=" + callerPackage);
        return;
    }

    @Override
    public boolean setEnabled(boolean enabled, String callerPackage) throws RemoteException {
        Slog.d(TAG, "setEnabled=" + enabled + ",caller=" + callerPackage);
        return false;

    }

    @Override
    public boolean isEnabled(String callerPackage) throws RemoteException {
        Slog.d(TAG, "isEnabled=" + mIsEnabled + ",caller=" + callerPackage);
        return mIsEnabled;
    }

    @Override
    public boolean isRecording(String callerPackage) throws RemoteException {
        return false;
    }

    @Override
    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
          if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
                != PERMISSION_GRANTED) {
            pw.println("Permission Denial: can't dump ovum_ai from from pid="
                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
                    + " without permission " + android.Manifest.permission.DUMP);
            return;
        }
        pw.println("AIManagerService");
    }
}

这里我们为了方便统一管理我们增加的自定义系统服务
在frameworks/base/services/core/java/com/android/server/目录下新增ovum/OvumOvulationService.java ,实现OvumOvulationService 并继承SystemService

package com.android.server.ovum;

import android.content.Context;
import android.util.Slog;

import com.android.server.am.ActivityManagerService;

import com.android.server.SystemService;

public class OvumOvulationService extends SystemService {
    private final static String TAG = "OvumOvulationService";
    private Context mContext;
    private AIManagerService mAiManagerService;

    public OvumOvulationService(Context context) {
        super(context);
        mContext = context;
        mAiManagerService = new AIManagerService(context);
    }

    @Override
    public void onStart() {
        Slog.d(TAG, "onStart ------");
    }

    @Override
    public void onBootPhase(int phase) {
        Slog.d(TAG, "onBootPhase ------ " + phase);
        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
        } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
            publishBinderService(Context.OVUM_AI_SERVICE, mAiManagerService);
            mAiManagerService.handleOnBootPhase();

        }
    }
}

修改frameworks/base/services/java/com/android/server/SystemServer.java 实现启动我们的服务

import com.android.server.ovum.OvumOvulationService;


private OvumOvulationService mOvumOvulationService;

...
 mSystemServiceManager.startService(OvumOvulationService.class);

同时修改frameworks/base/core/java/android/content/Context.java 新增 OVUM_AI_SERVICE,方便dump信息查看

/**
  * @hide
  */ 

public static final String OVUM_AI_SERVICE = "ovum_ai";

修改system/sepolicy/service_contexts文件,修改权限

ovum_ai                                   u:object_r:ovum_service:s0

这样整个系统服务就声明和实现完成了。编译替换后,重启系统我们就可以看到system log了

01-11 01:53:29.183742   708   708 D AIManagerService: AIManagerService()
01-11 01:53:29.184836   708   708 D OvumOvulationService: onStart ------
01-01 00:00:01.628209   708   748 D OvumOvulationService: onBootPhase ------ 1000
01-01 00:00:01.628901   708   748 D AIManagerService: handleOnBootPhase

说明我们的服务正常起来了

2.使用自定义系统服务

这里我们不做注册监听系统服务这些操作,直接通过反射并封装一个jar包提供给应用使用,这里直接使用反射的方式。

public class AIManager {
    private static final String TAG = "AIManager.jar";

    private static final boolean DEBUG = true;

    private static AIManager sAIManager;

    private static Object mSysAIManagerObject;
    private static Class mSysAIManagerClass;

    private static Method mMethodSwitchToWakeupMode;
    private static Method mMethodSwitchToRecordMode;
    private static Method mMethodWakeupAppStarted;
    private static Method mMethodOneshotRecordStarted0;
    private static Method mMethodOneshotRecordStarted;
    private static Method mMethodSetEnabled;
    private static Method mMethodIsEnabled;
    private static Method mMethodIsRecording;
    private static Method mMethodCallback;
    private static Method mMethodUnCallback;
    private static Method mMethodgetAudioData;
    private static Method mMethodgetWakeupDoa;
    private static Method mMethodstopAudiodata;
    private static Method mMethodauthDuiTest;

    public AIManager(Context context) {
        if (DEBUG) {
            Log.d(TAG, "new AIManager from package " + context.getPackageName());
        }
    }

    public static AIManager getInstance(Context context) {
        if (sAIManager == null) {
            sAIManager = new AIManager(context);


            mSysAIManagerObject = context.getApplicationContext().getSystemService("ovum_ai");
            if (DEBUG) {
                Log.d(TAG, "mSysAIManagerObject=" + mSysAIManagerObject);
            }

            if (mSysAIManagerObject != null) {
                mSysAIManagerClass = mSysAIManagerObject.getClass();
            }

            try {
                mMethodSetEnabled = mSysAIManagerClass.getMethod("setEnabled", boolean.class);
                mMethodSetEnabled.setAccessible(true);
            } catch (NoSuchMethodException e) {
                Log.e(TAG, e.getMessage());
            }

            try {
                mMethodIsEnabled = mSysAIManagerClass.getMethod("isEnabled");
                mMethodIsEnabled.setAccessible(true);
            } catch (NoSuchMethodException e) {
                Log.e(TAG, e.getMessage());
            }

            try {
                mMethodIsRecording = mSysAIManagerClass.getMethod("isRecording");
                mMethodIsRecording.setAccessible(true);
            } catch (NoSuchMethodException e) {
                Log.e(TAG, e.getMessage());
            }
            try {
                mMethodgetAudioData = mSysAIManagerClass.getMethod("getAudioData");
                mMethodgetAudioData.setAccessible(true);
            } catch (NoSuchMethodException e) {
                Log.e(TAG, e.getMessage());
            }
            try {
                mMethodgetWakeupDoa = mSysAIManagerClass.getMethod("getWakeupDoa");
                mMethodgetWakeupDoa.setAccessible(true);
            } catch (NoSuchMethodException e) {
                Log.e(TAG, e.getMessage());
            }
            try {
                mMethodstopAudiodata = mSysAIManagerClass.getMethod("stopAudioData");
                mMethodstopAudiodata.setAccessible(true);
            } catch (NoSuchMethodException e) {
                Log.e(TAG, e.getMessage());
            }
        }

        return sAIManager;
    }
    public void stopAudiodata() {
        if (sAIManager == null || mMethodstopAudiodata == null || mSysAIManagerObject == null)
            return;

        try {
            mMethodstopAudiodata.invoke(mSysAIManagerObject);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }

    public byte[] getAudioData() {
        if (sAIManager == null || mMethodgetAudioData == null || mSysAIManagerObject == null)
            return null;
        try {

            return (byte[]) mMethodgetAudioData.invoke(mSysAIManagerObject);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }

    public int getWakeupDoa() {
        if (sAIManager == null) return -1;

        try {
            return (int) mMethodgetWakeupDoa.invoke(mSysAIManagerObject);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return -1;
    }
    public void wakeupAppStarted() {
        if (sAIManager == null) return;

        try {
            mMethodWakeupAppStarted.invoke(mSysAIManagerObject);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    public boolean setEnabled(boolean enabled) {
        if (sAIManager == null) return false;

        try {
            return (boolean) mMethodSetEnabled.invoke(mSysAIManagerObject, enabled);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        return false;
    }

    public boolean isEnabled() {
        if (sAIManager == null) return false;

        try {
            return (boolean) mMethodIsEnabled.invoke(mSysAIManagerObject);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        return false;
    }

    public boolean isRecording() {
        if (sAIManager == null) return false;

        try {
            return (boolean) mMethodIsRecording.invoke(mSysAIManagerObject);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        return false;
    }

}

应用只需要集成jar包,然后如下这样调用就可以了

AIManager.getInstance(MainActivity.this).setEnabled(true);

你可能感兴趣的:(android7.0如何自定义添加系统服务)