blob: 6516dd4a32550bbf4160445e49ba55b01e1a5a6f [file] [log] [blame]
Jan Altensen53afa332019-07-09 22:43:47 +02001/*
2 * Copyright (C) 2019 The LineageOS Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#define LOG_TAG "android.hardware.light@2.0-service.samsung"
17
Jan Altensen83cc4602020-02-03 18:57:34 +010018#include <android-base/stringprintf.h>
Jan Altensen53afa332019-07-09 22:43:47 +020019#include <iomanip>
20
21#include "Light.h"
22
23#define COLOR_MASK 0x00ffffff
24#define MAX_INPUT_BRIGHTNESS 255
25
26using android::hardware::light::V2_0::LightState;
27using android::hardware::light::V2_0::Status;
28using android::hardware::light::V2_0::Type;
29
30namespace android {
31namespace hardware {
32namespace light {
33namespace V2_0 {
34namespace implementation {
35
36/*
37 * Write value to path and close file.
38 */
39template <typename T>
40static void set(const std::string& path, const T& value) {
41 std::ofstream file(path);
42 file << value << std::endl;
43}
44
45template <typename T>
46static T get(const std::string& path, const T& def) {
47 std::ifstream file(path);
48 T result;
49
50 file >> result;
51 return file.fail() ? def : result;
52}
53
54Light::Light() {
55 mLights.emplace(Type::BACKLIGHT,
56 std::bind(&Light::handleBacklight, this, std::placeholders::_1));
57#ifdef BUTTON_BRIGHTNESS_NODE
58 mLights.emplace(Type::BUTTONS, std::bind(&Light::handleButtons, this, std::placeholders::_1));
59#endif
60 mLights.emplace(Type::BATTERY, std::bind(&Light::handleBattery, this, std::placeholders::_1));
61 mLights.emplace(Type::NOTIFICATIONS,
62 std::bind(&Light::handleNotifications, this, std::placeholders::_1));
63 mLights.emplace(Type::ATTENTION,
64 std::bind(&Light::handleAttention, this, std::placeholders::_1));
65}
66
67Return<Status> Light::setLight(Type type, const LightState& state) {
68 auto it = mLights.find(type);
69
70 if (it == mLights.end()) {
71 return Status::LIGHT_NOT_SUPPORTED;
72 }
73
74 /*
75 * Lock global mutex until light state is updated.
76 */
77 std::lock_guard<std::mutex> lock(mLock);
78
79 it->second(state);
80
81 return Status::SUCCESS;
82}
83
84void Light::handleBacklight(const LightState& state) {
85 uint32_t max_brightness = get(PANEL_MAX_BRIGHTNESS_NODE, MAX_INPUT_BRIGHTNESS);
86 uint32_t brightness = rgbToBrightness(state);
87
88 if (max_brightness != MAX_INPUT_BRIGHTNESS) {
89 brightness = brightness * max_brightness / MAX_INPUT_BRIGHTNESS;
90 }
91
92 set(PANEL_BRIGHTNESS_NODE, brightness);
93}
94
95#ifdef BUTTON_BRIGHTNESS_NODE
96void Light::handleButtons(const LightState& state) {
97#ifdef VAR_BUTTON_BRIGHTNESS
98 uint32_t brightness = rgbToBrightness(state);
99#else
100 uint32_t brightness = (state.color & COLOR_MASK) ? 1 : 0;
101#endif
102
103 set(BUTTON_BRIGHTNESS_NODE, brightness);
104}
105#endif
106
107void Light::handleBattery(const LightState& state) {
108 mBatteryState = state;
109 setNotificationLED();
110}
111
112void Light::handleNotifications(const LightState& state) {
113 mNotificationState = state;
114 setNotificationLED();
115}
116
117void Light::handleAttention(const LightState& state) {
118 mAttentionState = state;
119 setNotificationLED();
120}
121
122void Light::setNotificationLED() {
123 int32_t adjusted_brightness = MAX_INPUT_BRIGHTNESS;
124 LightState state;
125#ifdef LED_BLN_NODE
126 bool bln = false;
127#endif
128
Jan Altensen7ffb4952019-08-07 11:33:32 +0200129 if (mNotificationState.color & COLOR_MASK) {
Jan Altensen53afa332019-07-09 22:43:47 +0200130 adjusted_brightness = LED_BRIGHTNESS_NOTIFICATION;
131 state = mNotificationState;
132#ifdef LED_BLN_NODE
133 bln = true;
134#endif
135 } else if (mAttentionState.color & COLOR_MASK) {
136 adjusted_brightness = LED_BRIGHTNESS_ATTENTION;
137 state = mAttentionState;
138 if (state.flashMode == Flash::HARDWARE) {
139 if (state.flashOnMs > 0 && state.flashOffMs == 0) state.flashMode = Flash::NONE;
140 state.color = 0x000000ff;
141 }
142 if (state.flashMode == Flash::NONE) {
143 state.color = 0;
144 }
Jan Altensen7ffb4952019-08-07 11:33:32 +0200145 } else if (mBatteryState.color & COLOR_MASK) {
146 adjusted_brightness = LED_BRIGHTNESS_BATTERY;
147 state = mBatteryState;
Jan Altensen53afa332019-07-09 22:43:47 +0200148 } else {
149 set(LED_BLINK_NODE, "0x00000000 0 0");
150 return;
151 }
152
153 if (state.flashMode == Flash::NONE) {
154 state.flashOnMs = 0;
155 state.flashOffMs = 0;
156 }
157
158 state.color = calibrateColor(state.color & COLOR_MASK, adjusted_brightness);
Jan Altensen83cc4602020-02-03 18:57:34 +0100159 set(LED_BLINK_NODE, android::base::StringPrintf("0x%08x %d %d", state.color, state.flashOnMs,
160 state.flashOffMs));
Jan Altensen53afa332019-07-09 22:43:47 +0200161
162#ifdef LED_BLN_NODE
163 if (bln) {
164 set(LED_BLN_NODE, (state.color & COLOR_MASK) ? 1 : 0);
165 }
166#endif
167}
168
169Return<void> Light::getSupportedTypes(getSupportedTypes_cb _hidl_cb) {
170 std::vector<Type> types;
171
172 for (auto const& light : mLights) {
173 types.push_back(light.first);
174 }
175
176 _hidl_cb(types);
177
178 return Void();
179}
180
181uint32_t Light::rgbToBrightness(const LightState& state) {
182 uint32_t color = state.color & COLOR_MASK;
183
184 return ((77 * ((color >> 16) & 0xff)) + (150 * ((color >> 8) & 0xff)) + (29 * (color & 0xff))) >>
185 8;
186}
187
188uint32_t Light::calibrateColor(uint32_t color, int32_t brightness) {
189 uint32_t red = ((color >> 16) & 0xFF) * LED_ADJUSTMENT_R;
190 uint32_t green = ((color >> 8) & 0xFF) * LED_ADJUSTMENT_G;
191 uint32_t blue = (color & 0xFF) * LED_ADJUSTMENT_B;
192
193 return (((red * brightness) / 255) << 16) + (((green * brightness) / 255) << 8) +
194 ((blue * brightness) / 255);
195}
196
197} // namespace implementation
198} // namespace V2_0
199} // namespace light
200} // namespace hardware
201} // namespace android