Camera 手电筒修改
Posted 虫师魁拔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Camera 手电筒修改相关的知识,希望对你有一定的参考价值。
文档内容:修改原生接口,使用节点控制的方式替换原生调用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, String16cameraId);
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);
... ...
以上是关于Camera 手电筒修改的主要内容,如果未能解决你的问题,请参考以下文章
Android 2.1 的 Camera.Parameters.FLASH_MODE_TORCH 替代品