publicstatic Camera mCameraDevice;
try {
Log.d(TAG,"open camera 0");
//writeFile(APK_FILE_PATH,1);
Log.d("qyh","opencamera"+System.currentTimeMillis());
mCameraDevice = Camera.open(0);/*打开camera,获取camera实例给mCameraDevice */
Log.d("qyh","sendMessage"+System.currentTimeMillis());
mHandler.sendEmptyMessageDelayed(DISMISS_ALL,500);
}catch (Exception e) {
Log.e(TAG,"open camera error");
//writeFile(APK_FILE_PATH,0);
e.printStackTrace();
return;
}
try{
mCameraDevice.setPreviewDisplay(holder);/*这个应该是数据的显示部分,待分析*/
}catch (Exception e) {
e.printStackTrace();
}
Camera.Parameters parameters = mCameraDevice.getParameters();/*获取驱动的相关参数*/
parameters.setPreviewSize(800, 600);/*重新设置预览的分辨率*/
mCameraDevice.setParameters(parameters);/*设置相关参数*/
mCameraDevice.startPreview();/*开始进入预览模式*/
以上是应用APP中打开camera的简要步骤,下面我们就对mCameraDevice = Camera.open(0);进行具体的跟进下:
STEP 1:
\frameworks\base\core\java\android\hardware\Camera.java
public static Camera open(int cameraId) {
if (!isPermissionGranted()) {
return null;
}
returnnewCamera(cameraId);
}
STEP 2:
\frameworks\base\core\java\android\hardware\Camera.java
/** used by Camera#open, Camera#open(int)*/
Camera(int cameraId) {
int err = cameraInitNormal(cameraId);
if (checkInitErrors(err)) {
switch(err) {
case EACCESS:
throw newRuntimeException("Fail to connect to camera service");
case ENODEV:
throw newRuntimeException("Camera initialization failed");
default:
// Should never hit this.
throw newRuntimeException("Unknown camera error");
}
}
}
STEP 3:
private int cameraInitNormal(int cameraId){
return cameraInitVersion(cameraId,CAMERA_HAL_API_VERSION_NORMAL_CONNECT);
}
/*
CAMERA_HAL_API_VERSION_NORMAL_CONNECT参数的定义
private static final int CAMERA_HAL_API_VERSION_NORMAL_CONNECT= -2;
*/
STEP 4:
private int cameraInitVersion(int cameraId,int halVersion) {
mShutterCallback = null;
mRawImageCallback = null;
mJpegCallback = null;
mPreviewCallback = null;
mPreviewRawDumpCallback = null;
mPostviewCallback = null;
mUsingPreviewAllocation = false;
mZoomListener = null;
Looper looper;
if ((looper = Looper.myLooper()) !=null) {
mEventHandler = new EventHandler(this,looper);
} else if ((looper =Looper.getMainLooper()) != null) {
mEventHandler = newEventHandler(this, looper);
} else {
mEventHandler = null;
}
return native_setup(newWeakReference<Camera>(this), cameraId, halVersion,
ActivityThread.currentOpPackageName());
}
/*
private native final int native_setup(Object camera_this, int cameraId,int halVersion,
String packageName);
native_setup是一个本地的方法,对应的JNI在下面步骤中。
*/
STEP 5:
\frameworks\base\core\jni\android_hardware_Camera.cpp
// connect tocamera service
static jint android_hardware_Camera_native_setup(JNIEnv *env,jobject thiz,
jobject weak_this, jint cameraId, jinthalVersion, 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'tcare, do normal camera connect.
camera = Camera::connect(cameraId,clientName,
Camera::USE_CALLING_UID);/*这里的 Camera 为本地的类,在下面步骤的Camera.cpp中,而不是前面用到的Camera.java中的类。*/
} else {
jint status =Camera::connectLegacy(cameraId, halVersion, clientName,
Camera::USE_CALLING_UID,camera);
if (status != NO_ERROR) {
return status;
}
}
if (camera == NULL) {
return -EACCES;
}
// make sure camera hardware is alive
if (camera->getStatus() != NO_ERROR) {
return NO_INIT;
}
jclass clazz =env->GetObjectClass(thiz);
if (clazz == NULL) {
// This should never happen
jniThrowRuntimeException(env,"Can't find android/hardware/Camera");
return INVALID_OPERATION;
}
// We use a weak reference so the Cameraobject can be garbage collected.
// The reference is only used as a proxyfor callbacks.
//!++
#if 0 // Use MTK JNI for MTK camerafeature.
sp<JNICameraContext> context = newJNICameraContext(env, weak_this, clazz, camera);
#else
sp<JNICameraContext> context = new MtkJNICameraContext(env,weak_this, clazz, camera);
#endif
//!--
context->incStrong((void*)android_hardware_Camera_native_setup);
camera->setListener(context);
// save context in opaque field
env->SetLongField(thiz, fields.context,(jlong)context.get());
return NO_ERROR;
}
STEP 6:
\frameworks\av\camera\Camera.cpp
sp<Camera>Camera::connect(int cameraId, const String16& clientPackageName,
int clientUid)
{
return CameraBaseT::connect(cameraId,clientPackageName, clientUid);
}
/*
CameraBaseT在/frameworks/av/include/camera/CameraBase.h中有定义如下:
typedefCameraBase<TCam> CameraBaseT
所以就是调用的CameraBase类的connect了。
*/
STEP 7:
\frameworks\av\camera\CameraBase.cpp
template<typename TCam, typename TCamTraits>
sp<TCam>CameraBase<TCam, TCamTraits>::connect(int cameraId,
const String16& clientPackageName,
int clientUid)
{
ALOGV("%s: connect",__FUNCTION__);
sp<TCam> c = new TCam(cameraId);
sp<TCamCallbacks> cl = c;
status_t status = NO_ERROR;
constsp<ICameraService>& cs = getCameraService();/*获取cameraService,这个在开机的时候已经注册过的一个camera服务: media.camera */
if (cs != 0) {
TCamConnectService fnConnectService =TCamTraits::fnConnectService;
status =(cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,
/*out*/ c->mCamera);
/*
这个对应的就是CameraService::connect;这里面的具体转换过程还不太清楚。待后续学习。Cs.get()是什么意思?CameraService 中没有找到get这个函数。
fnConnectService的定义在:\frameworks\av\camera\ Camera.cpp
CameraTraits<Camera>::TCamConnectServiceCameraTraits<Camera>::fnConnectService =
&ICameraService::connect;
*/
}
if (status == OK && c->mCamera!= 0) {
IInterface::asBinder(c->mCamera)->linkToDeath(c);
c->mStatus = NO_ERROR;
} else {
ALOGW("An error occurred whileconnecting to camera: %d", cameraId);
c.clear();
}
return c;
}
STEP 8:
\frameworks\av\services\camera\libcameraservice\CameraService.cpp
status_tCameraService::connect(
const sp<ICameraClient>&cameraClient,
int cameraId,
const String16& clientPackageName,
int clientUid,
/*out*/
sp<ICamera>& device) {
status_t ret = NO_ERROR;
String8 id =String8::format("%d", cameraId);
sp<Client> client = nullptr;
ret =connectHelper<ICameraClient,Client>(cameraClient, id,CAMERA_HAL_API_VERSION_UNSPECIFIED,
clientPackageName, clientUid, API_1, false, false, /*out*/client);
if(ret != NO_ERROR) {
logRejected(id, getCallingPid(),String8(clientPackageName),
String8::format("%s(%d)", strerror(-ret), ret));
return ret;
}
device = client;
return NO_ERROR;
}
STEP 9:
\frameworks\av\services\camera\libcameraservice\CameraService.h
template<classCALLBACK, class CLIENT>
status_t CameraService::connectHelper(constsp<CALLBACK>& cameraCb, const String8& cameraId,
int halVersion, const String16&clientPackageName, int clientUid,
apiLevel effectiveApiLevel, boollegacyMode, bool shimUpdateOnly,
/*out*/sp<CLIENT>& device) {
status_t ret = NO_ERROR;
String8 clientName8(clientPackageName);
int clientPid = getCallingPid();
ALOGI("CameraService::connect call(PID %d \"%s\", camera ID %s) for HAL version %s and "
"Camera API version %d",clientPid, clientName8.string(), cameraId.string(),
(halVersion == -1) ?"default" : std::to_string(halVersion).c_str(),
static_cast<int>(effectiveApiLevel));
sp<CLIENT> client = nullptr;
{
// Acquire mServiceLock and preventother clients from connecting
std::unique_ptr<AutoConditionLock>lock =
AutoConditionLock::waitAndAcquire(mServiceLockWrapper,DEFAULT_CONNECT_TIMEOUT_NS);
if (lock == nullptr) {
ALOGE("CameraService::connectX (PID %d) rejected (too many other clients connecting)."
, clientPid);
return -EBUSY;
}
// Enforce client permissions and dobasic sanity checks
if((ret =validateConnectLocked(cameraId, /*inout*/clientUid)) != NO_ERROR) {
return ret;
}
// Check the shim parameters afteracquiring lock, if they have already been updated and
// we were doing a shim update, returnimmediately
if (shimUpdateOnly) {
auto cameraState =getCameraState(cameraId);
if (cameraState != nullptr) {
if(!cameraState->getShimParams().isEmpty()) return NO_ERROR;
}
}
sp<BasicClient> clientTmp =nullptr;
std::shared_ptr<resource_policy::ClientDescriptor<String8,sp<BasicClient>>> partial;
if ((ret =handleEvictionsLocked(cameraId, clientPid, effectiveApiLevel,
IInterface::asBinder(cameraCb),clientName8, /*out*/&clientTmp,
/*out*/&partial)) !=NO_ERROR) {
return ret;
}
if (clientTmp.get() != nullptr) {
// Handle special case for API1MediaRecorder where the existing client is returned
device =static_cast<CLIENT*>(clientTmp.get());
return NO_ERROR;
}
// give flashlight a chance to closedevices if necessary.
mFlashlight->prepareDeviceOpen(cameraId);
// TODO: Update getDeviceVersion + HALinterface to use strings for Camera IDs
int id = cameraIdToInt(cameraId);
if (id == -1) {
ALOGE("%s: Invalid camera ID%s, cannot get device version from HAL.", __FUNCTION__,
cameraId.string());
return BAD_VALUE;
}
int facing = -1;
int deviceVersion =getDeviceVersion(id, /*out*/&facing);
sp<BasicClient> tmp = nullptr;
if((ret =makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid,
clientUid, getpid(), legacyMode, halVersion, deviceVersion,effectiveApiLevel,
/*out*/&tmp)) != NO_ERROR) {
return ret;
}
/*
上面的makeClient创建的只是cameraservice内部类client,而不是客户端。主要从打印中可以看到,是先创建cameraservice的内部clinet然后再创建的客户端clinet的。具体过程带分析。
01-02 00:27:12.751 181 448 D CameraService:[CameraService::loadSound] + tid:448 mSoundLock - ref=0
01-02 00:27:12.751 181 448 D CameraService:CameraService::loadSound ref=0
01-02 00:27:12.751 638 660 V DisplayEventReceiver:call nativeScheduleVsync mReceiverPtr = -1606054400
01-02 00:27:12.752 181 448 D CameraService:Client::Client X (pid 4232, id 0)
01-02 00:27:12.752 181 448 D CameraClient:CameraClient::CameraClient E (pid 4232, id 0)
01-02 00:27:12.752 181 448 D CameraClient:CameraClient::CameraClient X (pid 4232, id 0)
01-02 00:27:12.752 181 448 D CameraClient:CameraClient::initialize E (pid 4232, id 0)
*/
client =static_cast<CLIENT*>(tmp.get());
/*
Client则为客户端,具体的实现带分析。Tmp.get()不知道什么意思?
*/
LOG_ALWAYS_FATAL_IF(client.get() ==nullptr, "%s: CameraService in invalid state",
__FUNCTION__);
if ((ret =client->initialize(mModule)) != OK) {/*客户端初始化*/
/*
这里的mModule就是开机初始化cameraservice实例的时候获取的
mModule = newCameraModule(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;
deletemModule;
mModule =nullptr;
return;
}
*/
ALOGE("%s: Could notinitialize client from HAL module.", __FUNCTION__);
return ret;
}
//!++ The part is merged by MTK, googlewill merge in MR1
/*
sp<IBinder> remoteCallback =client->getRemote();
if (remoteCallback != nullptr) {
remoteCallback->linkToDeath(this);
}
*/
//!--
// Update shim paremeters for legacyclients
if (effectiveApiLevel == API_1) {
// Assume we have always received aClient subclass for API1
sp<Client> shimClient =reinterpret_cast<Client*>(client.get());
String8 rawParams =shimClient->getParameters();
CameraParameters params(rawParams);
auto cameraState =getCameraState(cameraId);
if (cameraState != nullptr) {
cameraState->setShimParams(params);
} else {
ALOGE("%s: Cannot updateshim parameters for camera %s, no such device exists.",
__FUNCTION__,cameraId.string());
}
}
if (shimUpdateOnly) {
// If only updating legacy shimparameters, immediately disconnect client
mServiceLock.unlock();
client->disconnect();
mServiceLock.lock();
} else {
// Otherwise, add client to activeclients list
finishConnectLocked(client,partial);
}
} // lock is destroyed, allow furtherconnect calls
// Important: release the mutex here so theclient can call back into the service from its
// destructor (can be at the end of thecall)
device = client;
return NO_ERROR;
}
STEP 10:
\frameworks\av\services\camera\libcameraservice\api1\CameraClient.cpp
status_tCameraClient::initialize(CameraModule *module) {
int callingPid = getCallingPid();
status_t res;
LOG1("CameraClient::initialize E (pid%d, id %d)", callingPid, mCameraId);
// Verify ops permissions
res = startCameraOps();
if (res != OK) {
return res;
}
char camera_device_name[10];
snprintf(camera_device_name,sizeof(camera_device_name), "%d", mCameraId);
mHardware = newCameraHardwareInterface(camera_device_name);
/*
mHardware 定义是 CameraHardwareInterface,他也是Android的通用接口。各个厂家提供的功能都要通过CameraHardwareInterface适配向CameraService提供硬件操作接口。
*/
res = mHardware->initialize(module);
if (res != OK) {
ALOGE("%s: Camera %d: unable toinitialize device: %s (%d)",
__FUNCTION__, mCameraId,strerror(-res), res);
mHardware.clear();
return res;
}
//!++
// mtk callback
mHardware->setMtkCallbacks(
mtkMetadataCallback,
(void *)(uintptr_t)mCameraId);
//!--
mHardware->setCallbacks(notifyCallback,
dataCallback,
dataCallbackTimestamp,
(void *)(uintptr_t)mCameraId);
// Enable zoom, error, focus, and metadatamessages by default
enableMsgType(CAMERA_MSG_ERROR |CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |
CAMERA_MSG_PREVIEW_METADATA |CAMERA_MSG_FOCUS_MOVE);
//!++
enableMsgType(MTK_CAMERA_MSG_EXT_NOTIFY |MTK_CAMERA_MSG_EXT_DATA); // Enable MTK-extended messages by default
//!--
LOG1("CameraClient::initialize X (pid %d,id %d)", callingPid, mCameraId);
return OK;
}
STEP 10:
\frameworks\av\services\camera\libcameraservice\device1\CameraHardwareInterface.h
status_t initialize(CameraModule *module)
{
ALOGI("Opening camera %s",mName.string());
camera_info info;
status_t res = module->getCameraInfo(atoi(mName.string()),&info);
if (res != OK) return res;
int rc = OK;
if (module->getModuleApiVersion()>= CAMERA_MODULE_API_VERSION_2_3 &&
info.device_version >CAMERA_DEVICE_API_VERSION_1_0) {
// Open higher version cameradevice as HAL1.0 device.
rc =module->openLegacy(mName.string(),
CAMERA_DEVICE_API_VERSION_1_0,
(hw_device_t **)&mDevice);
} else {
rc =module->open(mName.string(), (hw_device_t **)&mDevice);
}
if (rc != OK) {
ALOGE("Could not open camera%s: %d", mName.string(), rc);
return rc;
}
initHalPreviewWindow();
return rc;
}
/*
module->open这里的module就是\frameworks\av\services\camera\libcameraservice\CameraService.cpp中的onFirstRef在启动该服务的时候就创建好了,而cameraserver是在开机的时候就servicemanager中启动的。
void CameraService::onFirstRef()
{
ALOGI("CameraService process starting");
BnCameraService::onFirstRef();
// Updatebattery 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,
(consthw_module_t **)&rawModule);
/*
这里的hw_get_module获取的就是CAMERA_HARDWARE_MODULE_ID对应的库文档,对应我们现在分析平台就是camera.mt8127.so,mt8127对应的是MTK的芯片平台。
*/
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 = newCameraModule(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;
deletemModule;
mModule =nullptr;
return;
}
mNumberOfCameras = mModule->getNumberOfCameras();
mNumberOfNormalCameras = mNumberOfCameras;
……
*/
HAL层就是camera.mt8127.so具体的实现,就是MTK做的一些接口。对于\frameworks\av\services\camera\libcameraservice\device1\CameraHardwareInterface.h具体的实现。所以后面一篇文章中,我们再单独的学习CAMERA 的 HAL.