Warning, file /plasma/plasma-mobile/quicksettings/flashlight/flashlightutil.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * SPDX-FileCopyrightText: 2020 Han Young <hanyoung@protonmail.com> 0003 * SPDX-FileCopyrightText: 2022 by Devin Lin <devin@kde.org> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "flashlightutil.h" 0009 0010 #include <cstring> 0011 #include <fcntl.h> 0012 #include <libudev.h> 0013 #include <unistd.h> 0014 0015 #include <QDebug> 0016 #include <QFileInfo> 0017 0018 #define TORCH_SUBSYSTEM "leds" 0019 0020 FlashlightUtil::FlashlightUtil(QObject *parent) 0021 : QObject{parent} 0022 , m_device{nullptr} 0023 , m_isAvailable{false} 0024 { 0025 findTorchDevice(); 0026 } 0027 0028 FlashlightUtil::~FlashlightUtil() 0029 { 0030 if (m_device != nullptr) { 0031 udev_device_unref(m_device); 0032 } 0033 } 0034 0035 void FlashlightUtil::toggleTorch() 0036 { 0037 if (!isAvailable()) { 0038 qWarning() << "Flashlight not available"; 0039 return; 0040 } 0041 0042 int ret = udev_device_set_sysattr_value(m_device, "brightness", const_cast<char *>(m_torchEnabled ? "0" : m_maxBrightness)); 0043 if (ret < 0) { 0044 qWarning() << "Flashlight can't be toggled"; 0045 return; 0046 } 0047 0048 m_torchEnabled = !m_torchEnabled; 0049 Q_EMIT torchChanged(m_torchEnabled); 0050 } 0051 0052 bool FlashlightUtil::torchEnabled() const 0053 { 0054 return m_torchEnabled; 0055 } 0056 0057 bool FlashlightUtil::isAvailable() const 0058 { 0059 return m_isAvailable; 0060 } 0061 0062 void FlashlightUtil::findTorchDevice() 0063 { 0064 if (m_device != nullptr) { 0065 udev_device_unref(m_device); 0066 } 0067 m_device = nullptr; 0068 m_isAvailable = false; 0069 0070 struct udev *udev = udev_new(); 0071 struct udev_enumerate *enumerate = udev_enumerate_new(udev); 0072 0073 udev_enumerate_add_match_subsystem(enumerate, TORCH_SUBSYSTEM); 0074 udev_enumerate_add_match_sysname(enumerate, "*:torch"); 0075 udev_enumerate_add_match_sysname(enumerate, "*:flash"); 0076 udev_enumerate_scan_devices(enumerate); 0077 0078 struct udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate); 0079 struct udev_list_entry *entry = nullptr; 0080 0081 struct udev_device *device = nullptr; 0082 0083 udev_list_entry_foreach(entry, devices) 0084 { 0085 const char *path = udev_list_entry_get_name(entry); 0086 0087 if (path == nullptr) { 0088 continue; 0089 } 0090 0091 if (device != nullptr) { 0092 udev_device_unref(device); // Use to free memory from previous loop iteration 0093 } 0094 0095 device = udev_device_new_from_syspath(udev, path); 0096 0097 if (device == nullptr) { 0098 continue; 0099 } 0100 0101 qInfo() << "Found flashlight device : " << path; 0102 0103 const char *color = udev_device_get_sysattr_value(device, "color"); 0104 0105 if (color == nullptr) { 0106 continue; 0107 } 0108 0109 qInfo() << "Flash color : " << color; 0110 0111 if (std::strcmp(color, "white") == 0) { 0112 break; 0113 } 0114 } 0115 0116 if (device == nullptr) { 0117 qWarning() << "No flashlight device found"; 0118 return; 0119 } 0120 0121 const char *maxBrightness = udev_device_get_sysattr_value(device, "max_brightness"); 0122 0123 if (maxBrightness == nullptr) { 0124 qWarning() << "Failed to read max_brightness from udev device"; 0125 return; 0126 } 0127 0128 qInfo() << "Flash maxBrightness : " << maxBrightness; 0129 0130 const char *brightness = udev_device_get_sysattr_value(device, "brightness"); 0131 0132 if (brightness == nullptr) { 0133 qWarning() << "Failed to read brightness from udev device"; 0134 return; 0135 } 0136 0137 qInfo() << "Flash brightness : " << brightness; 0138 0139 m_maxBrightness = maxBrightness; 0140 m_device = device; 0141 m_isAvailable = true; 0142 m_torchEnabled = std::strcmp(brightness, "0") != 0; 0143 0144 udev_enumerate_unref(enumerate); 0145 udev_unref(udev); 0146 }