OpenHarmony——CameraService服务启动流程分析 原创 精华
作者:罗健
1. 相机组件简介
相机组件支持相机业务的开发,开发者可以通过已开放的接口实现相机硬件的访问、操作和新功能开发,最常见的操作如:预览、拍照和录像等
CameraService服务作为相机组件的重要一环,对上为app层提供IPC接口,对下完成CameraDevice设备创建以及会话管理等。
1.1 相机组件的代码在openharmony中的位置
相机组件的代码位于【foundation/multimedia/camera_standard】目录下
代码结构如下
├── bundle.json
├── figures
├── frameworks camera frameworks部分,支持js和native转换
│ ├── js
│ └── native
├── hisysevent.yaml
├── interfaces CameraService接口
│ ├── inner_api
│ └── kits
├── LICENSE
├── OAT.xml
├── README.md
├── README_zh.md
├── sa_profile CameraService进程加载配置文件
│ ├── 3008.xml
│ └── BUILD.gn
└── services CameraService启动相关
├── camera_service
└── etc
1.2 CameraService在系统中的位置
相机服务整体架构如下:
可以看到在整个相机组件中,把相机功能抽象为CaptureSession(管理生命周期、参数配置、输入管理、输出管理)、CameraInput(设备查询、设备控制、设备监听)和CameraOutput(元数据输出、流输出和状态控制)。
而CameraService就是将这些功能如何由camera app传达给camera host服务的中间人,以及Camera Host服务反馈的消息转发给Camera app。
所以下面的文章主要来看看CameraService实现了哪些接口,以及CameraService的启动流程
2. CameraService Native实现IPC通信需要实现的主要重要接口
2.1 icamera_service接口
实现ICameraService接口,继承于IRemoteBroker,定义描述符、业务函数和消息码
接口函数代码如下
【foundation\multimedia\camera_standard\services\camera_service\binder\base\include\icamera_service.h】
class ICameraService : public IRemoteBroker {
public:
virtual int32
virtual int32_t CreatePhotoOutput(const sptr<OHOS::IBufferProducer> &producer, int32_t format,
sptr<IStreamCapture> &photoOutput) = 0;
virtual int32_t CreatePreviewOutput(const sptr<OHOS::IBufferProducer> &producer, int32_t format,
sptr<IStreamRepeat> &previewOutput) = 0;
virtual int32_t CreateCustomPreviewOutput(const sptr<OHOS::IBufferProducer> &producer, int32_t format,
int32_t width, int32_t he_t CreateCameraDevice(std::string cameraId, sptr<ICameraDeviceService>& device) = 0;
virtual int32_t SetCallback(sptr<ICameraServiceCallback>& callback) = 0;
virtual int32_t GetCameras(std::vector<std::string> &cameraIds,
std::vector<std::shared_ptr<Camera::CameraMetadata>> &cameraAbilityList) = 0;
virtual int32_t CreateCaptureSession(sptr<ICaptureSession> &session) = 0;
ight, sptr<IStreamRepeat> &previewOutput) = 0;
virtual int32_t CreateVideoOutput(const sptr<OHOS::IBufferProducer> &producer, int32_t format,
sptr<IStreamRepeat> &videoOutput) = 0;
virtual int32_t SetListenerObject(const sptr<IRemoteObject> &object) = 0;
DECLARE_INTERFACE_DESCRIPTOR(u"ICameraService");
};
} // namespace CameraStandard
}
2.2 hcamera_service_stub接口
实现服务提供端HCameraServiceStub接口,继承于IRemoteStub(Native),实现接口类中未实现方法外,还需要实现OnRemoteRequest方法
接口函数代码:
【foundation\multimedia\camera_standard\services\camera_service\binder\server\include\hcamera_service_stub.h】
class HCameraServiceStub : public IRemoteStub<ICameraService> {
public:
HCameraServiceStub();
~HCameraServiceStub();
int OnRemoteRequest(uint32_t code, MessageParcel &data,
MessageParcel &reply, MessageOption &option) override;
private:
int HandleGetCameras(MessageParcel& reply);
int HandleCreateCameraDevice(MessageParcel &data, MessageParcel &reply);
int HandleSetCallback(MessageParcel &data);
int HandleCreateCaptureSession(MessageParcel &reply);
int HandleCreatePhotoOutput(MessageParcel &data, MessageParcel &reply);
int HandleCreatePreviewOutput(MessageParcel &data, MessageParcel &reply);
int HandleCreatePreviewOutputCustomSize(MessageParcel &data, MessageParcel &reply);
int HandleCreateVideoOutput(MessageParcel &data, MessageParcel &reply);
int DestroyStubForPid(pid_t pid);
void ClientDied(pid_t pid);
int SetListenerObject(const sptr<IRemoteObject> &object) override;
int SetListenerObject(MessageParcel &data, MessageParcel &reply);
std::map<pid_t, sptr<CameraDeathRecipient>> deathRecipientMap_;
std::map<pid_t, sptr<IStandardCameraListener>> cameraListenerMap_;
};
} // namespace CameraStandard
}
2.3 hcamera_service_proxy接口
实现服务请求段接口HCameraServiceProxy,继承IRemoteProxy(Native),封装业务函数,调用SendRequest将请求发送到Stub
接口函数代码:
【foundation\multimedia\camera_standard\services\camera_service\binder\client\include\hcamera_service_proxy.h】
class HCameraServiceProxy : public IRemoteProxy<ICameraService> {
public:
explicit HCameraServiceProxy(const sptr<IRemoteObject> &impl);
virtual ~HCameraServiceProxy() = default;
int32_t CreateCameraDevice(std::string cameraId, sptr<ICameraDeviceService>& device) override;
int32_t SetCallback(sptr<ICameraServiceCallback>& callback) override;
int32_t GetCameras(std::vector<std::string> &cameraIds,
std::vector<std::shared_ptr<Camera::CameraMetadata>> &cameraAbilityList) override;
int32_t CreateCaptureSession(sptr<ICaptureSession>& session) override;
int32_t CreatePhotoOutput(const sptr<OHOS::IBufferProducer> &producer, int32_t format,
sptr<IStreamCapture>& photoOutput) override;
int32_t CreatePreviewOutput(const sptr<OHOS::IBufferProducer> &producer, int32_t format,
sptr<IStreamRepeat>& previewOutput) override;
int32_t CreateCustomPreviewOutput(const sptr<OHOS::IBufferProducer> &producer, int32_t format, int32_t width,
int32_t height, sptr<IStreamRepeat>& previewOutput) override;
int32_t CreateVideoOutput(const sptr<OHOS::IBufferProducer> &producer, int32_t format,
sptr<IStreamRepeat>& videoOutput) override;
int32_t SetListenerObject(const sptr<IRemoteObject> &object) override;
private:
static inline BrokerDelegator<HCameraServiceProxy> delegator_;
};
} // namespace CameraStandard
}
3. CameraService启动流程
3.1 CameraService启动入口
sa_main通过读取解析camera_service.xml, 把动态库libcamera_service.z.so加载到自身进程中来,从而将camera_service服务启动起
在系统起来的时候,通过下面的命令{/system/bin/sa_main", “/system/profile/camera_service.xml” }将camera_service拉去来
<info>
<process>camera_service</process>
<loadlibs>
<libpath>libcamera_service.z.so</libpath>
</loadlibs>
<systemability>
<name>3008</name>
<libpath>libcamera_service.z.so</libpath>
<run-on-create>true</run-on-create>
<distributed>false</distributed>
<dump-level>1</dump-level>
</systemability>
</info>
3.2 CameraService启动流程
由配置文件中path字段,配置的是去运行"/system/bin/sa_main"可执行程序,再通过sa_main里的DoStartSAProcess()根据/system/profile/camera_service.xml的描述,去加载libcamera_service.z.so,以此来切换到camera_server进程的上下文中运行
在DoStartSAProcess中完成SystemAbilityProfiles的初始化,然后调用ret = Run(saId)函数将服务拉起来
【foundation\distributedschedule\safwk\services\safwk\src\local_ability_manager.cpp】
bool LocalAbilityManager::Run(int32_t saId)
{
...
FindAndStartPhaseTasks();
...
return true;
}
在FindAndStartPhaseTasks中根据启动的类型,去启动每一段的任务,调用StartPhaseTasks
【foundation\distributedschedule\safwk\services\safwk\src\local_ability_manager.cpp】
void LocalAbilityManager::StartPhaseTasks(const std::list<SystemAbility*>& systemAbilityList)
{
if (systemAbilityList.empty()) {
return;
}
for (auto systemAbility : systemAbilityList) {
if (systemAbility != nullptr) {
HILOGD(TAG, "add phase task for SA:%{public}d", systemAbility->GetSystemAbilitId());
std::lock_guard<std::mutex> autoLock(startPhaseLock_);
++startTaskNum_;
auto task = std::bind(&LocalAbilityManager::StartSystemAbilityTask, this, systemAbility);
pool_.AddTask(task);
}
}
...
}
通过bind函数去执行每一个SystemAbilityTask
【foundation\distributedschedule\safwk\services\safwk\src\local_ability_manager.cpp】
void LocalAbilityManager::StartSystemAbilityTask(SystemAbility* ability)
{
if (ability != nullptr) {
HILOGD(TAG, "StartSystemAbility is called for %{public}d", ability->GetSystemAbilitId());
if (ability->GetDependSa().empty()) {
ability->Start();
}
...
}
进入start函数
【foundation\distributedschedule\safwk\services\safwk\src\system_ability.cpp】
void SystemAbility::Start()
{
...
OnStart();
...
}
调用到实现服务的OnStart中
【foundation\multimedia\camera_standard\services\camera_service\src\hcamera_service.cpp】
void HCameraService::OnStart()
{
...
if (cameraHostManager_->Init() != CAMERA_OK) {
MEDIA_ERR_LOG("HCameraService OnStart failed to init camera host manager.");
}
bool res = Publish(this);//调用父类的publish,即system_ability.cpp中的public
if (res) {
MEDIA_INFO_LOG("HCameraService OnStart res=%{public}d", res);
}
...
}
调用cameraHostManager_->Init(),获取cameraHostProxy实例,完成相关的初始化,其实就是为了后面使用CameraHost做准备了
3.3 CameraService服务发布
后面调用Publish(this)将CameraService服务通过AddSystemAbility接口注册注册进SystemAbilityManager中
【foundation\distributedschedule\safwk\services\safwk\src\system_ability.cpp】
bool SystemAbility::Publish(sptr<IRemoteObject> systemAbility)
{
...
int32_t result = samgrProxy->AddSystemAbility(saId_, publishObj_, saExtra);
...
}
至此CameraService服务就发布完成了
后面Camera Client就可以通过SystemAbilityManager的GetSystemAbility方法可获取到Camera_service的代理IRemoteObject,然后构造HCameraServiceProxy
4. 总结
1.相机组件的基本介绍以及CameraService在相机组件中的位置
2.介绍了CameraService的启动流程及服务的发布过程
更多原创内容请关注:深开鸿技术团队
入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
楼主,图片好像挂掉了,方便补一下吗?
重新上传了
大佬能出一个camera设备驱动的教程吗