Skip to content

Flashlight : Use udev instead of hardcoded pinephone device file

Florian RICHER requested to merge florianricher/plasma-mobile:flashlight into master

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

  • Minimal project for testing
  • Try to build for pmOS to test in my device (OP6)
  • Need udev rules to work (Require write permission in brightness)

Stabilization

  • read permission removed in max_brightness to check if no crash

"Failed to read max_brightness from udev device" in log

  • read permission removed in brightness to check if no crash

"Failed to read brightness from udev device" in log

  • "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.

#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

# 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

Edited by Florian RICHER

Merge request reports

Loading