近期在排查打开相机黑屏的问题,然后就跟了一下android camera的框架。根据log分析发现是camera个数为0,然后就进行代码流程跟踪。由于开发平台是mtk平台,log提示上层报错的对应代码逻辑如下图。
mCameraService是ICameraService接口类型。
获取服务的名称如下:
并且是通过aidl跟底层c++通信。
frameworks/base/core/java/android/hardware/ICameraService.aidl
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware;
import android.hardware.ICamera;
import android.hardware.ICameraClient;
import android.hardware.camera2.ICameraDeviceUser;
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.utils.BinderHolder;
import android.hardware.ICameraServiceListener;
import android.hardware.CameraInfo;
/**
* Binder interface for the native camera service running in mediaserver.
*
* @hide
*/
interface ICameraService
{
/**
* Keep up-to-date with frameworks/av/include/camera/ICameraService.h
*/
int getNumberOfCameras(int type);
// rest of 'int' return values in this file are actually status_t
int getCameraInfo(int cameraId, out CameraInfo info);
int connect(ICameraClient client, int cameraId,
String opPackageName,
int clientUid,
// Container for an ICamera object
out BinderHolder device);
int connectDevice(ICameraDeviceCallbacks callbacks, int cameraId,
String opPackageName,
int clientUid,
// Container for an ICameraDeviceUser object
out BinderHolder device);
int addListener(ICameraServiceListener listener);
int removeListener(ICameraServiceListener listener);
int getCameraCharacteristics(int cameraId, out CameraMetadataNative info);
/**
* The java stubs for this method are not intended to be used. Please use
* the native stub in frameworks/av/include/camera/ICameraService.h instead.
* The BinderHolder output is being used as a placeholder, and will not be
* well-formatted in the generated java method.
*/
int getCameraVendorTagDescriptor(out BinderHolder desc);
// Writes the camera1 parameters into a single-element array.
int getLegacyParameters(int cameraId, out String[] parameters);
// Determines if a particular API version is supported; see ICameraService.h for version defines
int supportsCameraApi(int cameraId, int apiVersion);
int connectLegacy(ICameraClient client, int cameraId,
int halVersion,
String opPackageName,
int clientUid,
// Container for an ICamera object
out BinderHolder device);
int setTorchMode(String CameraId, boolean enabled, IBinder clientBinder);
/**
* Notify the camera service of a system event. Should only be called from system_server.
*
* Callers require the android.permission.CAMERA_SEND_SYSTEM_EVENTS permission.
*/
oneway void notifySystemEvent(int eventId, in int[] args);
// atc aosp enhancement: cvbs camera , cvbs format detect.
int atcSetCameraInfoUpdateFlag(int flag);
}
当时我们公司的应用开发工程师打开相机时会进行摄像头探测,通过调用framework的aidl接口去调用mCameraService.getNumberOfCameras()探测camera个数,总的流程会通过三部分讲解。分别为framework层,native层,driver层三部分。
一:framework层
注意:CarmerServiceDetector中的mCameraService是直接通过aidl调用到c++的CameraSevice服务的。具体代码如下:
private static final String CAMERA_SERVICE_BINDER_NAME = "media.camera";
......//代表中间有很多代码
mCameraService = ICameraService.Stub.asInterface(ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME));
我们看下CameraSevice.cpp是如何启动注册服务以及完成ICameraService.aidl的接口调用的。
//代码路径:frameworks/av/media/mediaserver/main_mediaserver.cpp
int main(int argc __unused, char** argv)
{
......//代表中间走过了很多代码
//相机服务开始初始化并注册
CameraService::instantiate();
.....
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
}
class CameraService :
public BinderService<CameraService>,
public BnCameraService,
public IBinder::DeathRecipient,
public camera_module_callbacks_t
{
friend class BinderService<CameraService>;
public:
class Client;
class BasicClient;
......
// 获取注册服务的名字,提供上层aidl找到该服务
static char const* getServiceName() {
return "media.camera"; }
.....
}
注意:在instantiate函数中,将CameraService注册到系统的binder service列表中,这样以后上层java就可以通过aid调