Merge changes from topic 'hidl-light-hal'

* changes:
  Adding android.hardware.light@2.0 service.
  Light 2.0 hal default implementation.
  Add lights 2.0 hal.
diff --git a/Android.bp b/Android.bp
index 65febd3..7188e91 100644
--- a/Android.bp
+++ b/Android.bp
@@ -5,6 +5,7 @@
     "benchmarks/msgq/1.0",
     "memtrack/1.0",
     "memtrack/1.0/default",
+    "light/2.0",
     "nfc/1.0",
     "nfc/1.0/default",
     "radio/1.0",
diff --git a/light/2.0/Android.bp b/light/2.0/Android.bp
new file mode 100644
index 0000000..a3b03a7
--- /dev/null
+++ b/light/2.0/Android.bp
@@ -0,0 +1,46 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+genrule {
+    name: "android.hardware.light@2.0_genc++",
+    tool: "hidl-gen",
+    cmd: "$tool -o $genDir -Lc++ -randroid.hardware:hardware/interfaces android.hardware.light@2.0",
+    srcs: [
+        "types.hal",
+        "ILight.hal",
+    ],
+    out: [
+        "android/hardware/light/2.0/types.cpp",
+        "android/hardware/light/2.0/LightAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.light@2.0_genc++_headers",
+    tool: "hidl-gen",
+    cmd: "$tool -o $genDir -Lc++ -randroid.hardware:hardware/interfaces android.hardware.light@2.0",
+    srcs: [
+        "types.hal",
+        "ILight.hal",
+    ],
+    out: [
+        "android/hardware/light/2.0/types.h",
+        "android/hardware/light/2.0/ILight.h",
+        "android/hardware/light/2.0/IHwLight.h",
+        "android/hardware/light/2.0/BnLight.h",
+        "android/hardware/light/2.0/BpLight.h",
+        "android/hardware/light/2.0/BsLight.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.light@2.0",
+    generated_sources: ["android.hardware.light@2.0_genc++"],
+    generated_headers: ["android.hardware.light@2.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.light@2.0_genc++_headers"],
+    shared_libs: [
+        "libhidl",
+        "libhwbinder",
+        "libutils",
+        "libcutils",
+    ],
+}
diff --git a/light/2.0/Android.mk b/light/2.0/Android.mk
new file mode 100644
index 0000000..8dc83f0
--- /dev/null
+++ b/light/2.0/Android.mk
@@ -0,0 +1,238 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.light@2.0-java
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+#
+# Build types.hal (Brightness)
+#
+GEN := $(intermediates)/android/hardware/light/2.0/Brightness.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.light@2.0::types.Brightness
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (Flash)
+#
+GEN := $(intermediates)/android/hardware/light/2.0/Flash.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.light@2.0::types.Flash
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (LightState)
+#
+GEN := $(intermediates)/android/hardware/light/2.0/LightState.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.light@2.0::types.LightState
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (Status)
+#
+GEN := $(intermediates)/android/hardware/light/2.0/Status.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.light@2.0::types.Status
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (Type)
+#
+GEN := $(intermediates)/android/hardware/light/2.0/Type.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.light@2.0::types.Type
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build ILight.hal
+#
+GEN := $(intermediates)/android/hardware/light/2.0/ILight.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ILight.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.light@2.0::ILight
+
+$(GEN): $(LOCAL_PATH)/ILight.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_JAVA_LIBRARY)
+
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.light@2.0-java-static
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+#
+# Build types.hal (Brightness)
+#
+GEN := $(intermediates)/android/hardware/light/2.0/Brightness.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.light@2.0::types.Brightness
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (Flash)
+#
+GEN := $(intermediates)/android/hardware/light/2.0/Flash.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.light@2.0::types.Flash
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (LightState)
+#
+GEN := $(intermediates)/android/hardware/light/2.0/LightState.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.light@2.0::types.LightState
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (Status)
+#
+GEN := $(intermediates)/android/hardware/light/2.0/Status.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.light@2.0::types.Status
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (Type)
+#
+GEN := $(intermediates)/android/hardware/light/2.0/Type.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.light@2.0::types.Type
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build ILight.hal
+#
+GEN := $(intermediates)/android/hardware/light/2.0/ILight.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ILight.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.light@2.0::ILight
+
+$(GEN): $(LOCAL_PATH)/ILight.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/light/2.0/ILight.hal b/light/2.0/ILight.hal
new file mode 100644
index 0000000..a7cd684
--- /dev/null
+++ b/light/2.0/ILight.hal
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 The Android Open Source 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.
+ */
+
+package android.hardware.light@2.0;
+
+interface ILight {
+
+    /**
+     * Set the provided lights to the provided values.
+     *
+     * @param type logical light to set
+     * @param state describes what the light should look like.
+     * @return status result of applying state transformation.
+     */
+    setLight(Type type, LightState state) generates (Status status);
+
+    /**
+     * Discover what indicator lights are available.
+     *
+     * @return types list of available lights
+     */
+    getSupportedTypes() generates (vec<Type> types);
+
+};
diff --git a/light/2.0/default/Android.mk b/light/2.0/default/Android.mk
new file mode 100644
index 0000000..61f4cc9
--- /dev/null
+++ b/light/2.0/default/Android.mk
@@ -0,0 +1,43 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.light@2.0-impl
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+    Light.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+    libhidl \
+    libhwbinder \
+    libutils \
+    liblog \
+    libcutils \
+    libhardware \
+    libbase \
+    libcutils \
+    android.hardware.light@2.0 \
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE := android.hardware.light@2.0-service
+LOCAL_INIT_RC := android.hardware.light@2.0-service.rc
+LOCAL_SRC_FILES := \
+    service.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog \
+    libcutils \
+    libdl \
+    libbase \
+    libutils \
+    libhardware_legacy \
+    libhardware \
+
+LOCAL_SHARED_LIBRARIES += \
+    libhwbinder \
+    libhidl \
+    android.hardware.light@2.0 \
+
+include $(BUILD_EXECUTABLE)
diff --git a/light/2.0/default/Light.cpp b/light/2.0/default/Light.cpp
new file mode 100644
index 0000000..fe94e91
--- /dev/null
+++ b/light/2.0/default/Light.cpp
@@ -0,0 +1,140 @@
+#include "Light.h"
+
+namespace android {
+namespace hardware {
+namespace light {
+namespace V2_0 {
+namespace implementation {
+
+static_assert(LIGHT_FLASH_NONE == static_cast<int>(Flash::NONE),
+    "Flash::NONE must match legacy value.");
+static_assert(LIGHT_FLASH_TIMED == static_cast<int>(Flash::TIMED),
+    "Flash::TIMED must match legacy value.");
+static_assert(LIGHT_FLASH_HARDWARE == static_cast<int>(Flash::HARDWARE),
+    "Flash::HARDWARE must match legacy value.");
+
+static_assert(BRIGHTNESS_MODE_USER == static_cast<int>(Brightness::USER),
+    "Brightness::USER must match legacy value.");
+static_assert(BRIGHTNESS_MODE_SENSOR == static_cast<int>(Brightness::SENSOR),
+    "Brightness::SENSOR must match legacy value.");
+static_assert(BRIGHTNESS_MODE_LOW_PERSISTENCE ==
+    static_cast<int>(Brightness::LOW_PERSISTENCE),
+    "Brightness::LOW_PERSISTENCE must match legacy value.");
+
+Light::Light(std::map<Type, light_device_t*> &&lights)
+  : mLights(std::move(lights)) {}
+
+// Methods from ::android::hardware::light::V2_0::ILight follow.
+Return<Status> Light::setLight(Type type, const LightState& state)  {
+    auto it = mLights.find(type);
+
+    if (it == mLights.end()) {
+        return Status::LIGHT_NOT_SUPPORTED;
+    }
+
+    light_device_t* hwLight = it->second;
+
+    light_state_t legacyState {
+        .color = state.color,
+        .flashMode = static_cast<int>(state.flashMode),
+        .flashOnMS = state.flashOnMs,
+        .flashOffMS = state.flashOffMs,
+        .brightnessMode = static_cast<int>(state.brightnessMode),
+    };
+
+    int ret = hwLight->set_light(hwLight, &legacyState);
+
+    switch (ret) {
+        case -ENOSYS:
+            return Status::BRIGHTNESS_NOT_SUPPORTED;
+        case 0:
+            return Status::SUCCESS;
+        default:
+            return Status::UNKNOWN;
+    }
+}
+
+Return<void> Light::getSupportedTypes(getSupportedTypes_cb _hidl_cb)  {
+    Type *types = new Type[mLights.size()];
+
+    int idx = 0;
+    for(auto const &pair : mLights) {
+        Type type = pair.first;
+
+        types[idx++] = type;
+    }
+
+    {
+        hidl_vec<Type> hidl_types{};
+        hidl_types.setToExternal(types, mLights.size());
+
+        _hidl_cb(hidl_types);
+    }
+
+    delete[] types;
+
+    return Void();
+}
+
+const static std::map<Type, const char*> kLogicalLights = {
+    {Type::BACKLIGHT,     LIGHT_ID_BACKLIGHT},
+    {Type::KEYBOARD,      LIGHT_ID_KEYBOARD},
+    {Type::BUTTONS,       LIGHT_ID_BUTTONS},
+    {Type::BATTERY,       LIGHT_ID_BATTERY},
+    {Type::NOTIFICATIONS, LIGHT_ID_NOTIFICATIONS},
+    {Type::ATTENTION,     LIGHT_ID_ATTENTION},
+    {Type::BLUETOOTH,     LIGHT_ID_BLUETOOTH},
+    {Type::WIFI,          LIGHT_ID_WIFI}
+};
+
+light_device_t* getLightDevice(const char* name) {
+    light_device_t* lightDevice;
+    const hw_module_t* hwModule = NULL;
+
+    int ret = hw_get_module (LIGHTS_HARDWARE_MODULE_ID, &hwModule);
+    if (ret == 0) {
+        ret = hwModule->methods->open(hwModule, name,
+            reinterpret_cast<hw_device_t**>(&lightDevice));
+        if (ret != 0) {
+            ALOGE("light_open %s %s failed: %d", LIGHTS_HARDWARE_MODULE_ID, name, ret);
+        }
+    } else {
+        ALOGE("hw_get_module %s %s failed: %d", LIGHTS_HARDWARE_MODULE_ID, name, ret);
+    }
+
+    if (ret == 0) {
+        return lightDevice;
+    } else {
+        ALOGE("Light passthrough failed to load legacy HAL.");
+        return nullptr;
+    }
+}
+
+ILight* HIDL_FETCH_ILight(const char* /* name */) {
+    std::map<Type, light_device_t*> lights;
+
+    for(auto const &pair : kLogicalLights) {
+        Type type = pair.first;
+        const char* name = pair.second;
+
+        light_device_t* light = getLightDevice(name);
+
+        if (light != nullptr) {
+            lights[type] = light;
+        }
+    }
+
+    if (lights.size() == 0) {
+        // Log information, but still return new Light.
+        // Some devices may not have any lights.
+        ALOGI("Could not open any lights.");
+    }
+
+    return new Light(std::move(lights));
+}
+
+} // namespace implementation
+}  // namespace V2_0
+}  // namespace light
+}  // namespace hardware
+}  // namespace android
diff --git a/light/2.0/default/Light.h b/light/2.0/default/Light.h
new file mode 100644
index 0000000..b32a09a
--- /dev/null
+++ b/light/2.0/default/Light.h
@@ -0,0 +1,46 @@
+#ifndef HIDL_GENERATED_android_hardware_light_V2_0_Light_H_
+#define HIDL_GENERATED_android_hardware_light_V2_0_Light_H_
+
+#include <android/hardware/light/2.0/ILight.h>
+#include <hardware/hardware.h>
+#include <hardware/lights.h>
+#include <hidl/Status.h>
+#include <hidl/MQDescriptor.h>
+#include <map>
+
+namespace android {
+namespace hardware {
+namespace light {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::light::V2_0::ILight;
+using ::android::hardware::light::V2_0::LightState;
+using ::android::hardware::light::V2_0::Status;
+using ::android::hardware::light::V2_0::Type;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+struct Light : public ILight {
+    Light(std::map<Type, light_device_t*> &&lights);
+
+    // Methods from ::android::hardware::light::V2_0::ILight follow.
+    Return<Status> setLight(Type type, const LightState& state)  override;
+    Return<void> getSupportedTypes(getSupportedTypes_cb _hidl_cb)  override;
+
+private:
+    std::map<Type, light_device_t*> mLights;
+};
+
+extern "C" ILight* HIDL_FETCH_ILight(const char* name);
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace light
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HIDL_GENERATED_android_hardware_light_V2_0_Light_H_
diff --git a/light/2.0/default/android.hardware.light@2.0-service.rc b/light/2.0/default/android.hardware.light@2.0-service.rc
new file mode 100644
index 0000000..4228d95
--- /dev/null
+++ b/light/2.0/default/android.hardware.light@2.0-service.rc
@@ -0,0 +1,4 @@
+service light-hal-2-0 /system/bin/hw/android.hardware.light@2.0-service
+    class hal
+    user system
+    group system readproc
\ No newline at end of file
diff --git a/light/2.0/default/service.cpp b/light/2.0/default/service.cpp
new file mode 100644
index 0000000..582d224
--- /dev/null
+++ b/light/2.0/default/service.cpp
@@ -0,0 +1,46 @@
+#define LOG_TAG "android.hardware.light@2.0-service"
+#include <utils/Log.h>
+
+#include <iostream>
+#include <unistd.h>
+
+#include <android/hardware/light/2.0/ILight.h>
+
+#include <hidl/IServiceManager.h>
+#include <hwbinder/IPCThreadState.h>
+#include <hwbinder/ProcessState.h>
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+
+using android::sp;
+
+// libhwbinder:
+using android::hardware::IPCThreadState;
+using android::hardware::ProcessState;
+
+// Generated HIDL files
+using android::hardware::light::V2_0::ILight;
+
+int main() {
+    ALOGI("Service is starting.");
+    const char instance[] = "light";
+    ALOGI("Retrieving default implementation of instance %s.",
+          instance);
+
+    android::sp<ILight> service = ILight::getService(instance, true);
+
+    if (service.get() == nullptr) {
+        ALOGE("ILight::getService returned NULL, exiting");
+        return -1;
+    }
+
+    LOG_FATAL_IF(service->isRemote(), "Implementation is REMOTE!");
+
+    ALOGI("Registering instance %s.", instance);
+    service->registerAsService(instance);
+    ALOGI("Ready.");
+
+    ProcessState::self()->setThreadPoolMaxThreadCount(0);
+    ProcessState::self()->startThreadPool();
+    IPCThreadState::self()->joinThreadPool();
+}
diff --git a/light/2.0/types.hal b/light/2.0/types.hal
new file mode 100644
index 0000000..f065ce0
--- /dev/null
+++ b/light/2.0/types.hal
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2016 The Android Open Source 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.
+ */
+
+package android.hardware.light@2.0;
+
+enum Status : int32_t {
+    SUCCESS,
+    LIGHT_NOT_SUPPORTED,
+    BRIGHTNESS_NOT_SUPPORTED,
+    UNKNOWN,
+};
+
+enum Flash : int32_t {
+    /*
+     * Keep the light steady on or off.
+     */
+    NONE,
+
+    /*
+     * Flash the light at specified rate.
+     */
+    TIMED,
+
+    /*
+     * Flash the light using hardware assist.
+     */
+    HARDWARE,
+};
+
+enum Brightness : int32_t {
+    /**
+     * Light brightness is managed by a user setting.
+     */
+    USER,
+
+    /**
+     * Light brightness is managed by a light sensor.
+     */
+    SENSOR,
+
+    /**
+     * Use a low-persistence mode for display backlights.
+     *
+     * When set, the device driver must switch to a mode optimized for low display
+     * persistence that is intended to be used when the device is being treated as a
+     * head mounted display (HMD). The actual display brightness in this mode is
+     * implementation dependent, and any value set for color in light_state may be
+     * overridden by the HAL implementation.
+     *
+     * For an optimal HMD viewing experience, the display must meet the following
+     * criteria in this mode:
+     * - Gray-to-Gray, White-to-Black, and Black-to-White switching time must be ≤ 3 ms.
+     * - The display must support low-persistence with ≤ 3.5 ms persistence.
+     *   Persistence is defined as the amount of time for which a pixel is
+     *   emitting light for a single frame.
+     * - Any "smart panel" or other frame buffering options that increase display
+     *   latency are disabled.
+     * - Display brightness is set so that the display is still visible to the user
+     *   under normal indoor lighting.
+     * - The display must update at 60 Hz at least, but higher refresh rates are
+     *   recommended for low latency.
+     *
+     */
+    LOW_PERSISTENCE,
+};
+
+/*
+ * These light IDs correspond to logical lights, not physical.
+ * So for example, if your INDICATOR light is in line with your
+ * BUTTONS, it might make sense to also light the INDICATOR
+ * light to a reasonable color when the BUTTONS are lit.
+ */
+enum Type : int32_t {
+    BACKLIGHT,
+    KEYBOARD,
+    BUTTONS,
+    BATTERY,
+    NOTIFICATIONS,
+    ATTENTION,
+    BLUETOOTH,
+    WIFI,
+
+    COUNT,
+};
+
+/**
+ * The parameters that can be set for a given light.
+ *
+ * Not all lights must support all parameters. If you
+ * can do something backward-compatible, do it.
+ */
+struct LightState {
+    /**
+     * The color of the LED in ARGB.
+     *
+     * Do your best here.
+     *   - If your light can only do red or green, if they ask for blue,
+     *     you should do green.
+     *   - If you can only do a brightness ramp, then use this formula:
+     *      unsigned char brightness = ((77*((color>>16)&0x00ff))
+     *              + (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8;
+     *   - If you can only do on or off, 0 is off, anything else is on.
+     *
+     * The high byte should be ignored. Callers will set it to 0xff (which
+     * would correspond to 255 alpha).
+     */
+    uint32_t color;
+
+    /**
+     * To flash the light at a given rate, set flashMode to LIGHT_FLASH_TIMED,
+     * and then flashOnMS should be set to the number of milliseconds to turn
+     * the light on, followed by the number of milliseconds to turn the light
+     * off.
+     */
+    Flash flashMode;
+
+    int32_t flashOnMs;
+    int32_t flashOffMs;
+
+    Brightness brightnessMode;
+};