平台:7885
OH版本:6.1
问题:systemui的下拉控制中心的手电筒怎么控制?
现状:flash底层驱动已经适配好了,使用# echo 12 > /sys/class/misc/sprd_flash/test
# echo 13 > /sys/class/misc/sprd_flash/test可以打开或者关闭flash,但是控制中心的开关无法使用,是不是中间还需要一层?有没有大佬分享一下谢谢
1.需要先检测设备是否支持手电筒接口:isTorchSupported
@State cameraManager: camera.CameraManager = camera.getCameraManager(getContext());
let torchSupported: boolean = this.isTorchSupported(this.cameraManager)
2.通过cameraManager.setTorchMode(torchMode); 1来开启或0关闭
在OH6.1中,手电筒功能已经归入既有框架(camera子系统),无需额外打造中间层,只需要补齐VDI函数即可。
完整调用链
SystemUI (ArkTS)
↓ 调用 @ohos.multimedia.camera API
Camera Framework (foundation/multimedia/camera_framework)
↓ IPC
Camera HDI Service (drivers/peripheral/camera/hdi_service)
↓
Camera VDI (drivers/peripheral/camera/vdi_base)
↓
展锐平台 VDI 实现 (vendor/xxx/camera)
↓ 写 sysfs
sprd_flash 驱动 (/sys/class/misc/sprd_flash/test)
你底层驱动已通,问题卡在 Camera VDI 层到驱动的桥接。
从 6.1 代码看,Camera VDI 中 SetFlashlight 的定义在:
// drivers/peripheral/camera/vdi_base/v4l2/src/camera_host/camera_host_vdi_impl.cpp:349
RetCode CameraHostVdiImpl::SetFlashlight(...) {
...
RetCode rc = deviceManager->SetFlashlight(FLASH_TORCH, isEnable);
...
}
最终调用到 ViController::SetFlashlight → viObject_->SetFlashlight。
但 drivers/peripheral/camera/vdi_base 下只有 v4l2 和 usb_camera 两种通用实现,没有展锐平台的 VDI 实现。展锐的 VDI 实现应该在 vendor/ 目录下,且必须实现 SetFlashlight(FLASH_TORCH, true) 来操作你的 /sys/class/misc/sprd_flash/test。
在你的 vendor/展锐平台/camera/ 或类似路径下,找到展锐的 CameraHost VDI 实现,搜索 SetFlashlight。大概率是空实现或未实现。
你需要在展锐的 VDI 实现中补充类似这样的代码:
#include <fcntl.h>
#include <unistd.h>
RetCode SpreadtrumCameraHost::SetFlashlight(bool isEnable) {
int fd = open("/sys/class/misc/sprd_flash/test", O_WRONLY);
if (fd < 0) {
return RC_ERROR;
}
const char* cmd = isEnable ? "12" : "13";
write(fd, cmd, strlen(cmd));
close(fd);
return RC_OK;
}
确保在SystemUI 的开关调用的是 Camera 的 Torch API:
import camera from '@ohos.multimedia.camera';
// 打开手电筒
camera.getCameraManager().setTorchMode(true);
// 关闭手电筒
camera.getCameraManager().setTorchMode(false);
如果 SystemUI 是原厂自带的,但 6.1 代码库里 controlcentercomponent 中没有手电筒相关代码,说明官方 SystemUI 可能没有内置手电筒开关。你需要自己添加一个开关组件,调用上述 API。
SystemUI应用与底层驱动交互间是需要一个系统服务作为桥梁。对于你这种情况一般是由SystemUI(客户端)通过IPC/RPC(进程间通信)调用一个系统服务(服务端),再由这个服务去操作硬件。
