davinci: light: Avoid resetting state

The handler function is called regardless of whether the value of the
highest priority state changed.
In case of the notification led, this translates to the breathing
process being reset, which triggers my OCD.

Change-Id: I4880b00602cbb739219871f1d7ce9ad85d87bc1b
This commit is contained in:
Demon000 2020-02-15 10:58:33 +00:00 committed by Arian
parent feedda1d84
commit 13a3863832
No known key found for this signature in database
GPG Key ID: 48029380598CE3B9

View File

@ -108,10 +108,21 @@ static void handleNotification(const LightState& state) {
}
}
static inline bool isLit(const LightState& state) {
static inline bool isStateLit(const LightState& state) {
return state.color & 0x00ffffff;
}
static inline bool isStateEqual(const LightState& first, const LightState& second) {
if (first.color == second.color && first.flashMode == second.flashMode &&
first.flashOnMs == second.flashOnMs &&
first.flashOffMs == second.flashOffMs &&
first.brightnessMode == second.brightnessMode) {
return true;
}
return false;
}
/* Keep sorted in the order of importance. */
static std::vector<LightBackend> backends = {
{ Type::ATTENTION, handleNotification },
@ -120,6 +131,40 @@ static std::vector<LightBackend> backends = {
{ Type::BACKLIGHT, handleBacklight },
};
static LightStateHandler findHandler(Type type) {
for (const LightBackend& backend : backends) {
if (backend.type == type) {
return backend.handler;
}
}
return nullptr;
}
static LightState findLitState(LightStateHandler handler) {
LightState emptyState;
for (const LightBackend& backend : backends) {
if (backend.handler == handler) {
if (isStateLit(backend.state)) {
return backend.state;
}
emptyState = backend.state;
}
}
return emptyState;
}
static void updateState(Type type, const LightState& state) {
for (LightBackend& backend : backends) {
if (backend.type == type) {
backend.state = state;
}
}
}
} // anonymous namespace
namespace android {
@ -129,34 +174,29 @@ namespace V2_0 {
namespace implementation {
Return<Status> Light::setLight(Type type, const LightState& state) {
LightStateHandler handler = nullptr;
/* Lock global mutex until light state is updated. */
std::lock_guard<std::mutex> lock(globalLock);
/* Update the cached state value for the current type. */
for (LightBackend& backend : backends) {
if (backend.type == type) {
backend.state = state;
handler = backend.handler;
}
}
/* If no handler has been found, then the type is not supported. */
LightStateHandler handler = findHandler(type);
if (!handler) {
/* If no handler has been found, then the type is not supported. */
return Status::LIGHT_NOT_SUPPORTED;
}
/* Light up the type with the highest priority that matches the current handler. */
for (LightBackend& backend : backends) {
if (handler == backend.handler && isLit(backend.state)) {
handler(backend.state);
return Status::SUCCESS;
}
/* Find the old state of the current handler. */
LightState oldState = findLitState(handler);
/* Update the cached state value for the current type. */
updateState(type, state);
/* Find the new state of the current handler. */
LightState newState = findLitState(handler);
if (isStateEqual(oldState, newState)) {
return Status::SUCCESS;
}
/* If no type has been lit up, then turn off the hardware. */
handler(state);
handler(newState);
return Status::SUCCESS;
}