aidl: light: Refactor
Change-Id: Ib4ae8e9821dd0fb36e922e2c5f993aa6c0e28be1
This commit is contained in:
parent
d43b640a7b
commit
ee864f39ea
@ -1,18 +1,22 @@
|
||||
//
|
||||
// Copyright (C) 2021-2022 The LineageOS Project
|
||||
// Copyright (C) 2021-2024 The LineageOS Project
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
cc_binary {
|
||||
name: "android.hardware.light-service.xiaomi",
|
||||
defaults: ["hidl_defaults"],
|
||||
vendor: true,
|
||||
relative_install_path: "hw",
|
||||
init_rc: ["android.hardware.light-service.xiaomi.rc"],
|
||||
vintf_fragments: ["android.hardware.light-service.xiaomi.xml"],
|
||||
srcs: [
|
||||
"Backlight.cpp",
|
||||
"BacklightDevice.cpp",
|
||||
"Devices.cpp",
|
||||
"LedDevice.cpp",
|
||||
"Lights.cpp",
|
||||
"LED.cpp",
|
||||
"RgbLedDevice.cpp",
|
||||
"Utils.cpp",
|
||||
"service.cpp",
|
||||
],
|
||||
@ -21,5 +25,4 @@ cc_binary {
|
||||
"libbinder_ndk",
|
||||
"android.hardware.light-V2-ndk",
|
||||
],
|
||||
vendor: true,
|
||||
}
|
||||
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "Backlight.h"
|
||||
|
||||
#include "LED.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
class BacklightBrightness : public BacklightDevice {
|
||||
public:
|
||||
BacklightBrightness(std::string name) : mBasePath(mkBacklightBasePath + name + "/") {
|
||||
if (!readFromFile(mBasePath + "max_brightness", &mMaxBrightness)) {
|
||||
mMaxBrightness = kDefaultMaxBrightness;
|
||||
}
|
||||
};
|
||||
|
||||
void setBacklight(uint8_t value) {
|
||||
writeToFile(mBasePath + "brightness", value * mMaxBrightness / 0xFF);
|
||||
}
|
||||
|
||||
bool exists() { return fileWriteable(mBasePath + "brightness"); }
|
||||
|
||||
private:
|
||||
std::string mBasePath;
|
||||
uint32_t mMaxBrightness;
|
||||
|
||||
inline static const std::string mkBacklightBasePath = "/sys/class/backlight/";
|
||||
inline static const uint32_t kDefaultMaxBrightness = 255;
|
||||
};
|
||||
|
||||
class LEDBacklight : public BacklightDevice {
|
||||
public:
|
||||
LEDBacklight(std::string type) : mLED(type){};
|
||||
|
||||
void setBacklight(uint8_t value) { mLED.setBrightness(value); }
|
||||
|
||||
bool exists() { return mLED.exists(); }
|
||||
|
||||
private:
|
||||
LED mLED;
|
||||
};
|
||||
|
||||
static const std::string kBacklightDevices[] = {
|
||||
"backlight",
|
||||
"panel0-backlight",
|
||||
};
|
||||
|
||||
static const std::string kLedDevices[] = {
|
||||
"lcd-backlight",
|
||||
};
|
||||
|
||||
BacklightDevice* getBacklightDevice() {
|
||||
for (auto& device : kBacklightDevices) {
|
||||
auto backlight = new BacklightBrightness(device);
|
||||
if (backlight->exists()) {
|
||||
return backlight;
|
||||
}
|
||||
delete backlight;
|
||||
}
|
||||
|
||||
for (auto& device : kLedDevices) {
|
||||
auto backlight = new LEDBacklight(device);
|
||||
if (backlight->exists()) {
|
||||
return backlight;
|
||||
}
|
||||
delete backlight;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
class BacklightDevice {
|
||||
public:
|
||||
virtual ~BacklightDevice() = default;
|
||||
|
||||
virtual void setBacklight(uint8_t value) = 0;
|
||||
virtual bool exists() = 0;
|
||||
};
|
||||
|
||||
BacklightDevice* getBacklightDevice();
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
55
aidl/light/BacklightDevice.cpp
Normal file
55
aidl/light/BacklightDevice.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2022-2024 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "BacklightDevice.h"
|
||||
|
||||
#define LOG_TAG "BacklightDevice"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <fstream>
|
||||
#include "Utils.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
static const std::string kBacklightBasePath = "/sys/class/backlight/";
|
||||
static const uint32_t kDefaultMaxBrightness = 255;
|
||||
|
||||
static const std::string kBrightnessNode = "brightness";
|
||||
static const std::string kMaxBrightnessNode = "max_brightness";
|
||||
|
||||
BacklightDevice::BacklightDevice(std::string name)
|
||||
: mName(name), mBasePath(kBacklightBasePath + name + "/") {
|
||||
if (!readFromFile(mBasePath + kMaxBrightnessNode, mMaxBrightness)) {
|
||||
mMaxBrightness = kDefaultMaxBrightness;
|
||||
}
|
||||
};
|
||||
|
||||
std::string BacklightDevice::getName() const {
|
||||
return mName;
|
||||
}
|
||||
|
||||
bool BacklightDevice::exists() const {
|
||||
return std::ifstream(mBasePath + kBrightnessNode).good();
|
||||
}
|
||||
|
||||
bool BacklightDevice::setBrightness(uint8_t value) {
|
||||
return writeToFile(mBasePath + kBrightnessNode, scaleBrightness(value, mMaxBrightness));
|
||||
}
|
||||
|
||||
void BacklightDevice::dump(int fd) const {
|
||||
dprintf(fd, "Name: %s", mName.c_str());
|
||||
dprintf(fd, ", exists: %d", exists());
|
||||
dprintf(fd, ", base path: %s", mBasePath.c_str());
|
||||
dprintf(fd, ", max brightness: %u", mMaxBrightness);
|
||||
}
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
66
aidl/light/BacklightDevice.h
Normal file
66
aidl/light/BacklightDevice.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2022-2024 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include "IDumpable.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
/**
|
||||
* A Linux backlight device.
|
||||
* @see https://www.kernel.org/doc/Documentation/ABI/stable/sysfs-class-backlight
|
||||
*/
|
||||
class BacklightDevice : public IDumpable {
|
||||
public:
|
||||
BacklightDevice() = delete;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param name The name of the backlight device
|
||||
*/
|
||||
BacklightDevice(std::string name);
|
||||
|
||||
/**
|
||||
* Get the name of the backlight device.
|
||||
*
|
||||
* @return std::string The name of the backlight device
|
||||
*/
|
||||
std::string getName() const;
|
||||
|
||||
/**
|
||||
* Return whether this backlight device exists.
|
||||
*
|
||||
* @return bool true if the backlight device exists, false otherwise
|
||||
*/
|
||||
bool exists() const;
|
||||
|
||||
/**
|
||||
* Set the brightness of this backlight device.
|
||||
*
|
||||
* @param value The brightness value to set
|
||||
* @return bool true if the brightness was set successfully, false otherwise
|
||||
*/
|
||||
bool setBrightness(uint8_t value);
|
||||
|
||||
void dump(int fd) const override;
|
||||
|
||||
private:
|
||||
std::string mName;
|
||||
std::string mBasePath;
|
||||
uint32_t mMaxBrightness;
|
||||
};
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
217
aidl/light/Devices.cpp
Normal file
217
aidl/light/Devices.cpp
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "Devices.h"
|
||||
|
||||
#define LOG_TAG "Devices"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
static const std::string kBacklightDevices[] = {
|
||||
"backlight",
|
||||
"panel0-backlight",
|
||||
};
|
||||
|
||||
static std::vector<BacklightDevice> getBacklightDevices() {
|
||||
std::vector<BacklightDevice> devices;
|
||||
|
||||
for (const auto& device : kBacklightDevices) {
|
||||
BacklightDevice backlight(device);
|
||||
if (backlight.exists()) {
|
||||
LOG(INFO) << "Found backlight device: " << backlight.getName();
|
||||
devices.push_back(backlight);
|
||||
}
|
||||
}
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
static const std::string kLedBacklightDevices[] = {
|
||||
"lcd-backlight",
|
||||
};
|
||||
|
||||
static std::vector<LedDevice> getBacklightLedDevices() {
|
||||
std::vector<LedDevice> devices;
|
||||
|
||||
for (const auto& device : kLedBacklightDevices) {
|
||||
LedDevice backlight(device);
|
||||
if (backlight.exists()) {
|
||||
LOG(INFO) << "Found backlight LED device: " << backlight.getName();
|
||||
devices.push_back(backlight);
|
||||
}
|
||||
}
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
static const std::string kButtonLedDevices[] = {
|
||||
"button-backlight",
|
||||
"button-backlight1",
|
||||
};
|
||||
|
||||
static std::vector<LedDevice> getButtonLedDevices() {
|
||||
std::vector<LedDevice> devices;
|
||||
|
||||
for (const auto& device : kButtonLedDevices) {
|
||||
LedDevice button(device);
|
||||
if (button.exists()) {
|
||||
LOG(INFO) << "Found button LED device: " << button.getName();
|
||||
devices.emplace_back(button);
|
||||
}
|
||||
}
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
static const std::string kRgbLedDevices[][3] = {
|
||||
{"red", "green", "blue"},
|
||||
};
|
||||
|
||||
static std::vector<RgbLedDevice> getNotificationRgbLedDevices() {
|
||||
std::vector<RgbLedDevice> devices;
|
||||
|
||||
for (const auto& device : kRgbLedDevices) {
|
||||
LedDevice red(device[0]);
|
||||
LedDevice green(device[1]);
|
||||
LedDevice blue(device[2]);
|
||||
|
||||
RgbLedDevice rgbLedDevice(red, green, blue);
|
||||
if (rgbLedDevice.exists()) {
|
||||
LOG(INFO) << "Found notification RGB LED device: " << red.getName() << ", "
|
||||
<< green.getName() << ", " << blue.getName();
|
||||
devices.emplace_back(red, green, blue);
|
||||
}
|
||||
}
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
static const std::string kNotificationLedDevices[] = {
|
||||
"white",
|
||||
};
|
||||
|
||||
static std::vector<LedDevice> getNotificationLedDevices() {
|
||||
std::vector<LedDevice> devices;
|
||||
|
||||
for (const auto& device : kNotificationLedDevices) {
|
||||
LedDevice notification(device);
|
||||
if (notification.exists()) {
|
||||
LOG(INFO) << "Found notification LED device: " << notification.getName();
|
||||
devices.emplace_back(notification);
|
||||
}
|
||||
}
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
Devices::Devices()
|
||||
: mBacklightDevices(getBacklightDevices()),
|
||||
mBacklightLedDevices(getBacklightLedDevices()),
|
||||
mButtonLedDevices(getButtonLedDevices()),
|
||||
mNotificationRgbLedDevices(getNotificationRgbLedDevices()),
|
||||
mNotificationLedDevices(getNotificationLedDevices()) {
|
||||
if (!hasBacklightDevices()) {
|
||||
LOG(INFO) << "No backlight devices found";
|
||||
}
|
||||
|
||||
if (!hasButtonDevices()) {
|
||||
LOG(INFO) << "No button devices found";
|
||||
}
|
||||
|
||||
if (!hasNotificationDevices()) {
|
||||
LOG(INFO) << "No notification devices found";
|
||||
}
|
||||
}
|
||||
|
||||
bool Devices::hasBacklightDevices() const {
|
||||
return !mBacklightDevices.empty() || !mBacklightLedDevices.empty();
|
||||
}
|
||||
|
||||
bool Devices::hasButtonDevices() const {
|
||||
return !mButtonLedDevices.empty();
|
||||
}
|
||||
|
||||
bool Devices::hasNotificationDevices() const {
|
||||
return !mNotificationRgbLedDevices.empty() || !mNotificationLedDevices.empty();
|
||||
}
|
||||
|
||||
void Devices::setBacklightColor(rgb color) {
|
||||
for (auto& device : mBacklightDevices) {
|
||||
device.setBrightness(color.toBrightness());
|
||||
}
|
||||
for (auto& device : mBacklightLedDevices) {
|
||||
device.setBrightness(color.toBrightness());
|
||||
}
|
||||
}
|
||||
|
||||
void Devices::setButtonsColor(rgb color) {
|
||||
for (auto& device : mButtonLedDevices) {
|
||||
device.setBrightness(color.toBrightness());
|
||||
}
|
||||
}
|
||||
|
||||
void Devices::setNotificationColor(rgb color, LightMode mode) {
|
||||
for (auto& device : mNotificationRgbLedDevices) {
|
||||
device.setBrightness(color, mode);
|
||||
}
|
||||
|
||||
for (auto& device : mNotificationLedDevices) {
|
||||
device.setBrightness(color.toBrightness(), mode);
|
||||
}
|
||||
}
|
||||
|
||||
void Devices::dump(int fd) const {
|
||||
dprintf(fd, "Backlight devices:\n");
|
||||
for (const auto& device : mBacklightDevices) {
|
||||
dprintf(fd, "- ");
|
||||
device.dump(fd);
|
||||
dprintf(fd, "\n");
|
||||
}
|
||||
dprintf(fd, "\n");
|
||||
|
||||
dprintf(fd, "Backlight LED devices:\n");
|
||||
for (const auto& device : mBacklightLedDevices) {
|
||||
dprintf(fd, "- ");
|
||||
device.dump(fd);
|
||||
dprintf(fd, "\n");
|
||||
}
|
||||
dprintf(fd, "\n");
|
||||
|
||||
dprintf(fd, "Button LED devices:\n");
|
||||
for (const auto& device : mButtonLedDevices) {
|
||||
dprintf(fd, "- ");
|
||||
device.dump(fd);
|
||||
dprintf(fd, "\n");
|
||||
}
|
||||
dprintf(fd, "\n");
|
||||
|
||||
dprintf(fd, "Notification RGB LED devices:\n");
|
||||
for (const auto& device : mNotificationRgbLedDevices) {
|
||||
dprintf(fd, "- ");
|
||||
device.dump(fd);
|
||||
dprintf(fd, "\n");
|
||||
}
|
||||
dprintf(fd, "\n");
|
||||
|
||||
dprintf(fd, "Notification LED devices:\n");
|
||||
for (const auto& device : mNotificationLedDevices) {
|
||||
dprintf(fd, "- ");
|
||||
device.dump(fd);
|
||||
dprintf(fd, "\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
51
aidl/light/Devices.h
Normal file
51
aidl/light/Devices.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "BacklightDevice.h"
|
||||
#include "IDumpable.h"
|
||||
#include "LedDevice.h"
|
||||
#include "RgbLedDevice.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
class Devices : public IDumpable {
|
||||
public:
|
||||
Devices();
|
||||
|
||||
bool hasBacklightDevices() const;
|
||||
bool hasButtonDevices() const;
|
||||
bool hasNotificationDevices() const;
|
||||
|
||||
void setBacklightColor(rgb color);
|
||||
void setButtonsColor(rgb color);
|
||||
void setNotificationColor(rgb color, LightMode mode = LightMode::STATIC);
|
||||
|
||||
void dump(int fd) const override;
|
||||
|
||||
private:
|
||||
// Backlight
|
||||
std::vector<BacklightDevice> mBacklightDevices;
|
||||
std::vector<LedDevice> mBacklightLedDevices;
|
||||
|
||||
// Buttons
|
||||
std::vector<LedDevice> mButtonLedDevices;
|
||||
|
||||
// Notifications
|
||||
std::vector<RgbLedDevice> mNotificationRgbLedDevices;
|
||||
std::vector<LedDevice> mNotificationLedDevices;
|
||||
};
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
32
aidl/light/IDumpable.h
Normal file
32
aidl/light/IDumpable.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
/**
|
||||
* Interface for dumpable objects using AIDL dump()'s file descriptor.
|
||||
*/
|
||||
class IDumpable {
|
||||
public:
|
||||
virtual ~IDumpable() = default;
|
||||
|
||||
/**
|
||||
* Write information regarding this object to the given file descriptor using dprintf().
|
||||
* You should avoid ending newline, since the caller will add it.
|
||||
* @param fd The file descriptor to write to.
|
||||
*/
|
||||
virtual void dump(int fd) const = 0;
|
||||
};
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2022 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "LED.h"
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
static const uint32_t kDefaultMaxLedBrightness = 255;
|
||||
|
||||
LED::LED(std::string type) : mBasePath("/sys/class/leds/" + type + "/") {
|
||||
if (!readFromFile(mBasePath + "max_brightness", &mMaxBrightness))
|
||||
mMaxBrightness = kDefaultMaxLedBrightness;
|
||||
mBreath = fileWriteable(mBasePath + "breath");
|
||||
}
|
||||
|
||||
bool LED::exists() {
|
||||
return fileWriteable(mBasePath + "brightness");
|
||||
}
|
||||
|
||||
bool LED::setBreath(uint8_t value) {
|
||||
return writeToFile(mBasePath + (mBreath ? "breath" : "blink"), value);
|
||||
}
|
||||
|
||||
bool LED::setBrightness(uint8_t value) {
|
||||
return writeToFile(mBasePath + "brightness", value * mMaxBrightness / 0xFF);
|
||||
}
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2022 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
class LED {
|
||||
public:
|
||||
LED(std::string type);
|
||||
|
||||
bool exists();
|
||||
bool setBreath(uint8_t value);
|
||||
bool setBrightness(uint8_t value);
|
||||
|
||||
private:
|
||||
std::string mBasePath;
|
||||
uint32_t mMaxBrightness;
|
||||
bool mBreath;
|
||||
};
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
94
aidl/light/LedDevice.cpp
Normal file
94
aidl/light/LedDevice.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2024 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "LedDevice.h"
|
||||
|
||||
#define LOG_TAG "LedDevice"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <fstream>
|
||||
#include "Utils.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
static const uint32_t kDefaultMaxBrightness = 255;
|
||||
|
||||
static const std::string kBaseLedsPath = "/sys/class/leds/";
|
||||
|
||||
static const std::string kBrightnessNode = "brightness";
|
||||
static const std::string kMaxBrightnessNode = "max_brightness";
|
||||
|
||||
static const std::string kBreathNodes[] = {
|
||||
"breath",
|
||||
"blink",
|
||||
};
|
||||
|
||||
LedDevice::LedDevice(std::string name) : mName(name), mBasePath(kBaseLedsPath + name + "/") {
|
||||
if (!readFromFile(mBasePath + kMaxBrightnessNode, mMaxBrightness)) {
|
||||
mMaxBrightness = kDefaultMaxBrightness;
|
||||
}
|
||||
|
||||
for (const auto& node : kBreathNodes) {
|
||||
if (std::ifstream(mBasePath + node).good()) {
|
||||
mBreathNode = node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string LedDevice::getName() const {
|
||||
return mName;
|
||||
}
|
||||
|
||||
bool LedDevice::supportsBreath() const {
|
||||
return !mBreathNode.empty();
|
||||
}
|
||||
|
||||
bool LedDevice::exists() const {
|
||||
return std::ifstream(mBasePath + kBrightnessNode).good();
|
||||
}
|
||||
|
||||
bool LedDevice::setBrightness(uint8_t value, LightMode mode) {
|
||||
// Disable current blinking
|
||||
if (supportsBreath()) {
|
||||
writeToFile(mBasePath + mBreathNode, 0);
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case LightMode::BREATH:
|
||||
if (supportsBreath()) {
|
||||
return writeToFile(mBasePath + mBreathNode, value > 0 ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
|
||||
// Fallthrough to static mode if breath is not supported
|
||||
FALLTHROUGH_INTENDED;
|
||||
case LightMode::STATIC:
|
||||
return writeToFile(mBasePath + kBrightnessNode, scaleBrightness(value, mMaxBrightness));
|
||||
break;
|
||||
default:
|
||||
LOG(ERROR) << "Unknown mode: " << mode;
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LedDevice::dump(int fd) const {
|
||||
dprintf(fd, "Name: %s", mName.c_str());
|
||||
dprintf(fd, ", exists: %d", exists());
|
||||
dprintf(fd, ", base path: %s", mBasePath.c_str());
|
||||
dprintf(fd, ", max brightness: %u", mMaxBrightness);
|
||||
dprintf(fd, ", supports breath: %d", supportsBreath());
|
||||
dprintf(fd, ", breath node: %s", mBreathNode.c_str());
|
||||
}
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
82
aidl/light/LedDevice.h
Normal file
82
aidl/light/LedDevice.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2024 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include "IDumpable.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
enum LightMode {
|
||||
STATIC,
|
||||
BREATH,
|
||||
};
|
||||
|
||||
/**
|
||||
* A Linux LED device.
|
||||
* @see https://docs.kernel.org/leds/leds-class.html
|
||||
*/
|
||||
class LedDevice : public IDumpable {
|
||||
public:
|
||||
LedDevice() = delete;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param name The name of the LED device
|
||||
*/
|
||||
LedDevice(std::string name);
|
||||
|
||||
/**
|
||||
* Get the name of the LED device.
|
||||
*
|
||||
* @return std::string The name of the LED device
|
||||
*/
|
||||
std::string getName() const;
|
||||
|
||||
/**
|
||||
* Return whether this LED device exists.
|
||||
*
|
||||
* @return bool true if the LED device exists, false otherwise
|
||||
*/
|
||||
bool exists() const;
|
||||
|
||||
/**
|
||||
* Return whether this LED device supports breathing.
|
||||
* When it doesn't, calling setBrightness with LightMode::BREATH will behave like
|
||||
* LightMode::STATIC.
|
||||
*
|
||||
* @return bool true if the LED device supports breathing, false otherwise
|
||||
*/
|
||||
bool supportsBreath() const;
|
||||
|
||||
/**
|
||||
* Set the brightness of the LED device.
|
||||
*
|
||||
* @param value The brightness value to set
|
||||
* @param mode The light mode to use
|
||||
* @return bool true if the brightness was set successfully, false otherwise
|
||||
*/
|
||||
bool setBrightness(uint8_t value, LightMode mode = LightMode::STATIC);
|
||||
|
||||
void dump(int fd) const override;
|
||||
|
||||
private:
|
||||
std::string mName;
|
||||
std::string mBasePath;
|
||||
uint32_t mMaxBrightness;
|
||||
std::string mBreathNode;
|
||||
};
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
@ -1,13 +1,14 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2022 The LineageOS Project
|
||||
* Copyright (C) 2021-2024 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "Lights.h"
|
||||
|
||||
#define LOG_TAG "Lights"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include "LED.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace aidl {
|
||||
@ -15,48 +16,23 @@ namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
static const std::string kAllButtonsPaths[] = {
|
||||
"/sys/class/leds/button-backlight/brightness",
|
||||
"/sys/class/leds/button-backlight1/brightness",
|
||||
};
|
||||
|
||||
enum led_type {
|
||||
RED,
|
||||
GREEN,
|
||||
BLUE,
|
||||
WHITE,
|
||||
MAX_LEDS,
|
||||
};
|
||||
|
||||
static LED kLEDs[MAX_LEDS] = {
|
||||
[RED] = LED("red"),
|
||||
[GREEN] = LED("green"),
|
||||
[BLUE] = LED("blue"),
|
||||
[WHITE] = LED("white"),
|
||||
};
|
||||
|
||||
#define AutoHwLight(light) \
|
||||
{ .id = (int32_t)light, .type = light, .ordinal = 0 }
|
||||
{ .id = static_cast<int32_t>(light), .ordinal = 0, .type = light }
|
||||
|
||||
Lights::Lights() {
|
||||
mBacklightDevice = getBacklightDevice();
|
||||
if (mBacklightDevice) {
|
||||
if (mDevices.hasBacklightDevices()) {
|
||||
mLights.push_back(AutoHwLight(LightType::BACKLIGHT));
|
||||
}
|
||||
|
||||
for (auto& buttons : kAllButtonsPaths) {
|
||||
if (!fileWriteable(buttons)) continue;
|
||||
|
||||
mButtonsPaths.push_back(buttons);
|
||||
if (mDevices.hasButtonDevices()) {
|
||||
mLights.push_back(AutoHwLight(LightType::BUTTONS));
|
||||
}
|
||||
|
||||
if (!mButtonsPaths.empty()) mLights.push_back(AutoHwLight(LightType::BUTTONS));
|
||||
|
||||
mWhiteLED = kLEDs[WHITE].exists();
|
||||
|
||||
mLights.push_back(AutoHwLight(LightType::BATTERY));
|
||||
mLights.push_back(AutoHwLight(LightType::NOTIFICATIONS));
|
||||
mLights.push_back(AutoHwLight(LightType::ATTENTION));
|
||||
if (mDevices.hasNotificationDevices()) {
|
||||
mLights.push_back(AutoHwLight(LightType::BATTERY));
|
||||
mLights.push_back(AutoHwLight(LightType::NOTIFICATIONS));
|
||||
mLights.push_back(AutoHwLight(LightType::ATTENTION));
|
||||
}
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Lights::setLightState(int32_t id, const HwLightState& state) {
|
||||
@ -65,27 +41,22 @@ ndk::ScopedAStatus Lights::setLightState(int32_t id, const HwLightState& state)
|
||||
LightType type = static_cast<LightType>(id);
|
||||
switch (type) {
|
||||
case LightType::BACKLIGHT:
|
||||
if (mBacklightDevice) mBacklightDevice->setBacklight(color.toBrightness());
|
||||
mDevices.setBacklightColor(color);
|
||||
break;
|
||||
case LightType::BUTTONS:
|
||||
for (auto& buttons : mButtonsPaths) writeToFile(buttons, color.isLit());
|
||||
mDevices.setButtonsColor(color);
|
||||
break;
|
||||
case LightType::BATTERY:
|
||||
mLastBatteryState = state;
|
||||
updateNotificationColor();
|
||||
break;
|
||||
case LightType::NOTIFICATIONS:
|
||||
mLastNotificationsState = state;
|
||||
updateNotificationColor();
|
||||
break;
|
||||
case LightType::ATTENTION:
|
||||
mLEDMutex.lock();
|
||||
|
||||
if (type == LightType::BATTERY)
|
||||
mLastBatteryState = state;
|
||||
else if (type == LightType::NOTIFICATIONS)
|
||||
mLastNotificationState = state;
|
||||
else if (type == LightType::ATTENTION)
|
||||
mLastAttentionState = state;
|
||||
|
||||
setLED();
|
||||
|
||||
mLEDMutex.unlock();
|
||||
|
||||
mLastAttentionState = state;
|
||||
updateNotificationColor();
|
||||
break;
|
||||
default:
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
@ -96,47 +67,59 @@ ndk::ScopedAStatus Lights::setLightState(int32_t id, const HwLightState& state)
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Lights::getLights(std::vector<HwLight>* _aidl_return) {
|
||||
for (const auto& light : mLights) _aidl_return->push_back(light);
|
||||
for (const auto& light : mLights) {
|
||||
_aidl_return->push_back(light);
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
void Lights::setLED() {
|
||||
bool rc = true;
|
||||
binder_status_t Lights::dump(int fd, const char** /*args*/, uint32_t /*numArgs*/) {
|
||||
dprintf(fd, "Lights AIDL:\n");
|
||||
dprintf(fd, "\n");
|
||||
|
||||
dprintf(fd, "Lights:\n");
|
||||
for (const auto& light : mLights) {
|
||||
dprintf(fd, "- %d: LightType::%s\n", light.id, toString(light.type).c_str());
|
||||
}
|
||||
dprintf(fd, "\n");
|
||||
|
||||
dprintf(fd, "Devices:\n");
|
||||
mDevices.dump(fd);
|
||||
dprintf(fd, "\n");
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
void Lights::updateNotificationColor() {
|
||||
std::lock_guard<std::mutex> lock(mLedMutex);
|
||||
|
||||
bool isBatteryLit = rgb(mLastBatteryState.color).isLit();
|
||||
bool isAttentionLit = rgb(mLastAttentionState.color).isLit();
|
||||
|
||||
const HwLightState state = isBatteryLit ? mLastBatteryState
|
||||
: isAttentionLit ? mLastAttentionState
|
||||
: mLastNotificationState;
|
||||
: mLastNotificationsState;
|
||||
|
||||
rgb color(state.color);
|
||||
uint8_t blink = (state.flashOnMs != 0 && state.flashOffMs != 0);
|
||||
|
||||
LightMode lightMode;
|
||||
switch (state.flashMode) {
|
||||
case FlashMode::HARDWARE:
|
||||
case FlashMode::NONE:
|
||||
lightMode = LightMode::STATIC;
|
||||
break;
|
||||
case FlashMode::TIMED:
|
||||
if (mWhiteLED) {
|
||||
rc = kLEDs[WHITE].setBreath(blink);
|
||||
} else {
|
||||
rc = kLEDs[RED].setBreath(blink && color.red);
|
||||
rc &= kLEDs[GREEN].setBreath(blink && color.green);
|
||||
rc &= kLEDs[BLUE].setBreath(blink && color.blue);
|
||||
}
|
||||
if (rc) break;
|
||||
FALLTHROUGH_INTENDED;
|
||||
case FlashMode::HARDWARE:
|
||||
lightMode = LightMode::BREATH;
|
||||
break;
|
||||
default:
|
||||
if (mWhiteLED) {
|
||||
rc = kLEDs[WHITE].setBrightness(color.toBrightness());
|
||||
} else {
|
||||
rc = kLEDs[RED].setBrightness(color.red);
|
||||
rc &= kLEDs[GREEN].setBrightness(color.green);
|
||||
rc &= kLEDs[BLUE].setBrightness(color.blue);
|
||||
}
|
||||
LOG(ERROR) << "Unknown flash mode: " << static_cast<int>(state.flashMode);
|
||||
lightMode = LightMode::STATIC;
|
||||
break;
|
||||
}
|
||||
|
||||
mDevices.setNotificationColor(color, lightMode);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2022 The LineageOS Project
|
||||
* Copyright (C) 2021-2024 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -8,10 +8,7 @@
|
||||
|
||||
#include <aidl/android/hardware/light/BnLights.h>
|
||||
#include <mutex>
|
||||
#include "Backlight.h"
|
||||
|
||||
using ::aidl::android::hardware::light::HwLight;
|
||||
using ::aidl::android::hardware::light::HwLightState;
|
||||
#include "Devices.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
@ -25,20 +22,19 @@ class Lights : public BnLights {
|
||||
ndk::ScopedAStatus setLightState(int32_t id, const HwLightState& state) override;
|
||||
ndk::ScopedAStatus getLights(std::vector<HwLight>* _aidl_return) override;
|
||||
|
||||
private:
|
||||
void setLED();
|
||||
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
|
||||
|
||||
private:
|
||||
std::vector<HwLight> mLights;
|
||||
|
||||
BacklightDevice* mBacklightDevice;
|
||||
std::vector<std::string> mButtonsPaths;
|
||||
bool mWhiteLED;
|
||||
|
||||
std::mutex mLEDMutex;
|
||||
Devices mDevices;
|
||||
|
||||
HwLightState mLastBatteryState;
|
||||
HwLightState mLastNotificationState;
|
||||
HwLightState mLastNotificationsState;
|
||||
HwLightState mLastAttentionState;
|
||||
std::mutex mLedMutex;
|
||||
|
||||
void updateNotificationColor();
|
||||
};
|
||||
|
||||
} // namespace light
|
||||
|
109
aidl/light/RgbLedDevice.cpp
Normal file
109
aidl/light/RgbLedDevice.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "RgbLedDevice.h"
|
||||
|
||||
#define LOG_TAG "RgbLedDevice"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
RgbLedDevice::RgbLedDevice(LedDevice red, LedDevice green, LedDevice blue)
|
||||
: mRed(red), mGreen(green), mBlue(blue), mColors(Color::NONE) {
|
||||
if (mRed.exists()) {
|
||||
mColors |= Color::RED;
|
||||
}
|
||||
if (mGreen.exists()) {
|
||||
mColors |= Color::GREEN;
|
||||
}
|
||||
if (mBlue.exists()) {
|
||||
mColors |= Color::BLUE;
|
||||
}
|
||||
}
|
||||
|
||||
bool RgbLedDevice::exists() const {
|
||||
return mColors != Color::NONE;
|
||||
}
|
||||
|
||||
bool RgbLedDevice::supportsBreath() const {
|
||||
return (!mRed.exists() || mRed.supportsBreath()) &&
|
||||
(!mGreen.exists() || mGreen.supportsBreath()) &&
|
||||
(!mBlue.exists() || mBlue.supportsBreath());
|
||||
}
|
||||
|
||||
bool RgbLedDevice::setBrightness(rgb color, LightMode mode) {
|
||||
bool rc = true;
|
||||
|
||||
if (mColors == Color::NONE) {
|
||||
LOG(ERROR) << "No LEDs found";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mode == LightMode::BREATH && !supportsBreath()) {
|
||||
// Not all LEDs support breathing, force static mode
|
||||
mode = LightMode::STATIC;
|
||||
}
|
||||
|
||||
if (mColors == Color::ALL) {
|
||||
rc &= mRed.setBrightness(color.red, mode);
|
||||
rc &= mGreen.setBrightness(color.green, mode);
|
||||
rc &= mBlue.setBrightness(color.blue, mode);
|
||||
} else {
|
||||
// Check if we have only one LED
|
||||
if (mColors == Color::RED) {
|
||||
rc &= mRed.setBrightness(color.toBrightness(), mode);
|
||||
} else if (mColors == Color::GREEN) {
|
||||
rc &= mGreen.setBrightness(color.toBrightness(), mode);
|
||||
} else if (mColors == Color::BLUE) {
|
||||
rc &= mBlue.setBrightness(color.toBrightness(), mode);
|
||||
} else {
|
||||
// We only have two LEDs, blend the missing color in the other two
|
||||
if ((mColors & Color::RED) == Color::NONE) {
|
||||
rc &= mBlue.setBrightness((color.blue + color.red) / 2, mode);
|
||||
rc &= mGreen.setBrightness((color.green + color.red) / 2, mode);
|
||||
} else if ((mColors & Color::GREEN) == Color::NONE) {
|
||||
rc &= mRed.setBrightness((color.red + color.green) / 2, mode);
|
||||
rc &= mBlue.setBrightness((color.blue + color.green) / 2, mode);
|
||||
} else if ((mColors & Color::BLUE) == Color::NONE) {
|
||||
rc &= mRed.setBrightness((color.red + color.blue) / 2, mode);
|
||||
rc &= mGreen.setBrightness((color.green + color.blue) / 2, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void RgbLedDevice::dump(int fd) const {
|
||||
dprintf(fd, "Exists: %d", exists());
|
||||
dprintf(fd, ", supports breath: %d", supportsBreath());
|
||||
dprintf(fd, ", colors:");
|
||||
if (mColors != Color::NONE) {
|
||||
if (mColors & Color::RED) {
|
||||
dprintf(fd, "\nRed: ");
|
||||
mRed.dump(fd);
|
||||
}
|
||||
if (mColors & Color::GREEN) {
|
||||
dprintf(fd, "\nGreen: ");
|
||||
mGreen.dump(fd);
|
||||
}
|
||||
if (mColors & Color::BLUE) {
|
||||
dprintf(fd, "\nBlue: ");
|
||||
mBlue.dump(fd);
|
||||
}
|
||||
} else {
|
||||
dprintf(fd, " None");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
84
aidl/light/RgbLedDevice.h
Normal file
84
aidl/light/RgbLedDevice.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IDumpable.h"
|
||||
#include "LedDevice.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
/**
|
||||
* A pool of LED devices that will be toggled based on the wanted color.
|
||||
* Support all types of LED combinations, with a maximum of 3 LEDs.
|
||||
* Also supports 2 color LEDs (*cough* ASUS *cough*).
|
||||
*/
|
||||
class RgbLedDevice : public IDumpable {
|
||||
public:
|
||||
RgbLedDevice() = delete;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param red The red LED device
|
||||
* @param green The green LED device
|
||||
* @param blue The blue LED device
|
||||
*/
|
||||
RgbLedDevice(LedDevice red, LedDevice green, LedDevice blue);
|
||||
|
||||
/**
|
||||
* Return whether this RGB LED device exists.
|
||||
* This is true when at least one of the LEDs exists.
|
||||
*
|
||||
* @return bool true if the RGB LED device exists, false otherwise
|
||||
*/
|
||||
bool exists() const;
|
||||
|
||||
/**
|
||||
* Return whether this RGB LED device supports breathing.
|
||||
* This is true when all existing LEDs support breathing.
|
||||
* In case this is false, calling setBrightness with LightMode::BREATH will behave like
|
||||
* LightMode::STATIC.
|
||||
*
|
||||
* @return bool true if the RGB LED device supports breathing, false otherwise
|
||||
*/
|
||||
bool supportsBreath() const;
|
||||
|
||||
/**
|
||||
* Set the brightness of this RGB LED device.
|
||||
*
|
||||
* @param color The color to set
|
||||
* @param mode The mode to set
|
||||
* @return bool true if the brightness was set successfully, false otherwise
|
||||
*/
|
||||
bool setBrightness(rgb color, LightMode mode = LightMode::STATIC);
|
||||
|
||||
void dump(int fd) const override;
|
||||
|
||||
enum Color {
|
||||
NONE = 0,
|
||||
RED = 1 << 0,
|
||||
GREEN = 1 << 1,
|
||||
BLUE = 1 << 2,
|
||||
ALL = RED | GREEN | BLUE,
|
||||
};
|
||||
|
||||
private:
|
||||
LedDevice mRed;
|
||||
LedDevice mGreen;
|
||||
LedDevice mBlue;
|
||||
|
||||
int mColors;
|
||||
};
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
@ -1,49 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2022 The LineageOS Project
|
||||
* Copyright (C) 2021-2024 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
#define LOG_TAG "android.hardware.light-service.xiaomi"
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <unistd.h>
|
||||
|
||||
using ::android::base::ReadFileToString;
|
||||
using ::android::base::WriteStringToFile;
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
bool fileWriteable(const std::string& file) {
|
||||
return !access(file.c_str(), W_OK);
|
||||
}
|
||||
rgb::rgb() : red(0), green(0), blue(0) {}
|
||||
|
||||
bool readFromFile(const std::string& file, std::string* content) {
|
||||
return ReadFileToString(file, content, true);
|
||||
}
|
||||
|
||||
bool readFromFile(const std::string& file, uint32_t* content) {
|
||||
std::string content_str;
|
||||
if (readFromFile(file, &content_str))
|
||||
*content = std::stoi(content_str);
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool writeToFile(const std::string& file, std::string content) {
|
||||
return WriteStringToFile(content, file);
|
||||
}
|
||||
|
||||
bool writeToFile(const std::string& file, uint32_t content) {
|
||||
return writeToFile(file, std::to_string(content));
|
||||
}
|
||||
rgb::rgb(uint8_t r, uint8_t g, uint8_t b) : red(r), green(g), blue(b){};
|
||||
|
||||
rgb::rgb(uint32_t color) {
|
||||
// Extract brightness from AARRGGBB.
|
||||
@ -55,7 +25,7 @@ rgb::rgb(uint32_t color) {
|
||||
blue = color & 0xFF;
|
||||
|
||||
// Scale RGB colors if a brightness has been applied by the user
|
||||
if (alpha > 0 && alpha < 255) {
|
||||
if (alpha > 0 && alpha < 0xFF) {
|
||||
red = red * alpha / 0xFF;
|
||||
green = green * alpha / 0xFF;
|
||||
blue = blue * alpha / 0xFF;
|
||||
@ -66,8 +36,16 @@ bool rgb::isLit() {
|
||||
return !!red || !!green || !!blue;
|
||||
}
|
||||
|
||||
static constexpr uint8_t kRedWeight = 77;
|
||||
static constexpr uint8_t kGreenWeight = 150;
|
||||
static constexpr uint8_t kBlueWeight = 29;
|
||||
|
||||
uint8_t rgb::toBrightness() {
|
||||
return (77 * red + 150 * green + 29 * blue) >> 8;
|
||||
return (kRedWeight * red + kGreenWeight * green + kBlueWeight * blue) >> 8;
|
||||
}
|
||||
|
||||
uint32_t scaleBrightness(uint8_t brightness, uint32_t maxBrightness) {
|
||||
return brightness * maxBrightness / 0xFF;
|
||||
}
|
||||
|
||||
} // namespace light
|
||||
|
@ -1,11 +1,13 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2022 The LineageOS Project
|
||||
* Copyright (C) 2021-2024 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
namespace aidl {
|
||||
@ -14,9 +16,9 @@ namespace hardware {
|
||||
namespace light {
|
||||
|
||||
struct rgb {
|
||||
rgb(uint8_t r, uint8_t g, uint8_t b) : red(r), green(g), blue(b){};
|
||||
rgb();
|
||||
rgb(uint8_t r, uint8_t g, uint8_t b);
|
||||
rgb(uint32_t color);
|
||||
rgb() : red(0), green(0), blue(0){};
|
||||
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
@ -26,10 +28,31 @@ struct rgb {
|
||||
uint8_t toBrightness();
|
||||
};
|
||||
|
||||
bool fileWriteable(const std::string& file);
|
||||
bool readFromFile(const std::string& file, std::string* content);
|
||||
bool readFromFile(const std::string& file, uint32_t* content);
|
||||
bool writeToFile(const std::string& file, uint32_t content);
|
||||
uint32_t scaleBrightness(uint8_t brightness, uint32_t maxBrightness);
|
||||
|
||||
template <typename T>
|
||||
bool readFromFile(const std::string& file, T& content) {
|
||||
std::ifstream fileStream(file);
|
||||
|
||||
if (!fileStream) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fileStream >> content;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool writeToFile(const std::string& file, const T content) {
|
||||
std::ofstream fileStream(file);
|
||||
|
||||
if (!fileStream) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fileStream << content;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
|
@ -1,38 +1,46 @@
|
||||
on early-boot
|
||||
# Notification LEDs
|
||||
chown system system /sys/class/leds/red/blink
|
||||
chown system system /sys/class/leds/red/breath
|
||||
chown system system /sys/class/leds/red/brightness
|
||||
chown system system /sys/class/leds/red/max_brightness
|
||||
|
||||
chown system system /sys/class/leds/green/blink
|
||||
chown system system /sys/class/leds/green/breath
|
||||
chown system system /sys/class/leds/green/brightness
|
||||
chown system system /sys/class/leds/green/max_brightness
|
||||
|
||||
chown system system /sys/class/leds/blue/blink
|
||||
chown system system /sys/class/leds/blue/breath
|
||||
chown system system /sys/class/leds/blue/brightness
|
||||
chown system system /sys/class/leds/blue/max_brightness
|
||||
|
||||
chown system system /sys/class/leds/white/blink
|
||||
chown system system /sys/class/leds/white/breath
|
||||
chown system system /sys/class/leds/white/brightness
|
||||
chown system system /sys/class/leds/white/max_brightness
|
||||
|
||||
# Backlight
|
||||
# Backlight devices
|
||||
chown system system /sys/class/backlight/backlight/brightness
|
||||
chown system system /sys/class/backlight/backlight/max_brightness
|
||||
|
||||
chown system system /sys/class/backlight/panel0-backlight/brightness
|
||||
chown system system /sys/class/backlight/panel0-backlight/max_brightness
|
||||
|
||||
# LED devices
|
||||
chown system system /sys/class/leds/blue/blink
|
||||
chown system system /sys/class/leds/blue/breath
|
||||
chown system system /sys/class/leds/blue/brightness
|
||||
chown system system /sys/class/leds/blue/max_brightness
|
||||
|
||||
chown system system /sys/class/leds/button-backlight/blink
|
||||
chown system system /sys/class/leds/button-backlight/breath
|
||||
chown system system /sys/class/leds/button-backlight/brightness
|
||||
chown system system /sys/class/leds/button-backlight/max_brightness
|
||||
|
||||
chown system system /sys/class/leds/button-backlight1/blink
|
||||
chown system system /sys/class/leds/button-backlight1/breath
|
||||
chown system system /sys/class/leds/button-backlight1/brightness
|
||||
chown system system /sys/class/leds/button-backlight1/max_brightness
|
||||
|
||||
chown system system /sys/class/leds/green/blink
|
||||
chown system system /sys/class/leds/green/breath
|
||||
chown system system /sys/class/leds/green/brightness
|
||||
chown system system /sys/class/leds/green/max_brightness
|
||||
|
||||
chown system system /sys/class/leds/lcd-backlight/blink
|
||||
chown system system /sys/class/leds/lcd-backlight/breath
|
||||
chown system system /sys/class/leds/lcd-backlight/brightness
|
||||
chown system system /sys/class/leds/lcd-backlight/max_brightness
|
||||
|
||||
# Buttons
|
||||
chown system system /sys/class/leds/button-backlight/brightness
|
||||
chown system system /sys/class/leds/button-backlight1/brightness
|
||||
chown system system /sys/class/leds/red/blink
|
||||
chown system system /sys/class/leds/red/breath
|
||||
chown system system /sys/class/leds/red/brightness
|
||||
chown system system /sys/class/leds/red/max_brightness
|
||||
|
||||
chown system system /sys/class/leds/white/blink
|
||||
chown system system /sys/class/leds/white/breath
|
||||
chown system system /sys/class/leds/white/brightness
|
||||
chown system system /sys/class/leds/white/max_brightness
|
||||
|
||||
service vendor.light-default /vendor/bin/hw/android.hardware.light-service.xiaomi
|
||||
class hal
|
||||
|
@ -1,11 +1,13 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The LineageOS Project
|
||||
* Copyright (C) 2021-2024 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "Lights.h"
|
||||
|
||||
#define LOG_TAG "android.hardware.light-service.xiaomi"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
|
Loading…
Reference in New Issue
Block a user