当前位置:网站首页>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);
    ... ...
}

原网站

版权声明
本文为[虫师魁拔]所创,转载请带上原文链接,感谢
https://blog.csdn.net/tq501501/article/details/125778309