Android8.1 添加自定義系統服務

-一、Aidl接口文件
代碼路徑:frameworks/base/core/java/android/os/IHookStatus.aidl

package android.os;
interface IHookStatus {
    boolean IsOffhookByHost();
    boolean IsOnhookByHost();
    boolean IsOffhookByFxs();
    boolean IsOnhookByFxs();
    void setstatus(int which, boolean value);
} 

在frameworks/base/Android.mk里加入IHookStatus.aidl

LOCAL_SRC_FILES += \
core/java/android/os/IHookStatus.aidl \

使用過aidl的都知道,編譯後aidl文件會生成一個同名的java文件,這是aidl技術的核心代碼,是binder技術java層的實現。
二、Aidl生成的java文件
代碼路徑:out\target\common\obj\JAVA_LIBRARIES\framework_intermediates\core\java\android\os\IHookStatus.java

/*
 * This file is auto-generated.  DO NOT MODIFY.
 * Original file: frameworks/base/core/java/android/os/IHookStatus.aidl
 */
package android.os;
public interface IHookStatus extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements android.os.IHookStatus
{
private static final java.lang.String DESCRIPTOR = "android.os.IHookStatus";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
 * Cast an IBinder object into an android.os.IHookStatus interface,
 * generating a proxy if needed.
 */
public static android.os.IHookStatus asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof android.os.IHookStatus))) {
return ((android.os.IHookStatus)iin);
}
return new android.os.IHookStatus.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_IsOffhookByHost:
{
data.enforceInterface(DESCRIPTOR);
boolean _result = this.IsOffhookByHost();
reply.writeNoException();
reply.writeInt(((_result)?(1):(0)));
return true;
}
case TRANSACTION_IsOnhookByHost:
{
data.enforceInterface(DESCRIPTOR);
boolean _result = this.IsOnhookByHost();
reply.writeNoException();
reply.writeInt(((_result)?(1):(0)));
return true;
}
case TRANSACTION_IsOffhookByFxs:
{
data.enforceInterface(DESCRIPTOR);
boolean _result = this.IsOffhookByFxs();
reply.writeNoException();
reply.writeInt(((_result)?(1):(0)));
return true;
}
case TRANSACTION_IsOnhookByFxs:
{
data.enforceInterface(DESCRIPTOR);
boolean _result = this.IsOnhookByFxs();
reply.writeNoException();
reply.writeInt(((_result)?(1):(0)));
return true;
}
case TRANSACTION_setstatus:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
boolean _arg1;
_arg1 = (0!=data.readInt());
this.setstatus(_arg0, _arg1);
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements android.os.IHookStatus
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override public boolean IsOffhookByHost() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_IsOffhookByHost, _data, _reply, 0);
_reply.readException();
_result = (0!=_reply.readInt());
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override public boolean IsOnhookByHost() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_IsOnhookByHost, _data, _reply, 0);
_reply.readException();
_result = (0!=_reply.readInt());
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override public boolean IsOffhookByFxs() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_IsOffhookByFxs, _data, _reply, 0);
_reply.readException();
_result = (0!=_reply.readInt());
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override public boolean IsOnhookByFxs() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_IsOnhookByFxs, _data, _reply, 0);
_reply.readException();
_result = (0!=_reply.readInt());
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override public void setstatus(int which, boolean value) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(which);
_data.writeInt(((value)?(1):(0)));
mRemote.transact(Stub.TRANSACTION_setstatus, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
}
static final int TRANSACTION_IsOffhookByHost = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_IsOnhookByHost = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_IsOffhookByFxs = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_IsOnhookByFxs = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
static final int TRANSACTION_setstatus = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
}
public boolean IsOffhookByHost() throws android.os.RemoteException;
public boolean IsOnhookByHost() throws android.os.RemoteException;
public boolean IsOffhookByFxs() throws android.os.RemoteException;
public boolean IsOnhookByFxs() throws android.os.RemoteException;
public void setstatus(int which, boolean value) throws android.os.RemoteException;
}

在這裏插入圖片描述三、HookStatusService服務的定義
代碼路徑:\frameworks\base\services\core\java\com\android\server\os\HookStatusService.java

package com.android.server.os;
import android.os.IHookStatus;
public class HookStatusService extends IHookStatus.Stub {
    private static final String TAG = "HookStatusService";
    
    @Override
    public boolean IsOffhookByHost() {
        return true;
    }
    
    @Override
    public boolean IsOnhookByHost() {
        return true;
    }
    
    @Override
    public boolean IsOffhookByFxs() {
        return true;
    }
    @Override
    public boolean IsOnhookByFxs() {
        return true;
    }
    
    @Override
    public void setstatus(int which, boolean value) {                
    }  
}

HookStatusService實現之前定義的方法,我們需要看到的是HookStatusService繼IHookStatus.Stub。
四、定義HookStatusService的封裝接口HookStatusManager
代碼路徑:frameworks/base/core/java/android/app/HookStatusManager.java

package android.app;
 
import android.content.Context;
import android.util.Log;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.IHookStatus;
 
 
public class HookStatusManager {
    private static final String TAG = "HookStatusManager";
	private IHookStatus mService;
	
	public static final int OFFHOOK_HOST = 0;
	public static final int ONHOOK_HOST = 1;
	public static final int OFFHOOK_FXS = 2;
	public static final int ONHOOK_FXS = 3;
 
    public HookStatusManager(Context ctx, IHookStatus service){
        mService = service;
    }
	
    public boolean IsOffhookByHost() {
        try {
            return mService.IsOffhookByHost();
        }catch(Exception e){
            Log.e(TAG, "exception=" + e);
            e.printStackTrace();
        }
        return false;
    }
	
    public boolean IsOnhookByHost() {
        try {
            return mService.IsOnhookByHost();
        }catch(Exception e){
            Log.e(TAG, "exception=" + e);
            e.printStackTrace();
        }
        return false;
    }
	
    public boolean IsOffhookByFxs() {
        try {
            return mService.IsOffhookByFxs();
        } catch(Exception e){
            Log.e(TAG, "exception=" + e);
            e.printStackTrace();
        }
		
        return false;
    }
	
    public boolean IsOnhookByFxs() {
        try {
            return mService.IsOnhookByFxs();
        } catch(Exception e){
            Log.e(TAG, "exception=" + e);
            e.printStackTrace();
        }
        return false;
    }
	
    public void setstatus(int which, boolean value) {
        try {
            mService.setstatus(which, value);
        }catch(Exception e){
            Log.e(TAG, "exception=" + e);
            e.printStackTrace();
        }
    }
}

封裝了之前在服務端實現的方法,注意到方法的調用者是IHookStatus,實際上在後續註冊服務的時候,我們可以看到並把它理解爲服務的本地代理prox。
五、自定義服務添加到SystemService
1、代碼路徑:/frameworks/base/services/java/com/android/server/SystemServer.java

導入頭文件
import com.android.server.os.HookStatusService;
在startOtherServices()方法中註冊
 private void startOtherServices() {
 traceBeginAndSlog("Start hookstatus service");
			ServiceManager.addService(Context.HOOKSTATUS_SERVICE, new HookStatusService());
			traceEnd();
 }

systemserver是啓動各個系統服務的地方,系統服務會add到servicemanager,由其管理。
2、代碼路徑:frameworks/base/core/java/android/app/SystemServiceRegistry.java 在靜態代碼塊中增加如下代碼

import android.os.IHookStatus;
static {
registerService(Context.HOOKSTATUS_SERVICE, HookStatusManager.class,
                new CachedServiceFetcher<HookStatusManager>() {
                    @Override
                    public HookStatusManager createService(ContextImpl ctx) throws ServiceNotFoundException {
                        IBinder b = ServiceManager.getServiceOrThrow(Context.HOOKSTATUS_SERVICE);
                        return new HookStatusManager(ctx, IHookStatus.Stub.asInterface(b));
                    }
                });
  }

定義了getsystemservice獲得manager的位置
六、服務名字的定義
代碼路徑:frameworks/base/core/java/android/content/Context.java

public static final String HOOKSTATUS_SERVICE = "hookstatus";

七、自定義服務sepolicy權限策略配置
1、代碼路徑:system/sepolicy/prebuilts/api/26.0/private/service_contexts 以及 system/sepolicy/private/service_contexts兩個配置文件分別添加

hookstatus    u:object_r:hookstatus_service:s0

2、system/sepolicy/prebuilts/api/26.0/public/service.te 以及 system/sepolicy/public/service.te兩個配置文件分別添加

type hookstatus_service, system_api_service, system_server_service, service_manager_type;

需要添加的代碼到這裏就結束了,編譯前需要先 make update-api,然後正常編譯即可.
八、代碼驗證

import android.app.HookStatusManager;
private HookStatusManager mHookStatusManager ;
mHookStatusManager = (HookStatusManager)this.getSystemService("hookstatus");
 Log.e(TAG, "mHookStatusManager !"+mHookStatusManager .IsOffhookByFxs());

打印結果

04-29 09:03:16.711 19377 19377 E MyService: mHookStatusManager    !true
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章