laurel_sprout: 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
diff --git a/light/Light.cpp b/light/Light.cpp
index 593842f..978a562 100644
--- a/light/Light.cpp
+++ b/light/Light.cpp
@@ -114,10 +114,21 @@
     }
 }
 
-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 },
@@ -126,6 +137,40 @@
     { 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 {
@@ -135,34 +180,29 @@
 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;
 }