Camera的Binder實(shí)現(xiàn)

api 調(diào)用

  • 獲取CameraManager對(duì)象
CameraManager mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
  • openCamera
mCameraManager.openCamera(cameraId, callback, handler);

調(diào)用的是 CameraManager 中的 openCameraDeviceUserAsync 方法

    private CameraDevice openCameraDeviceUserAsync(String cameraId,
            CameraDevice.StateCallback callback, Executor executor, final int uid)
            throws CameraAccessException {
... ...
                    // Use cameraservice's cameradeviceclient implementation for HAL3.2+ devices
                    ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
                    if (cameraService == null) {
                        throw new ServiceSpecificException(
                            ICameraService.ERROR_DISCONNECTED,
                            "Camera service is currently unavailable");
                    }
                    cameraUser = cameraService.connectDevice(callbacks, cameraId,
                            mContext.getOpPackageName(), uid);
... ...

        return device;
    }

ICameraService 是 aidl,來(lái)看一下它的對(duì)象實(shí)例化過(guò)程,它的實(shí)例化時(shí)在 CameraManager 的內(nèi)部類(lèi) CameraManagerGlobal 的 connectCameraServiceLocked 方法中

        private void connectCameraServiceLocked() {
            // Only reconnect if necessary
            if (mCameraService != null || sCameraServiceDisabled) return;

            Log.i(TAG, "Connecting to camera service");

            IBinder cameraServiceBinder = ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME);
            if (cameraServiceBinder == null) {
                // Camera service is now down, leave mCameraService as null
                return;
            }
            try {
                cameraServiceBinder.linkToDeath(this, /*flags*/ 0);
            } catch (RemoteException e) {
                // Camera service is now down, leave mCameraService as null
                return;
            }

            ICameraService cameraService = ICameraService.Stub.asInterface(cameraServiceBinder);
... ...
        }

ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME) 也是通過(guò) aidl 獲取 CameraService 在 Native 中注冊(cè)的 binder 對(duì)象蜒简,然后我們通過(guò)這個(gè) binder 對(duì)象實(shí)例化 ICameraService 對(duì)象迎变,我們看一下 ICameraService.aidl 通過(guò)編譯生成的 ICameraService.java 中 asInterface 方法的實(shí)現(xiàn)(文件路徑: /android/out/soong/.intermediates/frameworks/base/framework/android_common/gen/aidl/frameworks/av/camera/aidl/android/hardware/ICameraService.java)

public static android.hardware.ICameraService asInterface(android.os.IBinder obj) {
    if ((obj == null)) {
        return null;
    }
    android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
    if (((iin != null) && (iin instanceof android.hardware.ICameraService))) {
        return ((android.hardware.ICameraService) iin);
    }
    return new android.hardware.ICameraService.Stub.Proxy(obj);
}

首先會(huì)通過(guò)queryLocalInterface根據(jù)標(biāo)識(shí)DESCRIPTOR在本地搜索接口向楼,搜索到的是 ICameraService 內(nèi)部類(lèi) Stub 構(gòu)造函數(shù)內(nèi)調(diào)用 attachInterface 與 binder 綁定的接口

public Stub() {
    this.attachInterface(this, DESCRIPTOR);
}

如果沒(méi)有實(shí)例化 Stub 對(duì)象的話則會(huì)返回代理類(lèi)的對(duì)象(ICameraService 就沒(méi)有 Stub 對(duì)象)兰吟,代理類(lèi)也是 Aidl 自動(dòng)生成的觅廓;所以調(diào)用的 connectDevice 方法其實(shí)是 Proxy 類(lèi)的

@Override
public android.hardware.camera2.ICameraDeviceUser connectDevice(android.hardware.camera2.ICameraDeviceCallbacks callbacks, java.lang.String cameraId, java.lang.String opPackageName, int clientUid) throws android.os.RemoteException {
    android.os.Parcel _data = android.os.Parcel.obtain();
    android.os.Parcel _reply = android.os.Parcel.obtain();
    android.hardware.camera2.ICameraDeviceUser _result;
    try {
        _data.writeInterfaceToken(DESCRIPTOR);
        _data.writeStrongBinder((((callbacks != null)) ? (callbacks.asBinder()) : (null)));
        _data.writeString(cameraId);
        _data.writeString(opPackageName);
        _data.writeInt(clientUid);
        mRemote.transact(Stub.TRANSACTION_connectDevice, _data, _reply, 0);
        _reply.readException();
        _result = android.hardware.camera2.ICameraDeviceUser.Stub.asInterface(_reply.readStrongBinder());
    } finally {
        _reply.recycle();
        _data.recycle();
    }
    return _result;
}

調(diào)用 transact 方法發(fā)起 RPC (遠(yuǎn)程過(guò)程調(diào)用)請(qǐng)求,同時(shí)當(dāng)前線程掛起服鹅,然后服務(wù)端的 onTransact 方法會(huì)被調(diào)用凳兵,直到 RPC 過(guò)程返回,當(dāng)前線程繼續(xù)執(zhí)行企软,從 _reply 中取出 RPC 過(guò)程中返回的結(jié)果

public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
            java.lang.String descriptor = DESCRIPTOR;
            switch (code) {
... ...
                case TRANSACTION_connectDevice: {
                    data.enforceInterface(descriptor);
                    android.hardware.camera2.ICameraDeviceCallbacks _arg0;
                    _arg0 = android.hardware.camera2.ICameraDeviceCallbacks.Stub.asInterface(data.readStrongBinder());
                    java.lang.String _arg1;
                    _arg1 = data.readString();
                    java.lang.String _arg2;
                    _arg2 = data.readString();
                    int _arg3;
                    _arg3 = data.readInt();
                    android.hardware.camera2.ICameraDeviceUser _result = this.connectDevice(_arg0, _arg1, _arg2, _arg3);
                    reply.writeNoException();
                    reply.writeStrongBinder((((_result != null)) ? (_result.asBinder()) : (null)));
                    return true;
                }
... ...
            }
        }

對(duì)應(yīng) ICameraService.java庐扫, aidl 同時(shí)也在 Native 生成了 ICameraService.cpp,內(nèi)有 BpCameraService (Native Proxy)仗哨,及 BnCameraService 的實(shí)現(xiàn)形庭;最終是在 BnCameraService 的 onTransact 方法內(nèi)調(diào)用其子類(lèi) CameraService 的 connectDevice 方法實(shí)現(xiàn) openCamera 的操作的

Status CameraService::connectDevice(
        const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
        const String16& cameraId,
        const String16& clientPackageName,
        int clientUid,
        /*out*/
        sp<hardware::camera2::ICameraDeviceUser>* device) {

    ATRACE_CALL();
    Status ret = Status::ok();
    String8 id = String8(cameraId);
    sp<CameraDeviceClient> client = nullptr;
    ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
            /*api1CameraId*/-1,
            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,
            clientUid, USE_CALLING_PID, API_2,
            /*legacyMode*/ false, /*shimUpdateOnly*/ false,
            /*out*/client);

    if(!ret.isOk()) {
        logRejected(id, getCallingPid(), String8(clientPackageName),
                ret.toString8());
        return ret;
    }

    *device = client;
    return ret;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市厌漂,隨后出現(xiàn)的幾起案子萨醒,更是在濱河造成了極大的恐慌,老刑警劉巖苇倡,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件富纸,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡旨椒,警方通過(guò)查閱死者的電腦和手機(jī)晓褪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)综慎,“玉大人涣仿,你說(shuō)我怎么就攤上這事∈揪” “怎么了好港?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)涝涤。 經(jīng)常有香客問(wèn)我媚狰,道長(zhǎng),這世上最難降的妖魔是什么阔拳? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任崭孤,我火速辦了婚禮,結(jié)果婚禮上糊肠,老公的妹妹穿的比我還像新娘辨宠。我一直安慰自己,他們只是感情好货裹,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布嗤形。 她就那樣靜靜地躺著,像睡著了一般弧圆。 火紅的嫁衣襯著肌膚如雪赋兵。 梳的紋絲不亂的頭發(fā)上笔咽,一...
    開(kāi)封第一講書(shū)人閱讀 49,185評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音霹期,去河邊找鬼叶组。 笑死,一個(gè)胖子當(dāng)著我的面吹牛历造,可吹牛的內(nèi)容都是我干的甩十。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼吭产,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼侣监!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起臣淤,我...
    開(kāi)封第一講書(shū)人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤橄霉,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后荒典,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體酪劫,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡吞鸭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年寺董,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片刻剥。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡遮咖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出造虏,到底是詐尸還是另有隱情御吞,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布漓藕,位于F島的核電站陶珠,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏享钞。R本人自食惡果不足惜揍诽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望栗竖。 院中可真熱鬧暑脆,春花似錦、人聲如沸狐肢。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)份名。三九已至碟联,卻和暖如春妓美,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鲤孵。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工部脚, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人裤纹。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓委刘,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親鹰椒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子锡移,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344