本篇所講主要是Camera的啟動(dòng)過(guò)程,我們從onCreate方法到Camera成功open完成作如下時(shí)序圖:

上圖主要包括三個(gè)部分:從java到j(luò)ni、從jni/framework到hal、從hal到驅(qū)動(dòng)(不包括驅(qū)動(dòng))。
在第一部分中的應(yīng)用層中我們可以直接得到一個(gè)java里的Camera對(duì)象,這時(shí)對(duì)此對(duì)象進(jìn)行進(jìn)一步封裝,得到一個(gè)AndroidCamera對(duì)象:
public static ICamera openCamera(int cameraId) {
Camera camera = null;
if (sTrySwitchToLegacyMode > 0) {
// choose legacy mode in order to enter cam hal 1.0
camera = Camera.openLegacy(cameraId, Camera.CAMERA_HAL_API_VERSION_1_0);
} else {
camera = Camera.open(cameraId);
}
if (null == camera) {
Log.e(TAG, "openCamera:got null hardware camera!");
return null;
}
// wrap it with ICamera
return new AndroidCamera(camera);
}
ICamera接口內(nèi)定義了一系列針對(duì)Camera進(jìn)行操作的方法,而AndroidCamera則實(shí)現(xiàn)了這些方法:
public interface ICamera {
Camera getInstance();
void addCallbackBuffer(byte[] callbackBuffer);
void addRawImageCallbackBuffer(byte[] callbackBuffer);
void autoFocus(AutoFocusCallback cb);
void cancelAutoFocus();
void cancelContinuousShot();
void stopSmileDetection();
void lock();
Parameters getParameters();
void release();
void reconnect() throws IOException;
void setAsdCallback(AsdCallback cb);
void setAutoFocusMoveCallback(AutoFocusMoveCallback cb);
void setUncompressedImageCallback(PictureCallback cb);
void setAutoRamaCallback(AutoRamaCallback cb);
void setAutoRamaMoveCallback(AutoRamaMoveCallback cb);
void setJpsCallback(StereoCameraJpsCallback cb);
void setWarningCallback(StereoCameraWarningCallback cb);
void setMaskCallback(StereoCameraMaskCallback cb);
void setDistanceInfoCallback(DistanceInfoCallback cb);
void setContext(Context context);
void setContinuousShotCallback(ContinuousShotCallback callback);
void setContinuousShotSpeed(int speed);
void setDisplayOrientation(int degrees);
void setErrorCallback(ErrorCallback cb);
void setFaceDetectionListener(FaceDetectionListener listener);
void setFbOriginalCallback(FbOriginalCallback cb);
void setHdrOriginalCallback(HdrOriginalCallback cb);
void setParameters(Parameters params);
void setPreviewCallbackWithBuffer(PreviewCallback cb);
void setPreviewDoneCallback(ZSDPreviewDone callback);
void setPreviewTexture(SurfaceTexture surfaceTexture) throws IOException;
void setPreviewDisplay(SurfaceHolder holder) throws IOException;
void setSmileCallback(SmileCallback cb);
void setZoomChangeListener(OnZoomChangeListener listener);
// void slowdownContinuousShot();
void startAutoRama(int num);
void start3DSHOT(int num);
void stop3DSHOT(int num);
void setPreview3DModeForCamera(boolean enable);
void startFaceDetection();
void startObjectTracking(int x, int y);
void stopObjectTracking();
void setObjectTrackingListener(ObjectTrackingListener listener);
void startPreview();
void startSmoothZoom(int value);
void startSmileDetection();
void stopAutoRama(int isMerge);
void stopFaceDetection();
void stopPreview();
void setGestureCallback(GestureCallback cb);
void startGestureDetection();
void stopGestureDetection();
void takePicture(ShutterCallback shutter, PictureCallback raw, PictureCallback jpeg);
void takePicture(ShutterCallback shutter, PictureCallback raw, PictureCallback postview,
PictureCallback jpeg);
void unlock();
public void setOneShotPreviewCallback(PreviewCallback cb);
public void setMainFaceCoordinate(int x, int y);
public void cancelMainFaceInfo();
}
public class AndroidCamera implements ICamera {...}
另外還有兩個(gè)內(nèi)部類簡(jiǎn)單看一下關(guān)系

CameraHolder的內(nèi)部類持有CameraManager內(nèi)部類CameraProxy的對(duì)象,于是可以使用CamerHolder間接調(diào)用CameraProxy這個(gè)內(nèi)部類的方法。同時(shí)CamerManager還有另一個(gè)內(nèi)部類CameraHandler可以獲取CameraProxy發(fā)出的消息。
private class CameraHandler extends Handler {
CameraHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(final Message msg) {
long now = SystemClock.uptimeMillis();
if (mCamera == null) {
Log.e(mSubTag, "[handleMessage] camera device is null,return! ");
return;
}
Log.i(mSubTag, "[handleMessage]msg.what = " + getMsgLabel(msg.what)
+ " pending time = " + (now - msg.getWhen()) + "ms.");
try {
switch (msg.what) {
case RELEASE:
CameraPerformanceTracker.onEvent(TAG,
CameraPerformanceTracker.NAME_CAMERA_RELEASE,
CameraPerformanceTracker.ISBEGIN);
mCamera.release();
Log.i(mSubTag, "release camera device = " + mCamera);
CameraPerformanceTracker.onEvent(TAG,
CameraPerformanceTracker.NAME_CAMERA_RELEASE,
CameraPerformanceTracker.ISEND);
mCamera = null;
mCameraProxy = null;
mFaceDetectionRunning = false;
return;
case RECONNECT:
mReconnectException = null;
try {
mCamera.reconnect();
Log.i(mSubTag, "reconnect camera device = " + mCamera);
} catch (IOException ex) {
mReconnectException = ex;
}
mFaceDetectionRunning = false;
return;
case UNLOCK:
mCamera.unlock();
return;
case LOCK:
mCamera.lock();
return;
...
}
}
}
這個(gè)mCamera是一個(gè)ICamera對(duì)象,因此最終將調(diào)用AndroidCamera的相應(yīng)方法。
在第二部分中,我們看到本地的APP使用jni與CameraService進(jìn)行connect,然后會(huì)給APP創(chuàng)建一個(gè)客戶端,這也就是我們常說(shuō)的Camera采用的CS架構(gòu)的原因了:
status_t CameraService::makeClient(const sp<CameraService>& cameraService,
const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
/*out*/sp<BasicClient>* client) {
...
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
*client = new CameraClient(cameraService, tmp, packageName, id, facing,
clientPid, clientUid, getpid(), legacyMode);
...
}
那么代碼怎樣進(jìn)入到Hal層的呢?我們知道,開(kāi)機(jī)后系統(tǒng)會(huì)啟動(dòng)一個(gè)CameraService,然后會(huì)執(zhí)行到onFirstRef()方法,如下:
void CameraService::onFirstRef()
{
ALOGI("CameraService process starting");
BnCameraService::onFirstRef();
// Update battery life tracking if service is restarting
BatteryNotifier& notifier(BatteryNotifier::getInstance());
notifier.noteResetCamera();
notifier.noteResetFlashlight();
camera_module_t *rawModule;
int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
(const hw_module_t **)&rawModule);
if (err < 0) {
ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
logServiceError("Could not load camera HAL module", err);
mNumberOfCameras = 0;
return;
}
mModule = new CameraModule(rawModule);
ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
err = mModule->init();
if (err != OK) {
ALOGE("Could not initialize camera HAL module: %d (%s)", err,
strerror(-err));
logServiceError("Could not initialize camera HAL module", err);
mNumberOfCameras = 0;
delete mModule;
mModule = nullptr;
return;
...
}
...
}
hw_get_module根據(jù)CAMERA_HARDWARE_MODULE_ID加載相應(yīng)的so文件,具體加載過(guò)程可查看hardware.c,這個(gè)module是什么樣子的呢?如下
static
camera_module
get_camera_module()
{
camera_module module = {
common:{
tag : HARDWARE_MODULE_TAG,
#if (PLATFORM_SDK_VERSION >= 21)
module_api_version : CAMERA_MODULE_API_VERSION_2_4,
#else
module_api_version : CAMERA_DEVICE_API_VERSION_1_0,
#endif
hal_api_version : HARDWARE_HAL_API_VERSION,
id : CAMERA_HARDWARE_MODULE_ID,
name : "MediaTek Camera Module",
author : "MediaTek",
methods : get_module_methods(),
dso : NULL,
reserved : {0},
},
get_number_of_cameras : get_number_of_cameras,
get_camera_info : get_camera_info,
set_callbacks : set_callbacks,
get_vendor_tag_ops : get_vendor_tag_ops,
#if (PLATFORM_SDK_VERSION >= 21)
open_legacy : open_legacy,
#endif
set_torch_mode : set_torch_mode,
init : NULL,
reserved : {0},
};
return module;
};
而此module的open方法實(shí)際即為open_device方法:
static
hw_module_methods_t*
get_module_methods()
{
static
hw_module_methods_t
_methods =
{
open: open_device
};
return &_methods;
}
做了這么多僅僅只是打開(kāi)的相機(jī)嗎?我們回到j(luò)ni一開(kāi)始的入口方法setup:
static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName)
{
// Convert jstring to String16
const char16_t *rawClientName = reinterpret_cast<const char16_t*>(
env->GetStringChars(clientPackageName, NULL));
jsize rawClientNameLen = env->GetStringLength(clientPackageName);
String16 clientName(rawClientName, rawClientNameLen);
env->ReleaseStringChars(clientPackageName,
reinterpret_cast<const jchar*>(rawClientName));
sp<Camera> camera;
if (halVersion == CAMERA_HAL_API_VERSION_NORMAL_CONNECT) {
// Default path: hal version is don't care, do normal camera connect.
camera = Camera::connect(cameraId, clientName,
Camera::USE_CALLING_UID);
} else {
jint status = Camera::connectLegacy(cameraId, halVersion, clientName,
Camera::USE_CALLING_UID, camera);
if (status != NO_ERROR) {
return status;
}
}
...
}
可以看到,我們得到一個(gè)sp<Camera>對(duì)象,并且建立了客戶端到服務(wù)端的連接。
我們打開(kāi)相機(jī)后還可能需要對(duì)相機(jī)進(jìn)行各種參數(shù)設(shè)置,也就是說(shuō)需要一個(gè)Parameters對(duì)象:
private int firstOpenCamera(){
...
mParameters = (mCameraDevice == null) ? null : CameraHolder.instance()
.getOriginalParameters(mCameraId);
if (mCameraDevice != null && mParameters != null) {
mCurCameraDevice = new CameraDeviceExt(mCameraActivity, mCameraDevice, mParameters,
mCameraId, mPreferences);
} else {
Log.d(TAG, "[openCamera fail],mCameraDevice:" + mCameraDevice + ",mParameters:"
+ mParameters);
}
...
}
這個(gè)Parameters對(duì)象的獲取我們就不再?gòu)牡讓觼?lái)分析了,簡(jiǎn)單來(lái)說(shuō)只要Camera open成功了,這個(gè)參數(shù)就可以正常獲得,當(dāng)然一些基本的相機(jī)配置也可以從Hal層進(jìn)行初始化定義,我們從Log看下使用Client端設(shè)置后得到的結(jié)果:
01-01 06:14:08.574 D/CameraClient( 353): setParameters (pid 14933) (3dnr-mode=off;3dnr-mode-values=off;afeng-max-focus-step=1023;afeng-min-focus-step=0;antibanding=auto;antibanding-values=off,50hz,60hz,auto;auto-exposure-lock-supported=true;auto-whitebalance-lock-supported=true;brightness=middle;brightness-values=low,middle,high;brightness_value=0;cap-mode-values=normal,face_beauty;capfname=/sdcard/DCIM/cap00;contrast=middle;contrast-values=low,middle,high;cshot-indicator=true;cshot-indicator-supported=true;disp-rot-supported=true;disp-rot-supported-values=true;dynamic-frame-rate=true;dynamic-frame-rate-supported=true;edge=middle;edge-values=low,middle,high;effect=none;effect-values=none,mono,negative,sepia,aqua,whiteboard,blackboard,posterize,nashville,hefe,valencia,xproll,lofi,sierra,walden;eng-mfll-e=false;eng-mfll-s=true;eng-s-shad-t=0;eng-shad-t=0;exposure-compensation=0;exposure-compensation-step=1.0;fb-enlarge-eye-max=4;fb-enlarge-eye-min=-4;fb-extreme-beauty-supported=false;fb-face-pos=-2000:-2000;fb-sharp=0;fb-sharp-max=12;fb-sharp-max-val
我們看到相機(jī)可以設(shè)置的參數(shù)非常多,本篇暫不對(duì)各個(gè)參數(shù)做詳細(xì)解釋。open成功之后又做了如下操作:
...
mCameraAppUi = new CameraAppUiImpl(this);
mCameraAppUi.createCommonView();
initializeCommonManagers();
mCameraAppUi.initializeCommonView();
...
// Here should be lightweight functions!!!
private void initializeCommonManagers() {
mModePicker = new ModePicker(this);
mFileSaver = new FileSaver(this);
mFrameManager = new FrameManager(this);
mModePicker.setListener(mModeChangedListener);
mCameraAppUi.setSettingListener(mSettingListener);
mCameraAppUi.setPickerListener(mPickerListener);
mCameraAppUi.addFileSaver(mFileSaver);
mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
Log.v(TAG, "getSystemService,mPowerManager =" + mPowerManager);
// For tablet
if (FeatureSwitcher.isSubSettingEnabled()) {
mCameraAppUi.setSubSettingListener(mSettingListener);
}
}
CameraAppUiImpl也就是對(duì)整個(gè)Camera UI的實(shí)現(xiàn),前面講過(guò)整個(gè)UI由多個(gè)ManagerView做了具體的實(shí)現(xiàn),也就是這個(gè)createCommonView方法,而后執(zhí)行initializeCommonView方法的就可以將分散的UI加入一個(gè)整體進(jìn)行統(tǒng)一管理:
public void initializeCommonView() {
mModePicker = mCameraActivity.getModePicker();
mCameraViewArray.put(CommonUiType.SHUTTER, new CameraViewImpl(mShutterManager));
mCameraViewArray.put(CommonUiType.MODE_PICKER, new CameraViewImpl(mModePicker));
mCameraViewArray.put(CommonUiType.THUMBNAIL, new CameraViewImpl(mThumbnailManager));
mCameraViewArray.put(CommonUiType.PICKER, new CameraViewImpl(mPickerManager));
mCameraViewArray.put(CommonUiType.INDICATOR, new CameraViewImpl(mIndicatorManager));
mCameraViewArray.put(CommonUiType.REMAINING, new CameraViewImpl(mRemainingManager));
mCameraViewArray.put(CommonUiType.INFO, new CameraViewImpl(mInfoManager));
mCameraViewArray.put(CommonUiType.REVIEW, new CameraViewImpl(mReviewManager));
mCameraViewArray.put(CommonUiType.ROTATE_PROGRESS, new CameraViewImpl(mRotateProgress));
mCameraViewArray.put(CommonUiType.ROTATE_DIALOG, new CameraViewImpl(mRotateDialog));
mCameraViewArray.put(CommonUiType.ZOOM, new CameraViewImpl(mZoomManager));
mCameraViewArray.put(CommonUiType.SETTING, new CameraViewImpl(mSettingManager));
if (mFaceBeautyEntryView != null) {
mCameraViewArray.put(CommonUiType.FACE_BEAUTY_ENTRY, new CameraViewImpl(
mFaceBeautyEntryView));
}
}
而后AppUiImpl加入DeviceCtrl:
mCameraDeviceCtrl.setCameraAppUi(mCameraAppUi);
我們從CameraDeviceCtrl的成員變更來(lái)看,它基本包含了Camera的一切要素,由此可見(jiàn)它非常重要:
...
private CameraAppUiImpl mCameraAppUi;
private ISettingCtrl mISettingCtrl;
private ModuleManager mModuleManager;
private ICameraDeviceExt mDummyCameraDevice = new DummyCameraDevice();
private ICameraDeviceExt mCurCameraDevice = mDummyCameraDevice;
private ICameraDeviceExt mTopCameraDevice = mDummyCameraDevice;
private ICameraDeviceExt mOldTopCameraDevice = mDummyCameraDevice;
private RotateLayout mFocusAreaIndicator;
private FocusManager mFocusManager;
private CamcorderProfile mProfile;
private CameraActor mCameraActor;
private SurfaceTexture mSurfaceTexture;
private SurfaceTexture mTopCamSurfaceTexture;
private PreviewSurfaceView mSurfaceView;
private View mSurfaceViewCover;
private FrameLayout mCurSurfaceViewLayout;
private FrameLayout mLastSurfaceViewLayout;
private CameraStartUpThread mCameraStartUpThread;
...
而CameraDeviceCtrl的初始化非常早(在open之前),在它的構(gòu)造函數(shù)中直接啟動(dòng)了一個(gè)線程來(lái)開(kāi)啟預(yù)覽(open之后):
public CameraDeviceCtrl(CameraActivity activity, ComboPreferences preferences) {
mCameraActivity = activity;
mPreferences = preferences;
mIsFirstStartUp = true;
mMainHandler = new MainHandler(mCameraActivity.getMainLooper());
mCameraStartUpThread = new CameraStartUpThread();
mCameraStartUpThread.start();
}
private class CameraStartUpThread extends Thread {
...
@Override
public void run() {
...
applyFirstParameters();
...
}
前面說(shuō)的整個(gè)open過(guò)程也都是在該線程中完成的,然后就startpreview的過(guò)程:
private void applyFirstParameters () {
Log.i(TAG, "applyFirstParameters");
CameraPerformanceTracker.onEvent(TAG,
CameraPerformanceTracker.NAME_APPLY_FIRST_PARAMS,
CameraPerformanceTracker.ISBEGIN);
mIsFirstOpenCamera = false;
mMainHandler.sendEmptyMessage(MSG_SET_PREVIEW_ASPECT_RATIO);
switchCameraPreview();
mCurCameraDevice.setJpegRotation(mOrientation);
mCameraAppUi.setZoomParameter();
mCurCameraDevice.setDisplayOrientation(true);
mCurCameraDevice.setPreviewFormat(ImageFormat.YV12);
// Camera do not open zsd mode launched by 3rd party.
if (!mCameraActivity.isImageCaptureIntent() && !mCameraActivity.isVideoCaptureIntent()) {
mCurCameraDevice.getParametersExt()
.setZSDMode(SettingUtils.getPreferenceValue(mCameraActivity,
mPreferences,SettingConstants.ROW_SETTING_ZSD, Util.OFF));
}
mCurCameraDevice.getParametersExt().set(ParametersHelper.KEY_FIRST_PREVIEW_FRAME,
Util.FIRST_PREVIEW_BLACK_ON);
mCurCameraDevice.applyParametersToServer();
// for launch performance
mMainHandler.sendEmptyMessageDelayed(MSG_REMOVE_PREVIEW_COVER, 150);
mCameraActor.onCameraParameterReady(true);
mCurCameraDevice.setOneShotPreviewCallback(mOneShotPreviewCallback);
mMainHandler.sendEmptyMessage(MSG_CAMERA_PARAMETERS_READY);
mMainHandler.sendEmptyMessage(MSG_CAMERA_PREVIEW_DONE);
}
設(shè)置各種屬性后通知PhotoActor:
@Override
public void onCameraParameterReady(boolean startPreview) {
super.onCameraParameterReady(startPreview);
Log.i(TAG, "[onCameraParameterReady]startPreview = " + startPreview);
mModuleManager.onCameraParameterReady(startPreview);
if (startPreview) {
if (!mModuleManager.startPreview(true)) {
startPreview(true);
}
}
if (mCameraActivity.getISettingCtrl() != null && mCameraActivity.getISettingCtrl()
.getSettingValue(SettingConstants.KEY_SELF_TIMER) != null) {
String seflTimer = mCameraActivity.getISettingCtrl().getSettingValue(
SettingConstants.KEY_SELF_TIMER);
mSelfTimerManager.setSelfTimerDuration(seflTimer);
}
mCameraActivity.setCameraState(CameraActivity.STATE_IDLE);
mHandler.removeMessages(PARAMETER_CHANGE_DONE);
mHandler.sendEmptyMessage(PARAMETER_CHANGE_DONE);
}
private void startPreview(boolean needStop) {
Log.i(TAG, "[startPreview]needStop = " + needStop);
mCameraActivity.runOnUiThread(new Runnable() {
public void run() {
mCameraActivity.getFocusManager().resetTouchFocus();
}
});
// continuous shot neednot stop preview after capture
if (needStop) {
stopPreview();
}
if (!mIsSnapshotOnIdle) {
// If the focus mode is continuous autofocus, call cancelAutoFocus
// to
// resume it because it may have been paused by autoFocus call.
if (Parameters.FOCUS_MODE_CONTINUOUS_PICTURE.equals(mCameraActivity.getFocusManager()
.getFocusMode())) {
mCameraActivity.getCameraDevice().cancelAutoFocus();
mCameraActivity.getCameraDevice().setAutoFocusMoveCallback(mAutoFocusMoveCallback);
}
mCameraActivity.getFocusManager().setAeLock(false); // Unlock AE and
// AWB.
mCameraActivity.getFocusManager().setAwbLock(false);
}
if (isPowerDebug()) {
if (SettingUtils.isSupported(Parameters.FOCUS_MODE_INFINITY, mCameraActivity
.getParameters().getSupportedFocusModes())) {
overrideFocusMode(Parameters.FOCUS_MODE_INFINITY);
mCameraActivity.getParameters().setFocusMode(
mCameraActivity.getFocusManager().getFocusMode());
//mCameraActivity.applyParametersToServer();
Log.i(TAG, "set debug focus FOCUS_MODE_INFINITY ");
}
} else {
setFocusParameters();
Log.i(TAG, "[startPreview]set setFocusParameters normal");
}
mCameraActivity.getCameraDevice().startPreviewAsync();
mCameraActivity.getFocusManager().onPreviewStarted();
}
然后CameraManager使用Handler發(fā)送消息,最后調(diào)用前面說(shuō)過(guò)的ICamera對(duì)象進(jìn)行相關(guān)操作
public void startPreviewAsync() {
mCameraHandler.sendEmptyMessage(START_PREVIEW_ASYNC);
waitDone();
}
繼承PhotoActor的初始化,在它的構(gòu)造函數(shù)中,根據(jù)參數(shù)確定mode類型:
public PhotoActor(CameraActivity context, ModuleManager moduleManager, int mode) {...}
private void prepareCurrentMode(int newMode) {
Log.i(TAG, "[prepareCurrentMode] mCurrentMode:" + mCurrentMode + ",newMode:" + newMode);
mCurrentMode = newMode;
CameraModeType mode = getCameraModeType(mCurrentMode);
if (mode == null) {
mode = CameraModeType.EXT_MODE_PHOTO;
}
mModuleManager.createMode(mode);
}
public void createMode(CameraModeType newMode) {
Log.i(TAG, "[createMode],newMode:" + newMode + ",mCurrentMode:" + mCurrentMode);
if (mCurrentMode == newMode) {
return;
}
mICameraMode.close();
mCurrentMode = newMode;
mICameraMode = ModeFactory.getInstance().createMode(newMode, mICameraContext);
mAdditionManager.setCurrentMode(newMode);
mICameraMode.open();
}
ICameraMode是一個(gè)接口,定義了各種Mode類型、Action類型以及相關(guān)操作,它的實(shí)現(xiàn)是一個(gè)抽象類CameraMode,因此這里mICameraMode.open();的具體實(shí)現(xiàn)在PhotoActor中:
@Override
public boolean open() {
mAdditionManager.setListener(this);
mAdditionManager.open(true);
return true;
}
跟一下這個(gè)open(true)方法,在AdditionManager中:
public void open(boolean isMode) {
Log.i(TAG, "[open]isMode = " + isMode);
Vector<ICameraAddition> curAddition = mModeAddition;
if (!isMode) {
curAddition = mNormalAddition;
}
for (ICameraAddition addition : curAddition) {
if (addition.isSupport()) {
addition.open();
}
}
}
它的實(shí)現(xiàn)也是一個(gè)抽象類CameraAddition,看下它的子類RemoteCameraAddition:
@Override
public void open() {
Log.i(TAG, "[open], mIsMtkCameraApServiceLaunched:" + mIsMtkCameraApServiceLaunched);
if (mIsMtkCameraApServiceLaunched) {
int cameraId = mICameraDeviceManager.getCurrentCameraId();
ICameraDevice cameraDevice = mICameraDeviceManager.getCameraDevice(cameraId);
if (cameraDevice == null) {
Log.i(TAG, "cameraDevice is null, return.");
return;
}
Parameters parameters = cameraDevice.getParameters();
parameters.setPreviewFormat(ImageFormat.NV21);
if (mCameraService == null) {
bindCameraService();
}
mOpened = true;
}
}
我們看到這里綁定了一個(gè)service,在相機(jī)啟動(dòng)后緊接著啟動(dòng)了一個(gè)service:
private void bindCameraService() {
Log.i(TAG, "bindCameraService()");
mHasNotifyParameterReady = false;
Intent intent = new Intent(mActivity, MtkCameraService.class);
mActivity.bindService(intent, mCameraConnection, Context.BIND_AUTO_CREATE);
}
private void unBindCameraService() {
Log.i(TAG, "unBindCameraService()");
mActivity.unbindService(mCameraConnection);
}
private ServiceConnection mCameraConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
Log.i(TAG, "CameraConnection, onServiceDisconnected()");
mCameraService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
Log.i(TAG, "CameraConnection, onServiceConnected()");
mCameraService = (IMtkCameraService.Stub) service;
}
};
這個(gè)Service有什么特別的要求呢?如果它是在子線程中啟動(dòng)的,那么它至少要支持跨進(jìn)程通信,來(lái)看下:
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "intent:" + intent.getAction());
return new MtkCameraServiceImpl();
}
而這個(gè)MtkCameraServiceImpl也很有講究
public class MtkCameraServiceImpl extends IMtkCameraService.Stub {...}
看到這個(gè)Stub存根,我們想到了aidl,沒(méi)錯(cuò),它是一個(gè)aidl文件定義的:
interface IMtkCameraService {
void openCamera();
void releaseCamera();
void capture();
void sendMessage(in Message msg);
void registerCallback(ICameraClientCallback cb);
void unregisterCallback(ICameraClientCallback cb);
void setFrameRate(int frameRate);
// add for release
void cameraServerExit();
String getSupportedFeatureList();
}
我們暫不論這個(gè)service是怎樣工作的?但記住它是在這里啟動(dòng)的。
最后補(bǔ)充一張圖來(lái)說(shuō)明各種Camera相關(guān)類之間的關(guān)系(菱形箭頭表示內(nèi)部持有該類的對(duì)象,圓內(nèi)十字表示內(nèi)部類):

我們看到這個(gè)關(guān)系確實(shí)比較復(fù)雜,上邊的CameraManger和AndroidCamera內(nèi)部真正持有android.hardware.Camera的對(duì)象。而CameraDeviceCtrl持有多個(gè)ICameraDeviceExt的對(duì)象,ICameraDeviceExt的實(shí)現(xiàn)位于CameraDeviceExt,而CameraDeviceExt內(nèi)部持有CameraProxy這個(gè)內(nèi)部類的對(duì)象,所以通過(guò)CameraDeviceCtrl最終可以調(diào)節(jié)真正的相機(jī)。同理,如果我們有一個(gè)ICameraDeviceManger的對(duì)象,它的先一步實(shí)現(xiàn)在CameraDeviceManagerImpl中,而CameraDeviceManagerImpl持有ICameraDeviceManager的內(nèi)部類ICameraDevice的對(duì)象,而ICameraDevice的實(shí)現(xiàn)位于CameraDeviceImpl中,同樣,CameraDeviceImpl持有CameraProxy的對(duì)象,最終同樣調(diào)用了真正的Camera對(duì)象的方法。