blob: fc984338f9e2b3f3427028841e98767bda2fd6b7 [file] [log] [blame]
Alexander Koskovich5bee99d2021-08-01 21:40:55 -07001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6#include "Lights.h"
7#include <log/log.h>
8#include <android-base/logging.h>
9
10namespace aidl {
11namespace android {
12namespace hardware {
13namespace light {
14
15const static std::map<LightType, const char*> kLogicalLights = {
16 {LightType::BACKLIGHT, LIGHT_ID_BACKLIGHT},
17 {LightType::KEYBOARD, LIGHT_ID_KEYBOARD},
18 {LightType::BUTTONS, LIGHT_ID_BUTTONS},
19 {LightType::BATTERY, LIGHT_ID_BATTERY},
20 {LightType::NOTIFICATIONS, LIGHT_ID_NOTIFICATIONS},
21 {LightType::ATTENTION, LIGHT_ID_ATTENTION},
22 {LightType::BLUETOOTH, LIGHT_ID_BLUETOOTH},
23 {LightType::WIFI, LIGHT_ID_WIFI}
24};
25
26light_device_t* getLightDevice(const char* name) {
27 light_device_t* lightDevice;
28 const hw_module_t* hwModule = NULL;
29 int ret = hw_get_module (LIGHTS_HARDWARE_MODULE_ID, &hwModule);
30 if (ret == 0) {
31 ret = hwModule->methods->open(hwModule, name,
32 reinterpret_cast<hw_device_t**>(&lightDevice));
33 if (ret != 0) {
34 ALOGE("light_open %s %s failed: %d", LIGHTS_HARDWARE_MODULE_ID, name, ret);
35 }
36 } else {
37 ALOGE("hw_get_module %s %s failed: %d", LIGHTS_HARDWARE_MODULE_ID, name, ret);
38 }
39 if (ret == 0) {
40 return lightDevice;
41 } else {
42 ALOGE("Light passthrough failed to load legacy HAL.");
43 return nullptr;
44 }
45}
46
47Lights::Lights() {
48 std::map<int, light_device_t*> lights;
49 std::vector<HwLight> availableLights;
50 int lightCount =0;
51 for(auto const &pair : kLogicalLights) {
52 LightType type = pair.first;
53 const char* name = pair.second;
54 light_device_t* lightDevice = getLightDevice(name);
55 lightCount++;
56 if (lightDevice != nullptr) {
57 HwLight hwLight{};
58 hwLight.id = (int)type;
59 hwLight.type = type;
60 hwLight.ordinal = 0;
61 lights[hwLight.id] = lightDevice;
62 availableLights.emplace_back(hwLight);
63 }
64 }
65 mAvailableLights = availableLights;
66 mLights = lights;
67 maxLights = lightCount;
68}
69
70ndk::ScopedAStatus Lights::setLightState(int id, const HwLightState& state) {
71 if (id >= maxLights) {
72 ALOGE("Invalid Light id : %d", id);
73 return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
74 }
75 auto it = mLights.find(id);
76 if (it == mLights.end()) {
77 ALOGE("Light not supported");
78 return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
79 }
80 light_device_t* hwLight = it->second;
81 light_state_t legacyState {
82 .color = static_cast<unsigned int>(state.color),
83 .flashMode = static_cast<int>(state.flashMode),
84 .flashOnMS = state.flashOnMs,
85 .flashOffMS = state.flashOffMs,
86 .brightnessMode = static_cast<int>(state.brightnessMode),
87 };
88 int ret = hwLight->set_light(hwLight, &legacyState);
89 switch (ret) {
90 case -ENOSYS:
91 return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
92 case 0:
93 return ndk::ScopedAStatus::ok();
94 default:
95 return ndk::ScopedAStatus::fromServiceSpecificError(ret);
96 }
97}
98
99ndk::ScopedAStatus Lights::getLights(std::vector<HwLight>* lights) {
100 for (auto i = mAvailableLights.begin(); i != mAvailableLights.end(); i++) {
101 lights->push_back(*i);
102 }
103 return ndk::ScopedAStatus::ok();
104}
105
106} // namespace light
107} // namespace hardware
108} // namespace android
109} // namespace aidl