aidl: light: Add support for timed mode
Co-authored-by: Sebastiano Barezzi <seba@sebaubuntu.dev> Change-Id: I23623c7527cf98230f890935a4742f86adc3b3ea
This commit is contained in:
parent
ee864f39ea
commit
7329fd774f
@ -158,13 +158,14 @@ void Devices::setButtonsColor(rgb color) {
|
||||
}
|
||||
}
|
||||
|
||||
void Devices::setNotificationColor(rgb color, LightMode mode) {
|
||||
void Devices::setNotificationColor(rgb color, LightMode mode, uint32_t flashOnMs,
|
||||
uint32_t flashOffMs) {
|
||||
for (auto& device : mNotificationRgbLedDevices) {
|
||||
device.setBrightness(color, mode);
|
||||
device.setBrightness(color, mode, flashOnMs, flashOffMs);
|
||||
}
|
||||
|
||||
for (auto& device : mNotificationLedDevices) {
|
||||
device.setBrightness(color.toBrightness(), mode);
|
||||
device.setBrightness(color.toBrightness(), mode, flashOnMs, flashOffMs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,8 @@ class Devices : public IDumpable {
|
||||
|
||||
void setBacklightColor(rgb color);
|
||||
void setButtonsColor(rgb color);
|
||||
void setNotificationColor(rgb color, LightMode mode = LightMode::STATIC);
|
||||
void setNotificationColor(rgb color, LightMode mode = LightMode::STATIC, uint32_t flashOnMs = 0,
|
||||
uint32_t flashOffMs = 0);
|
||||
|
||||
void dump(int fd) const override;
|
||||
|
||||
|
@ -29,6 +29,16 @@ static const std::string kBreathNodes[] = {
|
||||
"blink",
|
||||
};
|
||||
|
||||
static const std::string kBlinkNode = "blink";
|
||||
static const std::string kStartIdxNode = "start_idx";
|
||||
static const std::string kDutyPctsNode = "duty_pcts";
|
||||
static const std::string kPauseLoNode = "pause_lo";
|
||||
static const std::string kPauseHiNode = "pause_hi";
|
||||
static const std::string kRampStepMsNode = "ramp_step_ms";
|
||||
|
||||
static constexpr int kRampSteps = 8;
|
||||
static constexpr int kRampMaxStepDurationMs = 50;
|
||||
|
||||
LedDevice::LedDevice(std::string name) : mName(name), mBasePath(kBaseLedsPath + name + "/") {
|
||||
if (!readFromFile(mBasePath + kMaxBrightnessNode, mMaxBrightness)) {
|
||||
mMaxBrightness = kDefaultMaxBrightness;
|
||||
@ -40,6 +50,13 @@ LedDevice::LedDevice(std::string name) : mName(name), mBasePath(kBaseLedsPath +
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mSupportsTimed = std::ifstream(mBasePath + kBlinkNode).good() &&
|
||||
std::ifstream(mBasePath + kStartIdxNode).good() &&
|
||||
std::ifstream(mBasePath + kDutyPctsNode).good() &&
|
||||
std::ifstream(mBasePath + kPauseLoNode).good() &&
|
||||
std::ifstream(mBasePath + kPauseHiNode).good() &&
|
||||
std::ifstream(mBasePath + kRampStepMsNode).good();
|
||||
}
|
||||
|
||||
std::string LedDevice::getName() const {
|
||||
@ -50,17 +67,57 @@ bool LedDevice::supportsBreath() const {
|
||||
return !mBreathNode.empty();
|
||||
}
|
||||
|
||||
bool LedDevice::supportsTimed() const {
|
||||
return mSupportsTimed;
|
||||
}
|
||||
|
||||
bool LedDevice::exists() const {
|
||||
return std::ifstream(mBasePath + kBrightnessNode).good();
|
||||
}
|
||||
|
||||
bool LedDevice::setBrightness(uint8_t value, LightMode mode) {
|
||||
static std::string getScaledDutyPercent(uint8_t brightness) {
|
||||
std::string output;
|
||||
for (int i = 0; i <= kRampSteps; i++) {
|
||||
if (i != 0) {
|
||||
output += ",";
|
||||
}
|
||||
output += std::to_string(i * 100 * brightness / (0xFF * kRampSteps));
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
bool LedDevice::setBrightness(uint8_t value, LightMode mode, uint32_t flashOnMs,
|
||||
uint32_t flashOffMs) {
|
||||
// Disable current blinking
|
||||
if (mSupportsTimed) {
|
||||
writeToFile(mBasePath + kBlinkNode, 0);
|
||||
}
|
||||
if (supportsBreath()) {
|
||||
writeToFile(mBasePath + mBreathNode, 0);
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case LightMode::TIMED:
|
||||
if (mSupportsTimed) {
|
||||
int32_t stepDuration = kRampMaxStepDurationMs;
|
||||
int32_t pauseLo = flashOffMs;
|
||||
int32_t pauseHi = flashOnMs - (stepDuration * kRampSteps * 2);
|
||||
|
||||
if (pauseHi < 0) {
|
||||
stepDuration = flashOnMs / (kRampSteps * 2);
|
||||
pauseHi = 0;
|
||||
}
|
||||
|
||||
return writeToFile(mBasePath + kStartIdxNode, 0) &&
|
||||
writeToFile(mBasePath + kDutyPctsNode, getScaledDutyPercent(value)) &&
|
||||
writeToFile(mBasePath + kPauseLoNode, pauseLo) &&
|
||||
writeToFile(mBasePath + kPauseHiNode, pauseHi) &&
|
||||
writeToFile(mBasePath + kRampStepMsNode, stepDuration) &&
|
||||
writeToFile(mBasePath + kBlinkNode, 1);
|
||||
}
|
||||
|
||||
// Fallthrough to breath mode if timed is not supported
|
||||
FALLTHROUGH_INTENDED;
|
||||
case LightMode::BREATH:
|
||||
if (supportsBreath()) {
|
||||
return writeToFile(mBasePath + mBreathNode, value > 0 ? 1 : 0);
|
||||
@ -85,6 +142,7 @@ void LedDevice::dump(int fd) const {
|
||||
dprintf(fd, ", base path: %s", mBasePath.c_str());
|
||||
dprintf(fd, ", max brightness: %u", mMaxBrightness);
|
||||
dprintf(fd, ", supports breath: %d", supportsBreath());
|
||||
dprintf(fd, ", supports timed: %d", supportsTimed());
|
||||
dprintf(fd, ", breath node: %s", mBreathNode.c_str());
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ namespace light {
|
||||
enum LightMode {
|
||||
STATIC,
|
||||
BREATH,
|
||||
TIMED,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -58,6 +59,15 @@ class LedDevice : public IDumpable {
|
||||
*/
|
||||
bool supportsBreath() const;
|
||||
|
||||
/**
|
||||
* Return whether this LED device supports timed mode.
|
||||
* When it doesn't, calling setBrightness with LightMode::TIMED will behave like
|
||||
* LightMode::BREATH.
|
||||
*
|
||||
* @return bool true if the LED device supports timed mode, false otherwise
|
||||
*/
|
||||
bool supportsTimed() const;
|
||||
|
||||
/**
|
||||
* Set the brightness of the LED device.
|
||||
*
|
||||
@ -65,7 +75,8 @@ class LedDevice : public IDumpable {
|
||||
* @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);
|
||||
bool setBrightness(uint8_t value, LightMode mode = LightMode::STATIC, uint32_t flashOnMs = 0,
|
||||
uint32_t flashOffMs = 0);
|
||||
|
||||
void dump(int fd) const override;
|
||||
|
||||
@ -74,6 +85,7 @@ class LedDevice : public IDumpable {
|
||||
std::string mBasePath;
|
||||
uint32_t mMaxBrightness;
|
||||
std::string mBreathNode;
|
||||
bool mSupportsTimed;
|
||||
};
|
||||
|
||||
} // namespace light
|
||||
|
@ -109,6 +109,8 @@ void Lights::updateNotificationColor() {
|
||||
lightMode = LightMode::STATIC;
|
||||
break;
|
||||
case FlashMode::TIMED:
|
||||
lightMode = LightMode::TIMED;
|
||||
break;
|
||||
case FlashMode::HARDWARE:
|
||||
lightMode = LightMode::BREATH;
|
||||
break;
|
||||
@ -118,7 +120,7 @@ void Lights::updateNotificationColor() {
|
||||
break;
|
||||
}
|
||||
|
||||
mDevices.setNotificationColor(color, lightMode);
|
||||
mDevices.setNotificationColor(color, lightMode, state.flashOnMs, state.flashOffMs);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -38,7 +38,14 @@ bool RgbLedDevice::supportsBreath() const {
|
||||
(!mBlue.exists() || mBlue.supportsBreath());
|
||||
}
|
||||
|
||||
bool RgbLedDevice::setBrightness(rgb color, LightMode mode) {
|
||||
bool RgbLedDevice::supportsTimed() const {
|
||||
return (!mRed.exists() || mRed.supportsTimed()) &&
|
||||
(!mGreen.exists() || mGreen.supportsTimed()) &&
|
||||
(!mBlue.exists() || mBlue.supportsTimed());
|
||||
}
|
||||
|
||||
bool RgbLedDevice::setBrightness(rgb color, LightMode mode, uint32_t flashOnMs,
|
||||
uint32_t flashOffMs) {
|
||||
bool rc = true;
|
||||
|
||||
if (mColors == Color::NONE) {
|
||||
@ -46,34 +53,44 @@ bool RgbLedDevice::setBrightness(rgb color, LightMode mode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mode == LightMode::TIMED && !supportsTimed()) {
|
||||
// Not all LEDs support timed mode, force breathing mode
|
||||
mode = LightMode::BREATH;
|
||||
}
|
||||
|
||||
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);
|
||||
rc &= mRed.setBrightness(color.red, mode, flashOnMs, flashOffMs);
|
||||
rc &= mGreen.setBrightness(color.green, mode, flashOnMs, flashOffMs);
|
||||
rc &= mBlue.setBrightness(color.blue, mode, flashOnMs, flashOffMs);
|
||||
} else {
|
||||
// Check if we have only one LED
|
||||
if (mColors == Color::RED) {
|
||||
rc &= mRed.setBrightness(color.toBrightness(), mode);
|
||||
rc &= mRed.setBrightness(color.toBrightness(), mode, flashOnMs, flashOffMs);
|
||||
} else if (mColors == Color::GREEN) {
|
||||
rc &= mGreen.setBrightness(color.toBrightness(), mode);
|
||||
rc &= mGreen.setBrightness(color.toBrightness(), mode, flashOnMs, flashOffMs);
|
||||
} else if (mColors == Color::BLUE) {
|
||||
rc &= mBlue.setBrightness(color.toBrightness(), mode);
|
||||
rc &= mBlue.setBrightness(color.toBrightness(), mode, flashOnMs, flashOffMs);
|
||||
} 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);
|
||||
rc &= mBlue.setBrightness((color.blue + color.red) / 2, mode, flashOnMs,
|
||||
flashOffMs);
|
||||
rc &= mGreen.setBrightness((color.green + color.red) / 2, mode, flashOnMs,
|
||||
flashOffMs);
|
||||
} 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);
|
||||
rc &= mRed.setBrightness((color.red + color.green) / 2, mode, flashOnMs,
|
||||
flashOffMs);
|
||||
rc &= mBlue.setBrightness((color.blue + color.green) / 2, mode, flashOnMs,
|
||||
flashOffMs);
|
||||
} 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);
|
||||
rc &= mRed.setBrightness((color.red + color.blue) / 2, mode, flashOnMs, flashOffMs);
|
||||
rc &= mGreen.setBrightness((color.green + color.blue) / 2, mode, flashOnMs,
|
||||
flashOffMs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -84,6 +101,7 @@ bool RgbLedDevice::setBrightness(rgb color, LightMode mode) {
|
||||
void RgbLedDevice::dump(int fd) const {
|
||||
dprintf(fd, "Exists: %d", exists());
|
||||
dprintf(fd, ", supports breath: %d", supportsBreath());
|
||||
dprintf(fd, ", supports timed: %d", supportsTimed());
|
||||
dprintf(fd, ", colors:");
|
||||
if (mColors != Color::NONE) {
|
||||
if (mColors & Color::RED) {
|
||||
|
@ -51,6 +51,16 @@ class RgbLedDevice : public IDumpable {
|
||||
*/
|
||||
bool supportsBreath() const;
|
||||
|
||||
/**
|
||||
* Return whether this RGB LED device supports timed mode.
|
||||
* This is true when all existing LEDs support timed mode.
|
||||
* In case this is false, calling setBrightness with LightMode::TIMED will behave like
|
||||
* LightMode::BREATH.
|
||||
*
|
||||
* @return bool true if the RGB LED device supports timed mode, false otherwise
|
||||
*/
|
||||
bool supportsTimed() const;
|
||||
|
||||
/**
|
||||
* Set the brightness of this RGB LED device.
|
||||
*
|
||||
@ -58,7 +68,8 @@ class RgbLedDevice : public IDumpable {
|
||||
* @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);
|
||||
bool setBrightness(rgb color, LightMode mode = LightMode::STATIC, uint32_t flashOnMs = 0,
|
||||
uint32_t flashOffMs = 0);
|
||||
|
||||
void dump(int fd) const override;
|
||||
|
||||
|
@ -10,37 +10,72 @@ on early-boot
|
||||
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/duty_pcts
|
||||
chown system system /sys/class/leds/blue/max_brightness
|
||||
chown system system /sys/class/leds/blue/pause_hi
|
||||
chown system system /sys/class/leds/blue/pause_lo
|
||||
chown system system /sys/class/leds/blue/ramp_step_ms
|
||||
chown system system /sys/class/leds/blue/start_idx
|
||||
|
||||
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/duty_pcts
|
||||
chown system system /sys/class/leds/button-backlight/max_brightness
|
||||
chown system system /sys/class/leds/button-backlight/pause_hi
|
||||
chown system system /sys/class/leds/button-backlight/pause_lo
|
||||
chown system system /sys/class/leds/button-backlight/ramp_step_ms
|
||||
chown system system /sys/class/leds/button-backlight/start_idx
|
||||
|
||||
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/duty_pcts
|
||||
chown system system /sys/class/leds/button-backlight1/max_brightness
|
||||
chown system system /sys/class/leds/button-backlight1/pause_hi
|
||||
chown system system /sys/class/leds/button-backlight1/pause_lo
|
||||
chown system system /sys/class/leds/button-backlight1/ramp_step_ms
|
||||
chown system system /sys/class/leds/button-backlight1/start_idx
|
||||
|
||||
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/duty_pcts
|
||||
chown system system /sys/class/leds/green/max_brightness
|
||||
chown system system /sys/class/leds/green/pause_hi
|
||||
chown system system /sys/class/leds/green/pause_lo
|
||||
chown system system /sys/class/leds/green/ramp_step_ms
|
||||
chown system system /sys/class/leds/green/start_idx
|
||||
|
||||
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/duty_pcts
|
||||
chown system system /sys/class/leds/lcd-backlight/max_brightness
|
||||
chown system system /sys/class/leds/lcd-backlight/pause_hi
|
||||
chown system system /sys/class/leds/lcd-backlight/pause_lo
|
||||
chown system system /sys/class/leds/lcd-backlight/ramp_step_ms
|
||||
chown system system /sys/class/leds/lcd-backlight/start_idx
|
||||
|
||||
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/duty_pcts
|
||||
chown system system /sys/class/leds/red/max_brightness
|
||||
chown system system /sys/class/leds/red/pause_hi
|
||||
chown system system /sys/class/leds/red/pause_lo
|
||||
chown system system /sys/class/leds/red/ramp_step_ms
|
||||
chown system system /sys/class/leds/red/start_idx
|
||||
|
||||
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/duty_pcts
|
||||
chown system system /sys/class/leds/white/max_brightness
|
||||
chown system system /sys/class/leds/white/pause_hi
|
||||
chown system system /sys/class/leds/white/pause_lo
|
||||
chown system system /sys/class/leds/white/ramp_step_ms
|
||||
chown system system /sys/class/leds/white/start_idx
|
||||
|
||||
service vendor.light-default /vendor/bin/hw/android.hardware.light-service.xiaomi
|
||||
class hal
|
||||
|
Loading…
Reference in New Issue
Block a user