diff options
Diffstat (limited to 'src/ledservice/ledstatus.cpp')
-rw-r--r-- | src/ledservice/ledstatus.cpp | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/ledservice/ledstatus.cpp b/src/ledservice/ledstatus.cpp index 5fac42c..a51ea2a 100644 --- a/src/ledservice/ledstatus.cpp +++ b/src/ledservice/ledstatus.cpp @@ -47,7 +47,61 @@ brillo::StreamPtr GetLEDDataStream(size_t index, bool write) { } // anonymous namespace +LedStatus::LedStatus() { + // Try to open the lights hal. + int ret = hw_get_module(LIGHTS_HARDWARE_MODULE_ID, &lights_hal_); + if (ret) { + LOG(ERROR) << "Failed to load the lights HAL."; + return; + } + CHECK(lights_hal_); + LOG(INFO) << "Loaded lights HAL."; + + // If we can open the hal, then we map each number from 1 - 4 to one of the + // leds available on the board. Note, multiple numbers could be mapped to the + // same led. + const std::initializer_list<const char*> kLogicalLights = { + LIGHT_ID_BACKLIGHT, LIGHT_ID_KEYBOARD, LIGHT_ID_BUTTONS, LIGHT_ID_BATTERY, + LIGHT_ID_NOTIFICATIONS, LIGHT_ID_ATTENTION, LIGHT_ID_BLUETOOTH, + LIGHT_ID_WIFI}; + size_t led_index = 0; + for (const char* light_name : kLogicalLights) { + light_device_t* light_device = nullptr; + ret = lights_hal_->methods->open( + lights_hal_, light_name, + reinterpret_cast<hw_device_t**>(&light_device)); + // If a given light device couldn't be opened, don't map it to a number. + if (ret || !light_device) { + continue; + } + hal_led_map_.emplace(led_index, light_name); + led_index++; + if (led_index == num_leds) { + // We have already mapped all num_leds LEDs. + break; + } + } + + // If the size of the map is zero, then the lights hal doesn't have any valid + // leds. + if (hal_led_map_.empty()) { + LOG(ERROR) << "Unable to open any light devices using the hal."; + lights_hal_ = nullptr; + return; + } + + // If not all 4 numbers have been mapped, then we map them to the first led + // mapped. + for (size_t i = hal_led_map_.size(); i < num_leds; i++) { + hal_led_map_.emplace(i, hal_led_map_[0]); + } + hal_led_status_.resize(num_leds); +} + std::vector<bool> LedStatus::GetStatus() const { + if (lights_hal_) + return hal_led_status_; + std::vector<bool> leds(num_leds); for (size_t index = 0; index < num_leds; index++) leds[index] = IsLedOn(index); @@ -75,6 +129,37 @@ bool LedStatus::IsLedOn(size_t index) const { } void LedStatus::SetLedStatus(size_t index, bool on) { + if (lights_hal_) { + light_state_t state = {}; + state.color = on; + state.flashMode = LIGHT_FLASH_NONE; + state.flashOnMS = 0; + state.flashOffMS = 0; + state.brightnessMode = BRIGHTNESS_MODE_USER; + light_device_t* light_device = nullptr; + int rc = lights_hal_->methods->open( + lights_hal_, hal_led_map_[index].c_str(), + reinterpret_cast<hw_device_t**>(&light_device)); + if (rc) { + LOG(ERROR) << "Unable to open " << hal_led_map_[index]; + return; + } + CHECK(light_device); + rc = light_device->set_light(light_device, &state); + if (rc) { + LOG(ERROR) << "Unable to set " << hal_led_map_[index]; + return; + } + hal_led_status_[index] = on; + light_device->common.close( + reinterpret_cast<hw_device_t*>(light_device)); + if (rc) { + LOG(ERROR) << "Unable to close " << hal_led_map_[index]; + return; + } + return; + } + brillo::StreamPtr stream = GetLEDDataStream(index, true); if (!stream) return; |