summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn S <shawnshen@google.com>2016-02-23 11:06:43 -0800
committerShawn Shen <shawnshen@google.com>2016-03-16 23:02:42 +0000
commit022637271d30cd5125ec402e2972b43c057ab953 (patch)
treefd84eeab02a0d6c5cabc71d34de6ac3a7fb0cd04
parent5030f0eb50039af1ec559a3f315c2b7a7b930080 (diff)
downloadexample-ledflasher-brillo-m10-dev.tar.gz
Updated ledflasher sample to use trait/component modelbrillo-m10-releasebrillo-m10-dev
- light schema onOff trait - dynamically add components based on available LEDs from lights HAL - custom trait _ledInfo to save lights HAL LED names BUG:26798554 Change-Id: I4c1dd0cdb2f3479703e9082fea152a713178e65c (cherry picked from commit 72d5a0e9b7fc812a880ab4e1f5795324e5ebf9a9)
-rw-r--r--src/common/aidl/brillo/examples/ledflasher/ILEDService.aidl3
-rw-r--r--src/ledflasher/animation.cpp4
-rw-r--r--src/ledflasher/animation.h2
-rw-r--r--src/ledflasher/animation_marquee.cpp3
-rw-r--r--src/ledflasher/etc/weaved/traits/ledflasher.json53
-rw-r--r--src/ledflasher/ledflasher.cpp145
-rw-r--r--src/ledservice/ledservice.cpp20
-rw-r--r--src/ledservice/ledstatus.cpp56
-rw-r--r--src/ledservice/ledstatus.h14
9 files changed, 181 insertions, 119 deletions
diff --git a/src/common/aidl/brillo/examples/ledflasher/ILEDService.aidl b/src/common/aidl/brillo/examples/ledflasher/ILEDService.aidl
index 5ec561b..84a5092 100644
--- a/src/common/aidl/brillo/examples/ledflasher/ILEDService.aidl
+++ b/src/common/aidl/brillo/examples/ledflasher/ILEDService.aidl
@@ -17,7 +17,10 @@
package brillo.examples.ledflasher;
interface ILEDService {
+ int getLEDCount();
void setLED(int ledIndex, boolean on);
boolean getLED(int ledIndex);
boolean[] getAllLEDs();
+ String[] getAllLEDNames();
+ void setAllLEDs(boolean on);
}
diff --git a/src/ledflasher/animation.cpp b/src/ledflasher/animation.cpp
index 34513d2..b76589e 100644
--- a/src/ledflasher/animation.cpp
+++ b/src/ledflasher/animation.cpp
@@ -25,6 +25,10 @@ Animation::Animation(
android::sp<brillo::examples::ledflasher::ILEDService> led_service,
const base::TimeDelta& step_duration)
: led_service_{led_service}, step_duration_{step_duration} {
+ int led_count;
+ led_service_->getLEDCount(&led_count);
+ num_leds = static_cast<size_t>(led_count);
+ step_duration_ /= num_leds;
}
Animation::~Animation() {
diff --git a/src/ledflasher/animation.h b/src/ledflasher/animation.h
index 190e9a6..30a3b40 100644
--- a/src/ledflasher/animation.h
+++ b/src/ledflasher/animation.h
@@ -39,9 +39,9 @@ class Animation {
const std::string& type,
const base::TimeDelta& duration);
- static const size_t num_leds = 4;
protected:
+ size_t num_leds;
virtual void DoAnimationStep() = 0;
bool GetLED(size_t index) const;
diff --git a/src/ledflasher/animation_marquee.cpp b/src/ledflasher/animation_marquee.cpp
index 77df265..37674e2 100644
--- a/src/ledflasher/animation_marquee.cpp
+++ b/src/ledflasher/animation_marquee.cpp
@@ -20,8 +20,7 @@ AnimationMarquee::AnimationMarquee(
android::sp<brillo::examples::ledflasher::ILEDService> led_service,
const base::TimeDelta& duration,
Direction direction)
- : Animation{led_service, duration / num_leds}, direction_{direction} {
-}
+ : Animation{led_service, duration}, direction_{direction} {}
void AnimationMarquee::DoAnimationStep() {
SetAllLEDs(false);
diff --git a/src/ledflasher/etc/weaved/traits/ledflasher.json b/src/ledflasher/etc/weaved/traits/ledflasher.json
index ff4ac68..0d5974a 100644
--- a/src/ledflasher/etc/weaved/traits/ledflasher.json
+++ b/src/ledflasher/etc/weaved/traits/ledflasher.json
@@ -1,27 +1,6 @@
{
"_ledflasher": {
"commands": {
- "set": {
- "minimalRole": "user",
- "parameters": {
- "led": {
- "type": "integer",
- "minimum": 1,
- "maximum": 4
- },
- "on": { "type": "boolean" }
- }
- },
- "toggle": {
- "minimalRole": "user",
- "parameters": {
- "led": {
- "type": "integer",
- "minimum": 1,
- "maximum": 4
- }
- }
- },
"animate": {
"minimalRole": "user",
"parameters": {
@@ -41,10 +20,34 @@
"status": {
"type": "string",
"enum": [ "idle", "animating" ]
- },
- "leds": {
- "type": "array",
- "items": { "type": "boolean" }
+ }
+ }
+ },
+ "onOff": {
+ "commands": {
+ "setConfig": {
+ "minimalRole": "user",
+ "parameters": {
+ "state": {
+ "type": "string",
+ "enum": [ "on", "off" ]
+ }
+ }
+ }
+ },
+ "state": {
+ "state": {
+ "isRequired": true,
+ "type": "string",
+ "enum": [ "on", "off" ]
+ }
+ }
+ },
+ "_ledInfo": {
+ "state": {
+ "name": {
+ "isRequired": true,
+ "type": "string"
}
}
}
diff --git a/src/ledflasher/ledflasher.cpp b/src/ledflasher/ledflasher.cpp
index de495f3..bce3420 100644
--- a/src/ledflasher/ledflasher.cpp
+++ b/src/ledflasher/ledflasher.cpp
@@ -31,11 +31,16 @@
#include "binder_constants.h"
#include "brillo/examples/ledflasher/ILEDService.h"
+using android::String16;
+
namespace {
-const char kWeaveComponent[] = "ledflasher";
-const char kWeaveTrait[] = "_ledflasher";
+const char kLedFlasherComponent[] = "ledflasher";
+const char kLedFlasherTrait[] = "_ledflasher";
const char kBaseComponent[] = "base";
const char kBaseTrait[] = "base";
+const char kLedComponentPrefix[] = "led";
+const char kOnOffTrait[] = "onOff";
+const char kLedInfoTrait[] = "_ledInfo";
} // anonymous namespace
using brillo::examples::ledflasher::ILEDService;
@@ -52,10 +57,10 @@ class Daemon final : public brillo::Daemon {
void ConnectToLEDService();
void OnLEDServiceDisconnected();
void OnPairingInfoChanged(const weaved::Service::PairingInfo* pairing_info);
+ void CreateLedComponentsIfNeeded();
// Particular command handlers for various commands.
- void OnSet(std::unique_ptr<weaved::Command> command);
- void OnToggle(std::unique_ptr<weaved::Command> command);
+ void OnSetConfig(size_t led_index, std::unique_ptr<weaved::Command> command);
void OnAnimate(std::unique_ptr<weaved::Command> command);
void OnIdentify(std::unique_ptr<weaved::Command> command);
@@ -80,6 +85,8 @@ class Daemon final : public brillo::Daemon {
brillo::BinderWatcher binder_watcher_;
std::unique_ptr<weaved::Service::Subscription> weave_service_subscription_;
+ bool led_components_added_{false};
+
base::WeakPtrFactory<Daemon> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(Daemon);
};
@@ -111,15 +118,12 @@ void Daemon::OnWeaveServiceConnected(
if (!weave_service)
return;
- weave_service->AddComponent(kWeaveComponent, {kWeaveTrait}, nullptr);
- weave_service->AddCommandHandler(
- kWeaveComponent, kWeaveTrait, "set",
- base::Bind(&Daemon::OnSet, weak_ptr_factory_.GetWeakPtr()));
+ weave_service->AddComponent(
+ kLedFlasherComponent, {kLedFlasherTrait}, nullptr);
weave_service->AddCommandHandler(
- kWeaveComponent, kWeaveTrait, "toggle",
- base::Bind(&Daemon::OnToggle, weak_ptr_factory_.GetWeakPtr()));
- weave_service->AddCommandHandler(
- kWeaveComponent, kWeaveTrait, "animate",
+ kLedFlasherComponent,
+ kLedFlasherTrait,
+ "animate",
base::Bind(&Daemon::OnAnimate, weak_ptr_factory_.GetWeakPtr()));
weave_service->AddCommandHandler(
kBaseComponent, kBaseTrait, "identify",
@@ -129,6 +133,8 @@ void Daemon::OnWeaveServiceConnected(
base::Bind(&Daemon::OnPairingInfoChanged,
weak_ptr_factory_.GetWeakPtr()));
+ led_components_added_ = false;
+ CreateLedComponentsIfNeeded();
UpdateDeviceState();
}
@@ -147,61 +153,92 @@ void Daemon::ConnectToLEDService() {
base::Bind(&Daemon::OnLEDServiceDisconnected,
weak_ptr_factory_.GetWeakPtr()));
led_service_ = android::interface_cast<ILEDService>(binder);
+ CreateLedComponentsIfNeeded();
UpdateDeviceState();
}
+void Daemon::CreateLedComponentsIfNeeded() {
+ if (led_components_added_ || !led_service_.get())
+ return;
+
+ auto weave_service = weave_service_.lock();
+ if (!weave_service)
+ return;
+
+ std::vector<bool> leds;
+ std::vector<String16> ledNames;
+ if (!led_service_->getAllLEDs(&leds).isOk())
+ return;
+
+ if (!led_service_->getAllLEDNames(&ledNames).isOk())
+ return;
+
+ for (size_t led_index = 0; led_index < leds.size(); led_index++) {
+ std::string led_name = android::String8{ledNames[led_index]}.string();
+ std::string component_name =
+ kLedComponentPrefix + std::to_string(led_index + 1);
+ if (weave_service->AddComponent(
+ component_name, {kOnOffTrait, kLedInfoTrait}, nullptr)) {
+ weave_service->AddCommandHandler(
+ component_name,
+ kOnOffTrait,
+ "setConfig",
+ base::Bind(
+ &Daemon::OnSetConfig, weak_ptr_factory_.GetWeakPtr(), led_index));
+
+ weave_service->SetStateProperty(
+ component_name,
+ kOnOffTrait,
+ "state",
+ *brillo::ToValue(leds[led_index] ? "on" : "off"),
+ nullptr);
+
+ weave_service->SetStateProperty(component_name,
+ kLedInfoTrait,
+ "name",
+ *brillo::ToValue(led_name),
+ nullptr);
+ }
+ }
+ led_components_added_ = true;
+}
+
void Daemon::OnLEDServiceDisconnected() {
animation_.reset();
led_service_ = nullptr;
ConnectToLEDService();
}
-void Daemon::OnSet(std::unique_ptr<weaved::Command> command) {
+void Daemon::OnSetConfig(size_t led_index,
+ std::unique_ptr<weaved::Command> command) {
if (!led_service_.get()) {
command->Abort("_system_error", "ledservice unavailable", nullptr);
return;
}
- int index = command->GetParameter<int>("led");
- if(index < 1 || index > 4) {
- command->Abort("_invalid_parameter", "Invalid parameter value", nullptr);
- return;
- }
- bool on = command->GetParameter<bool>("on");
- android::binder::Status status = led_service_->setLED(index - 1, on);
+ auto state = command->GetParameter<std::string>("state");
+ bool on = (state == "on");
+ android::binder::Status status = led_service_->setLED(led_index, on);
if (!status.isOk()) {
command->AbortWithCustomError(status, nullptr);
return;
}
- animation_.reset();
- status_ = "idle";
- UpdateDeviceState();
- command->Complete({}, nullptr);
-}
-
-void Daemon::OnToggle(std::unique_ptr<weaved::Command> command) {
- if (!led_service_.get()) {
- command->Abort("_system_error", "ledservice unavailable", nullptr);
- return;
+ if (animation_) {
+ animation_.reset();
+ status_ = "idle";
+ UpdateDeviceState();
}
- int index = command->GetParameter<int>("led");
- if(index < 1 || index > 4) {
- command->Abort("_invalid_parameter", "Invalid parameter value", nullptr);
- return;
- }
- index--;
- bool on = false;
- android::binder::Status status = led_service_->getLED(index, &on);
- if (status.isOk())
- status = led_service_->setLED(index, !on);
- if(!status.isOk()) {
- command->AbortWithCustomError(status, nullptr);
- return;
+ auto weave_service = weave_service_.lock();
+ if (weave_service) {
+ std::string component_name =
+ kLedComponentPrefix + std::to_string(led_index + 1);
+ weave_service->SetStateProperty(component_name,
+ kOnOffTrait,
+ "state",
+ *brillo::ToValue(on ? "on" : "off"),
+ nullptr);
}
- animation_.reset();
- status_ = "idle";
- UpdateDeviceState();
command->Complete({}, nullptr);
}
@@ -263,21 +300,15 @@ void Daemon::StopAnimation() {
}
void Daemon::UpdateDeviceState() {
- if (!led_service_.get())
- return;
-
- std::vector<bool> leds;
- if (!led_service_->getAllLEDs(&leds).isOk())
- return;
-
auto weave_service = weave_service_.lock();
if (!weave_service)
return;
- base::DictionaryValue state_change;
- state_change.SetString("_ledflasher.status", status_);
- state_change.Set("_ledflasher.leds", brillo::ToValue(leds).release());
- weave_service->SetStateProperties(kWeaveComponent, state_change, nullptr);
+ weave_service->SetStateProperty(kLedFlasherComponent,
+ kLedFlasherTrait,
+ "status",
+ *brillo::ToValue(status_),
+ nullptr);
}
int main(int argc, char* argv[]) {
diff --git a/src/ledservice/ledservice.cpp b/src/ledservice/ledservice.cpp
index cdc2924..065606a 100644
--- a/src/ledservice/ledservice.cpp
+++ b/src/ledservice/ledservice.cpp
@@ -29,8 +29,15 @@
#include "brillo/examples/ledflasher/BnLEDService.h"
#include "ledstatus.h"
+using android::String16;
+
class LEDService : public brillo::examples::ledflasher::BnLEDService {
public:
+ android::binder::Status getLEDCount(int32_t* count) override {
+ *count = leds_.GetLedCount();
+ return android::binder::Status::ok();
+ }
+
android::binder::Status setLED(int32_t ledIndex, bool on) override {
leds_.SetLedStatus(ledIndex, on);
return android::binder::Status::ok();
@@ -46,6 +53,19 @@ class LEDService : public brillo::examples::ledflasher::BnLEDService {
return android::binder::Status::ok();
}
+ android::binder::Status getAllLEDNames(std::vector<String16>* leds) override {
+ std::vector<std::string> ledNames = leds_.GetNames();
+ for (const std::string& name : ledNames) {
+ leds->push_back(String16{name.c_str()});
+ }
+ return android::binder::Status::ok();
+ }
+
+ android::binder::Status setAllLEDs(bool on) override {
+ leds_.SetAllLeds(on);
+ return android::binder::Status::ok();
+ }
+
private:
LedStatus leds_;
};
diff --git a/src/ledservice/ledstatus.cpp b/src/ledservice/ledstatus.cpp
index 6ce65c6..f62c77c 100644
--- a/src/ledservice/ledstatus.cpp
+++ b/src/ledservice/ledstatus.cpp
@@ -30,7 +30,6 @@
namespace {
brillo::StreamPtr GetLEDDataStream(size_t index, bool write) {
- CHECK(index < LedStatus::num_leds);
std::string led_path;
if( index == 3 ) {
led_path = "/sys/class/leds/boot/brightness";
@@ -48,7 +47,7 @@ brillo::StreamPtr GetLEDDataStream(size_t index, bool write) {
} // anonymous namespace
LedStatus::LedStatus() {
- // Try to open the lights hal.
+ // 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.";
@@ -57,14 +56,12 @@ LedStatus::LedStatus() {
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.
+ // If we can open the HAL, then we map each number to one of the LEDs
+ // available on the board.
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(
@@ -74,41 +71,39 @@ LedStatus::LedStatus() {
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;
- }
+ hal_leds_.push_back(light_name);
+ hal_led_status_.push_back(false);
}
- // If the size of the map is zero, then the lights hal doesn't have any valid
+ // 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.";
+ if (hal_leds_.empty()) {
+ LOG(INFO) << "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);
+size_t LedStatus::GetLedCount() const {
+ return lights_hal_ ? hal_leds_.size() : 1;
}
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++)
+ std::vector<bool> leds(GetLedCount());
+ for (size_t index = 0; index < GetLedCount(); index++)
leds[index] = IsLedOn(index);
return leds;
}
+std::vector<std::string> LedStatus::GetNames() const {
+ return lights_hal_ ? hal_leds_ : std::vector<std::string>(GetLedCount());
+}
+
bool LedStatus::IsLedOn(size_t index) const {
+ CHECK(index < GetLedCount());
if (lights_hal_)
return hal_led_status_[index];
@@ -132,6 +127,7 @@ bool LedStatus::IsLedOn(size_t index) const {
}
void LedStatus::SetLedStatus(size_t index, bool on) {
+ CHECK(index < GetLedCount());
if (lights_hal_) {
light_state_t state = {};
state.color = on;
@@ -141,23 +137,24 @@ void LedStatus::SetLedStatus(size_t index, bool on) {
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(),
+ lights_hal_,
+ hal_leds_[index].c_str(),
reinterpret_cast<hw_device_t**>(&light_device));
if (rc) {
- LOG(ERROR) << "Unable to open " << hal_led_map_[index];
+ LOG(ERROR) << "Unable to open " << hal_leds_[index];
return;
}
CHECK(light_device);
rc = light_device->set_light(light_device, &state);
if (rc) {
- LOG(ERROR) << "Unable to set " << hal_led_map_[index];
+ LOG(ERROR) << "Unable to set " << hal_leds_[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];
+ LOG(ERROR) << "Unable to close " << hal_leds_[index];
return;
}
return;
@@ -170,3 +167,8 @@ void LedStatus::SetLedStatus(size_t index, bool on) {
std::string brightness = on ? "255" : "0";
stream->WriteAllBlocking(brightness.data(), brightness.size(), nullptr);
}
+
+void LedStatus::SetAllLeds(bool on) {
+ for (size_t i = 0; i < GetLedCount(); i++)
+ SetLedStatus(i, on);
+}
diff --git a/src/ledservice/ledstatus.h b/src/ledservice/ledstatus.h
index dc9a472..8e9c26a 100644
--- a/src/ledservice/ledstatus.h
+++ b/src/ledservice/ledstatus.h
@@ -17,7 +17,7 @@
#ifndef LEDFLASHER_SRC_LEDSERVICE_LEDSTATUS_H_
#define LEDFLASHER_SRC_LEDSERVICE_LEDSTATUS_H_
-#include <map>
+#include <string>
#include <vector>
#include <base/macros.h>
@@ -28,17 +28,17 @@ class LedStatus final {
LedStatus();
std::vector<bool> GetStatus() const;
+ std::vector<std::string> GetNames() const;
bool IsLedOn(size_t index) const;
void SetLedStatus(size_t index, bool on);
-
- static const size_t num_leds = 4;
+ void SetAllLeds(bool on);
+ size_t GetLedCount() const;
private:
const hw_module_t* lights_hal_{nullptr};
- // Maps the lights available to the hal to numbers 1 - 4. It is possible for
- // multiple numbers to be mapped to the same led on the board.
- std::map<size_t, std::string> hal_led_map_;
- // Since the hal doesn't have a way to track the led status, we maintain that
+ // Contains the names of LEDs in the HAL for each of supported LEDs.
+ std::vector<std::string> hal_leds_;
+ // Since the HAL doesn't have a way to track the led status, we maintain that
// info here.
std::vector<bool> hal_led_status_;