diff --git a/light/Light.cpp b/light/Light.cpp index 6d68a88..19e578e 100644 --- a/light/Light.cpp +++ b/light/Light.cpp @@ -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 backends = { { Type::ATTENTION, handleNotification }, @@ -120,6 +131,40 @@ static std::vector 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 Light::setLight(Type type, const LightState& state) { - LightStateHandler handler = nullptr; - /* Lock global mutex until light state is updated. */ std::lock_guard 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; }