Files
device_xiaomi_rosemary/lights/Light.cpp
LinkBoi00 6ce8341120 rosemary: lights: Adapt brightness scaling behaviour to match MIUI
MIUI's lowest brightness value is '19' and using lower values
can cause the backlight to completely power off inadvertedly

Therefore, let's just account for this behaviour in the light AIDL
by adding '19' instead of '1' to the final brightness value

Signed-off-by: LinkBoi00 <linkdevel@protonmail.com>
Change-Id: I0e31bda9a0cc505f1246209810eae624dfe5d068
2023-04-25 17:59:38 +02:00

142 lines
3.5 KiB
C++

/*
* Copyright (C) 2018-2019 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Light.h"
#include <android-base/properties.h>
#include <fstream>
#define LCD_LED "/sys/class/leds/lcd-backlight/"
#define BRIGHTNESS "brightness"
#define MAX_BRIGHTNESS "max_brightness"
namespace {
/*
* Write value to path and close file.
*/
static void set(std::string path, std::string value) {
std::ofstream file(path);
if (!file.is_open()) {
LOG(WARNING) << "failed to write " << value.c_str() << " to " << path.c_str();
return;
}
file << value;
}
static void set(std::string path, int value) {
set(path, std::to_string(value));
}
/*
* Read max brightness from path and close file.
*/
static int getMaxBrightness(std::string path) {
std::ifstream file(path);
int value;
if (!file.is_open()) {
LOG(WARNING) << "failed to read from " << path.c_str();
return 0;
}
file >> value;
return value;
}
static uint32_t getBrightness(const HwLightState& state) {
uint32_t alpha, red, green, blue;
/*
* Extract brightness from AARRGGBB.
*/
alpha = (state.color >> 24) & 0xFF;
red = (state.color >> 16) & 0xFF;
green = (state.color >> 8) & 0xFF;
blue = state.color & 0xFF;
/*
* Scale RGB brightness using Alpha brightness.
*/
red = red * alpha / 0xFF;
green = green * alpha / 0xFF;
blue = blue * alpha / 0xFF;
return (77 * red + 150 * green + 29 * blue) >> 8;
}
static inline uint32_t scaleBrightness(uint32_t brightness, uint32_t maxBrightness) {
if (brightness == 0) {
return 0;
}
return (brightness - 1) * (maxBrightness - 19) / (0xFF - 1) + 19;
}
static inline uint32_t getScaledBrightness(const HwLightState& state, uint32_t maxBrightness) {
return scaleBrightness(getBrightness(state), maxBrightness);
}
static void handleBacklight(const HwLightState& state) {
uint32_t brightness = getScaledBrightness(state, getMaxBrightness(LCD_LED MAX_BRIGHTNESS));
set(LCD_LED BRIGHTNESS, brightness);
}
/* Keep sorted in the order of importance. */
static std::vector<LightType> backends = {
LightType::BACKLIGHT,
};
} // anonymous namespace
namespace aidl {
namespace android{
namespace hardware {
namespace light {
ndk::ScopedAStatus Lights::setLightState(int id, const HwLightState& state) {
switch(id) {
case (int) LightType::BACKLIGHT:
handleBacklight(state);
return ndk::ScopedAStatus::ok();
default:
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
}
ndk::ScopedAStatus Lights::getLights(std::vector<HwLight>* lights) {
int i = 0;
for (const LightType& backend : backends) {
HwLight hwLight;
hwLight.id = (int) backend;
hwLight.type = backend;
hwLight.ordinal = i;
lights->push_back(hwLight);
i++;
}
return ndk::ScopedAStatus::ok();
}
} // namespace light
} // namespace hardware
} // namespace android
} // namespace aidl