Add support for Notification LED

Also support blink/breathing effect.

Issue: FP3-A11#203
Issue: FP3-A11#233
Issue: FP3-A12#69
Change-Id: I3816c7320d6eb544d911a9b26d4b022ff4c27a69
diff --git a/liblight/lights.c b/liblight/lights.c
index e20c1ab..1ca1232 100644
--- a/liblight/lights.c
+++ b/liblight/lights.c
@@ -38,6 +38,16 @@
 #define DEFAULT_LOW_PERSISTENCE_MODE_BRIGHTNESS 0x80
 #endif
 
+/* #define ARIMA_DEBUG */
+
+#ifdef ARIMA_DEBUG
+#define LIGHT_DBG(fmt,args...) ALOGE("[ARIMA][%s] " fmt, __FUNCTION__, ##args)
+#else
+#define LIGHT_DBG(fmt,args...) do {} while (0)
+#endif
+
+#define LED_FIRST_NOTIFICATION 1
+
 /******************************************************************************/
 
 static pthread_once_t g_init = PTHREAD_ONCE_INIT;
@@ -66,13 +76,13 @@
         = "/sys/class/leds/button-backlight/brightness";
 
 char const*const RED_BLINK_FILE
-        = "/sys/class/leds/red/blink";
+        = "/sys/class/leds/red/breath";
 
 char const*const GREEN_BLINK_FILE
-        = "/sys/class/leds/green/blink";
+        = "/sys/class/leds/green/breath";
 
 char const*const BLUE_BLINK_FILE
-        = "/sys/class/leds/blue/blink";
+        = "/sys/class/leds/blue/breath";
 
 char const*const PERSISTENCE_FILE
         = "/sys/class/graphics/fb0/msm_fb_persist_mode";
@@ -214,24 +224,47 @@
         blink = 0;
     }
 
+    LIGHT_DBG("red=%02X, green=%02X, blue=%02X, blink=%d\n", red, green, blue, blink);
+
     if (blink) {
+        write_int(RED_BLINK_FILE, 0);
+        write_int(GREEN_BLINK_FILE, 0);
+        write_int(BLUE_BLINK_FILE, 0);
+        /* Delay 6ms for off effective and complete */
+        usleep(6000);
+
         if (red) {
             if (write_int(RED_BLINK_FILE, blink))
                 write_int(RED_LED_FILE, 0);
+        } else {
+            write_int(RED_LED_FILE, 0);
         }
+
         if (green) {
             if (write_int(GREEN_BLINK_FILE, blink))
                 write_int(GREEN_LED_FILE, 0);
+        } else {
+            write_int(GREEN_LED_FILE, 0);
         }
+
         if (blue) {
             if (write_int(BLUE_BLINK_FILE, blink))
                 write_int(BLUE_LED_FILE, 0);
+        } else {
+            write_int(BLUE_LED_FILE, 0);
         }
     } else {
+        write_int(RED_LED_FILE, 0);
+        write_int(GREEN_LED_FILE, 0);
+        write_int(BLUE_LED_FILE, 0);
+        /* Delay 6ms for off effective and complete */
+        usleep(6000);
+
         write_int(RED_LED_FILE, red);
         write_int(GREEN_LED_FILE, green);
         write_int(BLUE_LED_FILE, blue);
     }
+    usleep(5000); /* 5ms */
 
     return 0;
 }
@@ -239,17 +272,28 @@
 static void
 handle_speaker_battery_locked(struct light_device_t* dev)
 {
+#if LED_FIRST_NOTIFICATION
+    if (is_lit(&g_notification)) {
+        LIGHT_DBG("Notification\n");
+        set_speaker_light_locked(dev, &g_notification);
+    } else {
+        LIGHT_DBG("Battery\n");
+        set_speaker_light_locked(dev, &g_battery);
+    }
+#else /* Default */
     if (is_lit(&g_battery)) {
         set_speaker_light_locked(dev, &g_battery);
     } else {
         set_speaker_light_locked(dev, &g_notification);
     }
+#endif
 }
 
 static int
 set_light_battery(struct light_device_t* dev,
         struct light_state_t const* state)
 {
+    LIGHT_DBG("Enter...\n");
     pthread_mutex_lock(&g_lock);
     g_battery = *state;
     handle_speaker_battery_locked(dev);
@@ -261,6 +305,7 @@
 set_light_notifications(struct light_device_t* dev,
         struct light_state_t const* state)
 {
+    LIGHT_DBG("Enter...\n");
     pthread_mutex_lock(&g_lock);
     g_notification = *state;
     handle_speaker_battery_locked(dev);
@@ -321,6 +366,7 @@
     int (*set_light)(struct light_device_t* dev,
             struct light_state_t const* state);
 
+    LIGHT_DBG("Enter...\n");
     if (0 == strcmp(LIGHT_ID_BACKLIGHT, name)) {
         set_light = set_light_backlight;
     } else if (0 == strcmp(LIGHT_ID_BATTERY, name))