当前位置:网站首页>Camera 手电筒修改
Camera 手电筒修改
2022-07-23 10:42:00 【虫师魁拔】
文档内容:修改原生接口,使用节点控制的方式替换原生调用hal层接口。
一、应用设置API
应用设置手电筒代码,调用系统接口 setTorchMode
private final CameraManager mCameraManager;
private final Context mContext;
public FlashlightControllerImpl(Context context) {
mContext = context;
mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
}
public void setFlashlight(String cameraId, boolean enabled) {
synchronized (this) {
try {
mCameraManager.setTorchMode(cameraId, enabled);
} catch (CameraAccessException e) {
Log.e(TAG, "Couldn't set torch mode", e);
}
}
}这里CameraManager调用会直接到 libcameraservice 的 CameraService.cpp 中,这点不同于一般XXXManager 之类的实现代码在 framework 中 services.jar 模块之中。
二、关键函数
CameraService.cpp 中执行几个重要函数
setTorchMode 操作闪光灯
Status CameraService::setTorchMode(const String16& cameraId, bool enabled,
const sp<IBinder>& clientBinder) {
Mutex::Autolock lock(mServiceLock);
ATRACE_CALL();
if (enabled && clientBinder == nullptr) {
ALOGE("%s: torch client binder is NULL", __FUNCTION__);
return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
"Torch client Binder is null");
}
String8 id = String8(cameraId.string());
//ADD 写节点打开手电筒代码块
std::string idStr = std::string(id);
char value[PROPERTY_VALUE_MAX];
memset(value, 0, sizeof(value));
property_get("sys.torch.rw_dev", value, "0");
int32_t serviceStatus = ICameraServiceListener::TORCH_STATUS_NOT_AVAILABLE;
if (0 == strcmp(value, "1") && idStr.compare("0") == 0) {
if (enabled) {
FILE *fp = NULL;
fp = fopen("/sys/class/leds/led:torch_0/brightness", "w");
fprintf(fp, "250");
fclose(fp);
fp = fopen("/sys/class/leds/led:switch_0/brightness", "w");
fprintf(fp, "1");
fclose(fp);
serviceStatus = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON;
} else {
FILE *fp = NULL;
fp = fopen("/sys/class/leds/led:switch_0/brightness", "w");
fprintf(fp, "0");
fclose(fp);
serviceStatus = ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF;
}
// 通知手电筒状态变化
for (auto& i : mListenerList) {
i->getListener()->onTorchStatusChanged(serviceStatus, String16{cameraId});
}
return Status::ok();
}
//ADD
... ...
// 判断是否设置为系统相机
int uid = CameraThreadState::getCallingUid();
if (shouldRejectSystemCameraConnection(id)) {
return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT, "Unable to set torch mode"
" for system only device %s: ", id.string());
}
... ...
// 原生check闪光灯是否可用
StatusInternal cameraStatus = state->getStatus();
... ...
// 原生操作闪光灯地方
status_t err = mFlashlight->setTorchMode(id, enabled);
... ...
return Status::ok();
}
onTorchStatusChangedLocked 手电筒状态回调函数
即使改成写节点的方式操作手电筒,开启关闭camera后也会执行此函数通知状态
void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
TorchModeStatus newStatus, SystemCameraKind systemCameraKind) {
ALOGI("%s: Torch status changed for cameraId=%s, mHCameraIdStr=%s, newStatus=%d",
__FUNCTION__, cameraId.string(), mHCameraIdStr.string(), newStatus);
TorchModeStatus status;
status_t res = getTorchStatusLocked(cameraId, &status);
if (res) {
ALOGE("%s: cannot get torch status of camera %s: %s (%d)",
__FUNCTION__, cameraId.string(), strerror(-res), res);
return;
}
if (status == newStatus) {
return;
}
// 增加判断,对于后摄(后摄有闪光灯)打开时,关闭手电筒
char value[PROPERTY_VALUE_MAX];
memset(value, 0, sizeof(value));
property_get("sys.torch.rw_dev", value, "0");
std::string idStr = std::string(cameraId);
if (0 == strcmp(value, "1") && newStatus != TorchModeStatus::AVAILABLE_ON) {
if (idStr.compare("0") == 0) {
FILE *fp = NULL;
fp = fopen("/sys/class/leds/led:switch_0/brightness", "w");
fprintf(fp, "0");
fclose(fp);
}
}
// 原生的Torch回调事件,通知应用手电筒状态的
res = setTorchStatusLocked(cameraId, newStatus);
... ...
broadcastTorchModeStatus(cameraId, newStatus, systemCameraKind);
}开启关闭Camera执行如下函数
// closeCamera时会执行disconnect步骤
binder::Status CameraService::BasicClient::disconnect() {
binder::Status res = Status::ok();
if (mDisconnected) {
return res;
}
... ...
}
// openCamera时会执行connect步骤
template<class CALLBACK, class CLIENT>
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
int api1CameraId, int halVersion, const String16& clientPackageName,
const std::unique_ptr<String16>& clientFeatureId, int clientUid, int clientPid,
apiLevel effectiveApiLevel, bool shimUpdateOnly,
/*out*/sp<CLIENT>& device) {
binder::Status ret = binder::Status::ok();
String8 clientName8(clientPackageName);
... ...
}边栏推荐
- uniapp路由跳转的六种方式
- postgresql没有nvl的解决办法,postgresql查询所有的表
- The exclamation point of vscode +tab shortcut key cannot be used, and the solution to the problem of a-soul-live2d plug-in
- Common SQL of Oracle Report
- Smart headline: smart clothing forum will be held on August 4, and the whole house smart sales will exceed 10billion in 2022
- MySQL 常用命令
- Simulation of BOC modulation signal acquisition based on MATLAB
- Live classroom system 01 database table design
- 精品国创《少年歌行》数字藏品开售,邀你共铸少年武侠江湖梦
- VSCode 更新后与tab相关快捷键无法使用
猜你喜欢
随机推荐
【启发式分治】启发式合并的逆思想
Xlswriter - Excel export
turbo编译码误码率性能matlab仿真
js判断元素是否到滚动到顶部
NVIDIA vid2vid论文复现
Force buckle monotone stack
Redis | 非常重要的中间件
581. Shortest unordered continuous subarray
VSCode的感叹号+tab的快捷键不能用,以及A-SOUL-live2d插件出问题的解决方法
leetcode: 17. 电话号码的字母组合
如何实现多个传感器与西门子PLC之间485无线通讯?
494. Objectives and
【机器学习基础】无监督学习(5)——生成模型
Live classroom system 01 database table design
Live classroom system 03 model class and entity
报错 | cannot read property ‘_normalized‘ of undefined
Smart headline: smart clothing forum will be held on August 4, and the whole house smart sales will exceed 10billion in 2022
百度工程师眼中的云原生可观测性追踪技术
开源四足机器人 附设计图及代码「建议收藏」
安全合理用电 收获清凉一“夏”









