Skip to content
  • Florian RICHER's avatar
    Flashlight : Use udev instead of hardcoded pinephone device file · 5c6a97ca
    Florian RICHER authored and Devin Lin's avatar Devin Lin committed
    # Goal of this patch
    
    Use udev to change or detect flash device instead of hardcoded pinephone device file.
    Inspired by phosh flash manager because it works in many devices. https://gitlab.gnome.org/World/Phosh/phosh/-/blob/main/src/torch-manager.c?ref_type=heads#L168-198
    
    # Remaining work
    
    - [x] Minimal project for testing
    - [x] Try to build for pmOS to test in my device (OP6)
    - [x] Need udev rules to work (Require write permission in brightness)
    
    # Stabilization
    
    - [x] read permission removed in max_brightness to check if no crash
    > "Failed to read max_brightness from udev device" in log
    - [x] read permission removed in brightness to check if no crash
    > "Failed to read brightness from udev device" in log
    - [x] "Break" match in my side to check if no crash occured when no device found
    > "No flashlight found" in log
    
    # Minimal project
    
    It run in my device perfectly, it find device, get current value and max value and toggle flashlight. It require **root** permissions to write in device file.
    
    ```cpp
    #include <iostream>
    #include <cstring>
    #include <libudev.h>
    
    #define TORCH_SUBSYSTEM "leds"
    
    int main() {
        struct udev* udev = udev_new();
        struct udev_enumerate* enumerate = udev_enumerate_new(udev);
    
        // Use to find all devices in subsystem "leds"
        // And use match sysname to filter only flash or torch
        // Example:
        //  - /sys/devices/platform/soc@0/c440000.spmi/spmi-0/0-03/c440000.spmi:pmic@3:led-controller@d300/leds/white:flash On OP6
        //  - /sys/devices/platform/soc@0/c440000.spmi/spmi-0/0-03/c440000.spmi:pmic@3:led-controller@d300/leds/yellow:flash On OP6
        //  - /sys/devices/platform/led-controller/leds/white:flash/brightness On pinephone
        udev_enumerate_add_match_subsystem(enumerate, TORCH_SUBSYSTEM);
        udev_enumerate_add_match_sysname(enumerate, "*:torch");
        udev_enumerate_add_match_sysname(enumerate, "*:flash");
        udev_enumerate_scan_devices(enumerate);
    
        struct udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate);
        struct udev_list_entry *entry = udev_list_entry_get_next(devices);
    
        if (entry == nullptr) {
            std::cout << "No flashlight found" << std::endl;
            return 1;
        }
    
        const char *path = udev_list_entry_get_name(entry);
        struct udev_device *torch = udev_device_new_from_syspath(udev, path);
    
        const char *max_brightness = udev_device_get_sysattr_value(torch, "max_brightness");
    
        const char *brightness = udev_device_get_sysattr_value(torch, "brightness");
    
        bool enabled = std::strcmp(brightness, "0") != 0;
        udev_device_set_sysattr_value(torch, "brightness", const_cast<char*>(enabled ? "0" : max_brightness));
    
        udev_device_unref(torch);
        udev_enumerate_unref(enumerate);
        udev_unref(udev);
        return 0;
    }
    ```
    
    Build with `g++ torch.cpp -ludev -o torch`
    Run with `sudo ./torch`
    
    # Important info
    
    - **udev** dependencies added
    - destructor for flashlightutil added to unref udev_device
    
    # Require udev rules
    
    Files `/etc/udev/rules.d/99-flashlight.rules`
    ```bash
    # Allow everyone to set brightness of flashlight (Required for plasma-mobile flashlightplugin)
    SUBSYSTEMS=="leds", KERNEL=="*:flash|*:torch", RUN+="/bin/chmod 666 %S%p/brightness"
    ```
    
    pmOS : See to add depends `eudev` and makedepends `eudev-dev`
    5c6a97ca