Android在framework中新增AIDL接口

1、背景

項目中遇到一個需求,要對Mdmservice進行管控。簡化下來大概就是需要監聽一個系統屬性值,當這個屬性值變爲false的時候,禁止調用揚聲器、聽筒。跟蹤代碼發現這個需求裏面的場景,只需要處理MediaRecorder就能達到目標。
2、實現

根據需求,調用揚聲器、聽筒之前讀取一下系統屬性值判斷一下即可,有個場景是正在調用揚聲器、聽筒的過程中屬性值發生變化,着重要處理的就是這個場景。
2.1 定義AIDL接口

接口名稱定爲INotifyPolicyChange.aidl,直接給出代碼:


/*
* server use this interface of client
*/
interface INotifyPolicyChange {
    void notifyPolicyChange();
}

2.2 在IMdmService.aidl中定義註冊、去註冊接口

interface IMdmService {
      //Interactive interface
      void registerCallBack(IBinder token, INotifyPolicyChange callback);
      void unregisterCallBack(INotifyPolicyChange callback);
……
}

2.3 在MdmService中實現註冊、去註冊

給出代碼片段:

private RemoteCallbackList<INotifyPolicyChange> mCallBacks = new RemoteCallbackList<>();

final class ClientDeathCallback implements DeathRecipient {
            public final IBinder mToken;
            public final INotifyPolicyChange mCallback;
            public ClientDeathCallback(IBinder token, INotifyPolicyChange mCallback) {
                this.mToken = token;
                this.mCallback = mCallback;
            }

            @Override
            public void binderDied() {
                Log.d(TAG,"client died! mToken=" + mToken + ";callback=" + mCallback);
                try {
                    unregisterCallBack(mCallback);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }

        public void registerCallBack(IBinder token, INotifyPolicyChange callback) throws RemoteException {
            ClientDeathCallback clientDeathCallback = new ClientDeathCallback(token, callback);
            //register callback
            mCallBacks.register(callback);
            //register recipient
            token.linkToDeath(clientDeathCallback, 0);
        }

        public void unregisterCallBack(INotifyPolicyChange callback) throws RemoteException {
            mCallBacks.unregister(callback);
        }

        /**
        * notify client that policy change
        */

        private void notifyChange() {
            final int len = mCallBacks.beginBroadcast();
            for(int i = 0; i < len; i++) {
                try {
                    mCallBacks.getBroadcastItem(i).notifyPolicyChange();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
            mCallBacks.finishBroadcast();
        }

public boolean setMicrophonePolicy(int policy) throws RemoteException {
            if(isActive) {
                boolean success = MdmDevicePolicyManager.getInstance(mContext)
                        .getPeripheralPolicy().setMicrophonePolicy(policy);
                //notify client policy changed
                if(success) {
                    notifyChange();
                }
                return success;
            }
            return false;
        }

2.4 在MediaRecorder中實現業務邏輯

給出代碼片段:

private IBinder mBinder;
private IMdmService mMdmService;
public MediaRecorder() {
//get mdmservice mBinder and register a callback
        mBinder = ServiceManager.getService("mdm3");
        mMdmService = mBinder == null ? null : IMdmService.Stub.asInterface(mBinder);
        if(mMdmService != null) {
            try {
                mMdmService.registerCallBack(new Binder(), mNotifyCallBack);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        } else {
            Log.e(TAG, "MediaRecorder cannot get mdmservice mBinder!");
        }
}

private INotifyPolicyChange mNotifyCallBack = new INotifyPolicyChange.Stub() {
        @Override
        public void notifyPolicyChange() throws RemoteException {
            //add logic here
        }
    };

mBinder = ServiceManager.getService("mdm3");這句代碼能獲取到MdmService實例是因爲在SystemService已經以“mdm3”對MdmService註冊過了。
2.5 在mk及其他文件裏註冊新增AIDL文件

新增了AIDL之後,需手動註冊,否則編譯時找不到相應文件。

core/java/android/service/mdm3/INotifyPolicyChange.aidl

編譯過後,“api/current.txt”、“api/system-current.txt”、“api/test-current”也新增了相應接口。
這樣,就完成了在framework中新增一個AIDL接口。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章