当前位置:网站首页>Camera flashlight modification

Camera flashlight modification

2022-07-23 15:21:00 Insect master Kuiba

Document content : Modify native interface , Replace the native call with a node controlled way hal Layer interface .

One 、 Application settings API

Application set flashlight code , Call the system interface  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);
            }
        }
    }

here CameraManager The call will go directly to  libcameraservice Of CameraService.cpp in , This is different from general XXXManager Such implementation code is  framework in services.jar In the module .

Two 、 The key function

CameraService.cpp  Execute several important functions in

setTorchMode Operate the flash

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  Write node open flashlight code block 
    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;
        }
        //  Inform the flashlight of the state change 
        for (auto& i : mListenerList) {
            i->getListener()->onTorchStatusChanged(serviceStatus, String16{cameraId});
        }
        return Status::ok();
    }
    //ADD
    ... ...

    //  Determine whether it is set as the system camera 
    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());
    }
    ... ...

    //  Native check Whether the flash is available 
    StatusInternal cameraStatus = state->getStatus();
    ... ...

    //  Native operation flash places 
    status_t err = mFlashlight->setTorchMode(id, enabled);
    ... ...
    return Status::ok();
}

 

onTorchStatusChangedLocked Flashlight status callback function

Even if the flashlight is operated in the way of writing nodes , On off camera This function will also be executed to notify the status

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;
    }

    //  Add judgment , For post shooting ( There is a flash in the back ) When open , Turn off the flashlight 
    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);
        }
    }

    //  Native Torch Callback events , Notify the application of flashlight status 
    res = setTorchStatusLocked(cameraId, newStatus);
    ... ...
    broadcastTorchModeStatus(cameraId, newStatus, systemCameraKind);
}

On off Camera Execute the following functions

// closeCamera Will be executed disconnect step 
binder::Status CameraService::BasicClient::disconnect() {
    binder::Status res = Status::ok();

    if (mDisconnected) {
        return res;
    }
    ... ...
}

// openCamera Will be executed connect step 
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);
    ... ...
}

原网站

版权声明
本文为[Insect master Kuiba]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/204/202207231042314714.html