aidl: light: Wire up
* Merged Xiaomi SM8250, SM8150, SM6250, SDM710 and MSM8953 implementations Change-Id: I16764ec8676de6c2a9f745876dddab75db6adf35
This commit is contained in:
parent
fecaf7f077
commit
f162d20b5b
@ -11,6 +11,8 @@ cc_binary {
|
||||
vintf_fragments: ["android.hardware.light-service.xiaomi.xml"],
|
||||
srcs: [
|
||||
"Lights.cpp",
|
||||
"LED.cpp",
|
||||
"Utils.cpp",
|
||||
"service.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
|
39
aidl/light/LED.cpp
Normal file
39
aidl/light/LED.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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(uint32_t value) {
|
||||
return writeToFile(mBasePath + (mBreath ? "breath" : "blink"), value);
|
||||
}
|
||||
|
||||
bool LED::setBrightness(uint32_t value) {
|
||||
return writeToFile(mBasePath + "brightness", value * mMaxBrightness / 0xFF);
|
||||
}
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
32
aidl/light/LED.h
Normal file
32
aidl/light/LED.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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(uint32_t value);
|
||||
bool setBrightness(uint32_t value);
|
||||
private:
|
||||
std::string mBasePath;
|
||||
uint32_t mMaxBrightness;
|
||||
bool mBreath;
|
||||
};
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
@ -6,17 +6,142 @@
|
||||
|
||||
#include "Lights.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include "LED.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
ndk::ScopedAStatus Lights::setLightState(int32_t /*id*/, const HwLightState& /*state*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
static const std::string kAllBacklightPaths[] = {
|
||||
"/sys/class/backlight/panel0-backlight/brightness",
|
||||
"/sys/class/leds/lcd-backlight/brightness",
|
||||
};
|
||||
|
||||
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}
|
||||
|
||||
static const HwLight kBacklightHwLight = AutoHwLight(LightType::BACKLIGHT);
|
||||
static const HwLight kBatteryHwLight = AutoHwLight(LightType::BATTERY);
|
||||
static const HwLight kButtonsHwLight = AutoHwLight(LightType::BUTTONS);
|
||||
static const HwLight kNotificationHwLight = AutoHwLight(LightType::NOTIFICATIONS);
|
||||
|
||||
Lights::Lights() {
|
||||
for (auto& backlight : kAllBacklightPaths) {
|
||||
if (!fileWriteable(backlight))
|
||||
continue;
|
||||
|
||||
mBacklightPath = backlight;
|
||||
mLights.push_back(kBacklightHwLight);
|
||||
break;
|
||||
}
|
||||
|
||||
for (auto& buttons : kAllButtonsPaths) {
|
||||
if (!fileWriteable(buttons))
|
||||
continue;
|
||||
|
||||
mButtonsPaths.push_back(buttons);
|
||||
}
|
||||
|
||||
if (!mButtonsPaths.empty())
|
||||
mLights.push_back(kButtonsHwLight);
|
||||
|
||||
mWhiteLED = kLEDs[WHITE].exists();
|
||||
|
||||
mLights.push_back(kBatteryHwLight);
|
||||
mLights.push_back(kNotificationHwLight);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Lights::getLights(std::vector<HwLight> */*_aidl_return*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
ndk::ScopedAStatus Lights::setLightState(int32_t id, const HwLightState& state) {
|
||||
LightType type = static_cast<LightType>(id);
|
||||
switch (type) {
|
||||
case LightType::BACKLIGHT:
|
||||
if (!mBacklightPath.empty())
|
||||
writeToFile(mBacklightPath, colorToBrightness(state.color));
|
||||
break;
|
||||
case LightType::BUTTONS:
|
||||
for (auto& buttons : mButtonsPaths)
|
||||
writeToFile(buttons, isLit(state.color));
|
||||
break;
|
||||
case LightType::BATTERY:
|
||||
case LightType::NOTIFICATIONS:
|
||||
mLEDMutex.lock();
|
||||
if (type == LightType::BATTERY)
|
||||
mLastBatteryState = state;
|
||||
else
|
||||
mLastNotificationState = state;
|
||||
setLED(isLit(mLastBatteryState.color) ? mLastBatteryState : mLastNotificationState);
|
||||
mLEDMutex.unlock();
|
||||
break;
|
||||
default:
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
break;
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Lights::getLights(std::vector<HwLight> *_aidl_return) {
|
||||
for (auto& light : mLights)
|
||||
_aidl_return->push_back(light);
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
void Lights::setLED(const HwLightState& state) {
|
||||
bool rc = true;
|
||||
argb_t color = colorToArgb(state.color);
|
||||
uint32_t blink = (state.flashOnMs != 0 && state.flashOffMs != 0);
|
||||
|
||||
switch (state.flashMode) {
|
||||
case FlashMode::HARDWARE:
|
||||
case FlashMode::TIMED:
|
||||
if (mWhiteLED) {
|
||||
rc = kLEDs[WHITE].setBreath(blink);
|
||||
} else {
|
||||
if (!!color.red)
|
||||
rc &= kLEDs[RED].setBreath(blink);
|
||||
if (!!color.green)
|
||||
rc &= kLEDs[GREEN].setBreath(blink);
|
||||
if (!!color.blue)
|
||||
rc &= kLEDs[BLUE].setBreath(blink);
|
||||
}
|
||||
if (rc)
|
||||
break;
|
||||
FALLTHROUGH_INTENDED;
|
||||
default:
|
||||
if (mWhiteLED) {
|
||||
rc = kLEDs[WHITE].setBrightness(colorToBrightness(state.color));
|
||||
} else {
|
||||
rc = kLEDs[RED].setBrightness(color.red);
|
||||
rc &= kLEDs[GREEN].setBrightness(color.green);
|
||||
rc &= kLEDs[BLUE].setBrightness(color.blue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace light
|
||||
|
@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <aidl/android/hardware/light/BnLights.h>
|
||||
#include <mutex>
|
||||
|
||||
using ::aidl::android::hardware::light::HwLightState;
|
||||
using ::aidl::android::hardware::light::HwLight;
|
||||
@ -18,8 +19,22 @@ namespace light {
|
||||
|
||||
class Lights : public BnLights {
|
||||
public:
|
||||
Lights();
|
||||
|
||||
ndk::ScopedAStatus setLightState(int32_t id, const HwLightState& state) override;
|
||||
ndk::ScopedAStatus getLights(std::vector<HwLight> *_aidl_return) override;
|
||||
private:
|
||||
void setLED(const HwLightState& state);
|
||||
|
||||
std::vector<HwLight> mLights;
|
||||
|
||||
std::string mBacklightPath;
|
||||
std::vector<std::string> mButtonsPaths;
|
||||
bool mWhiteLED;
|
||||
|
||||
std::mutex mLEDMutex;
|
||||
HwLightState mLastBatteryState;
|
||||
HwLightState mLastNotificationState;
|
||||
};
|
||||
|
||||
} // namespace light
|
||||
|
86
aidl/light/Utils.cpp
Normal file
86
aidl/light/Utils.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
bool isLit(uint32_t color) {
|
||||
return color & 0x00ffffff;
|
||||
}
|
||||
|
||||
argb_t colorToArgb(uint32_t color) {
|
||||
argb_t r;
|
||||
|
||||
// Extract brightness from AARRGGBB.
|
||||
r.alpha = (color >> 24) & 0xFF;
|
||||
|
||||
// Retrieve each of the RGB colors
|
||||
r.red = (color >> 16) & 0xFF;
|
||||
r.green = (color >> 8) & 0xFF;
|
||||
r.blue = color & 0xFF;
|
||||
|
||||
// Scale RGB colors if a brightness has been applied by the user
|
||||
if (r.alpha != 0xFF) {
|
||||
r.red = r.red * r.alpha / 0xFF;
|
||||
r.green = r.green * r.alpha / 0xFF;
|
||||
r.blue = r.blue * r.alpha / 0xFF;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32_t argbToBrightness(argb_t c_argb) {
|
||||
return (77 * c_argb.red + 150 * c_argb.green + 29 * c_argb.blue) >> 8;
|
||||
}
|
||||
|
||||
uint32_t colorToBrightness(uint32_t color) {
|
||||
argb_t c_argb = colorToArgb(color);
|
||||
|
||||
return argbToBrightness(c_argb);
|
||||
}
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
35
aidl/light/Utils.h
Normal file
35
aidl/light/Utils.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
typedef struct argb {
|
||||
uint32_t alpha;
|
||||
uint32_t red;
|
||||
uint32_t green;
|
||||
uint32_t blue;
|
||||
} argb_t;
|
||||
|
||||
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);
|
||||
bool isLit(uint32_t color);
|
||||
argb_t colorToArgb(uint32_t color);
|
||||
uint32_t argbToBrightness(argb_t c_argb);
|
||||
uint32_t colorToBrightness(uint32_t color);
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
@ -1,5 +1,32 @@
|
||||
on early-boot
|
||||
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
|
||||
|
||||
chown system system /sys/class/leds/lcd-backlight/brightness
|
||||
chown system system /sys/class/backlight/panel0-backlight/brightness
|
||||
|
||||
chown system system /sys/class/leds/button-backlight/brightness
|
||||
chown system system /sys/class/leds/button-backlight1/brightness
|
||||
|
||||
service vendor.light-default /vendor/bin/hw/android.hardware.light-service.xiaomi
|
||||
class hal
|
||||
user nobody
|
||||
group nobody
|
||||
user system
|
||||
group system
|
||||
shutdown critical
|
||||
|
Loading…
Reference in New Issue
Block a user