aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBertrand SIMONNET <bsimonnet@google.com>2016-03-14 13:56:31 -0700
committerLee Campbell <leecam@google.com>2016-03-15 16:31:18 +0000
commit7d12dacad6018701dac2b1a1b3e378d295ffe544 (patch)
tree06b519837779c3f4a1566b50b5d4a4369a9892c9
parenta733d4aefdba57cd752783e19db1b0f906ff2877 (diff)
downloadperipheralmanager-7d12dacad6018701dac2b1a1b3e378d295ffe544.tar.gz
Expose the Led interface to the user.
This CL adds: * LED support in the AIDL interface. * LED support and implementation in the C API. * an example blinking an LED. Bug: 27580067 Change-Id: Ia8334006626c2683aa8ce40b0b90efc32585a29c
-rw-r--r--client/Android.mk1
-rw-r--r--client/led_impl.cc51
-rw-r--r--client/led_impl.h40
-rw-r--r--client/peripheral_manager_client_impl.cc13
-rw-r--r--client/peripheral_manager_client_impl.h4
-rw-r--r--client/wrapper.cc42
-rw-r--r--daemon/peripheral_manager_client.cc63
-rw-r--r--daemon/peripheral_manager_client.h15
-rw-r--r--example/Android.mk16
-rw-r--r--example/led_example.cc94
-rw-r--r--include/peripheralmanager/led.h60
-rw-r--r--include/peripheralmanager/peripheral_manager_client.h17
-rw-r--r--ipc/android/os/IPeripheralManagerClient.aidl12
13 files changed, 428 insertions, 0 deletions
diff --git a/client/Android.mk b/client/Android.mk
index fc47b21..6a98485 100644
--- a/client/Android.mk
+++ b/client/Android.mk
@@ -42,6 +42,7 @@ LOCAL_SHARED_LIBRARIES := $(libperipheralman_CommonSharedLibraries)
LOCAL_STATIC_LIBRARIES := libperipheralman_binder
LOCAL_SRC_FILES := \
gpio_impl.cc \
+ led_impl.cc \
peripheral_manager_client_impl.cc \
spi_device_impl.cc \
wrapper.cc \
diff --git a/client/led_impl.cc b/client/led_impl.cc
new file mode 100644
index 0000000..d964a80
--- /dev/null
+++ b/client/led_impl.cc
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+#include <led_impl.h>
+
+using android::binder::Status;
+using android::os::IPeripheralManagerClient;
+using android::sp;
+
+LedImpl::LedImpl(const std::string& name, sp<IPeripheralManagerClient> client)
+ : name_(name), client_(client) {}
+
+LedImpl::~LedImpl() {
+ client_->ReleaseLed(name_);
+}
+
+int LedImpl::GetBrightness(uint32_t* brightness) {
+ int val;
+ Status status = client_->LedGetBrightness(name_, &val);
+ if (!status.isOk())
+ *brightness = static_cast<uint32_t>(val);
+
+ return status.serviceSpecificErrorCode();
+}
+
+int LedImpl::GetMaxBrightness(uint32_t* max_brightness) {
+ int val;
+ Status status = client_->LedGetMaxBrightness(name_, &val);
+ if (!status.isOk())
+ *max_brightness = static_cast<uint32_t>(val);
+
+ return status.serviceSpecificErrorCode();
+}
+
+int LedImpl::SetBrightness(uint32_t brightness) {
+ return client_->LedSetBrightness(name_, brightness)
+ .serviceSpecificErrorCode();
+}
diff --git a/client/led_impl.h b/client/led_impl.h
new file mode 100644
index 0000000..f848864
--- /dev/null
+++ b/client/led_impl.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#ifndef SYSTEM_PERIPHERALMANAGER_LED_IMPL_H_
+#define SYSTEM_PERIPHERALMANAGER_LED_IMPL_H_
+
+#include <string>
+
+#include <android/os/IPeripheralManagerClient.h>
+#include <utils/StrongPointer.h>
+
+class LedImpl {
+ public:
+ LedImpl(const std::string& name,
+ android::sp<android::os::IPeripheralManagerClient> client);
+ ~LedImpl();
+
+ int GetBrightness(uint32_t* brightness);
+ int GetMaxBrightness(uint32_t* max_brightness);
+ int SetBrightness(uint32_t brightness);
+
+ private:
+ std::string name_;
+ android::sp<android::os::IPeripheralManagerClient> client_;
+};
+
+#endif // SYSTEM_PERIPHERALMANAGER_LED_IMPL_H_
diff --git a/client/peripheral_manager_client_impl.cc b/client/peripheral_manager_client_impl.cc
index eb1f5f5..af44804 100644
--- a/client/peripheral_manager_client_impl.cc
+++ b/client/peripheral_manager_client_impl.cc
@@ -58,3 +58,16 @@ int PeripheralManagerClientImpl::ListSpiBuses(std::vector<std::string>* buses) {
Status status = client_->ListSpiBuses(buses);
return status.serviceSpecificErrorCode();
}
+
+int PeripheralManagerClientImpl::ListLeds(std::vector<std::string>* leds) {
+ return client_->ListLeds(leds).serviceSpecificErrorCode();
+}
+
+int PeripheralManagerClientImpl::OpenLed(const std::string& name,
+ std::unique_ptr<LedImpl>* led) {
+ Status status = client_->OpenLed(name);
+ if (status.isOk()) {
+ led->reset(new LedImpl(name, client_));
+ }
+ return status.serviceSpecificErrorCode();
+}
diff --git a/client/peripheral_manager_client_impl.h b/client/peripheral_manager_client_impl.h
index 3a3000d..80d3492 100644
--- a/client/peripheral_manager_client_impl.h
+++ b/client/peripheral_manager_client_impl.h
@@ -21,6 +21,7 @@
#include <utils/StrongPointer.h>
#include "gpio_impl.h"
+#include "led_impl.h"
#include "spi_device_impl.h"
class PeripheralManagerClientImpl {
@@ -36,6 +37,9 @@ class PeripheralManagerClientImpl {
std::unique_ptr<SpiDeviceImpl>* device);
int ListSpiBuses(std::vector<std::string>* buses);
+ int OpenLed(const std::string& name, std::unique_ptr<LedImpl>* device);
+ int ListLeds(std::vector<std::string>* leds);
+
private:
android::sp<android::os::IPeripheralManagerClient> client_;
android::sp<android::IBinder> lifeline_;
diff --git a/client/wrapper.cc b/client/wrapper.cc
index 2e08dca..e7e800d 100644
--- a/client/wrapper.cc
+++ b/client/wrapper.cc
@@ -18,8 +18,10 @@
#include <memory>
#include "gpio_impl.h"
+#include "led_impl.h"
#include "peripheral_manager_client_impl.h"
#include "peripheralmanager/peripheral_manager_client.h"
+#include "spi_device_impl.h"
namespace {
@@ -48,6 +50,10 @@ struct BSpiDevice {
SpiDeviceImpl* impl;
};
+struct BLed {
+ LedImpl* impl;
+};
+
BPeripheralManagerClient* BPeripheralManagerClient_new() {
std::unique_ptr<PeripheralManagerClientImpl> impl(
new PeripheralManagerClientImpl);
@@ -191,3 +197,39 @@ void BSpiDevice_delete(BSpiDevice* device) {
delete device->impl;
delete device;
}
+
+char** BPeripheralManagerClient_listLed(const BPeripheralManagerClient* client,
+ int* num_leds) {
+ std::vector<std::string> list;
+ client->impl->ListLeds(&list);
+ *num_leds = list.size();
+ return ConvertStringVectorToC(list);
+}
+
+int BPeripheralManagerClient_openLed(const BPeripheralManagerClient* client,
+ const char* name,
+ BLed** led) {
+ std::unique_ptr<LedImpl> impl;
+ int ret = client->impl->OpenLed(name, &impl);
+ if (!ret)
+ *led = new BLed{impl.release()};
+
+ return ret;
+}
+
+int BLed_setBrightness(const BLed* led, uint32_t brightness) {
+ return led->impl->SetBrightness(brightness);
+}
+
+int BLed_getBrightness(const BLed* led, uint32_t* brightness) {
+ return led->impl->GetBrightness(brightness);
+}
+
+int BLed_getMaxBrightness(const BLed* led, uint32_t* max_brightness) {
+ return led->impl->GetMaxBrightness(max_brightness);
+}
+
+void BLed_delete(BLed* led) {
+ delete led->impl;
+ delete led;
+}
diff --git a/daemon/peripheral_manager_client.cc b/daemon/peripheral_manager_client.cc
index 5eaa2e5..128700b 100644
--- a/daemon/peripheral_manager_client.cc
+++ b/daemon/peripheral_manager_client.cc
@@ -235,4 +235,67 @@ Status PeripheralManagerClient::SpiDeviceSetBitsPerWord(const std::string& name,
return Status::fromServiceSpecificError(EREMOTEIO);
}
+Status PeripheralManagerClient::ListLeds(std::vector<std::string>* leds) {
+ *leds = LedManager::GetLedManager()->GetLeds();
+ return Status::ok();
+}
+
+Status PeripheralManagerClient::OpenLed(const std::string& name) {
+ if (!LedManager::GetLedManager()->HasLed(name)) {
+ return Status::fromServiceSpecificError(ENODEV);
+ }
+ auto led = LedManager::GetLedManager()->OpenLed(name);
+ if (!led) {
+ LOG(ERROR) << "Failed to open LED" << name;
+ return Status::fromServiceSpecificError(EBUSY);
+ }
+
+ leds_.emplace(name, std::move(led));
+ return Status::ok();
+}
+
+Status PeripheralManagerClient::ReleaseLed(const std::string& name) {
+ leds_.erase(name);
+ return Status::ok();
+}
+
+Status PeripheralManagerClient::LedGetBrightness(const std::string& name,
+ int* brightness) {
+ if (!leds_.count(name))
+ return Status::fromServiceSpecificError(EPERM);
+
+ uint32_t temp;
+ if (leds_.find(name)->second->GetBrightness(&temp)) {
+ *brightness = temp;
+ return Status::ok();
+ }
+
+ return Status::fromServiceSpecificError(EREMOTEIO);
+}
+
+Status PeripheralManagerClient::LedGetMaxBrightness(const std::string& name,
+ int* max_brightness) {
+ if (!leds_.count(name))
+ return Status::fromServiceSpecificError(EPERM);
+
+ uint32_t temp;
+ if (leds_.find(name)->second->GetMaxBrightness(&temp)) {
+ *max_brightness = temp;
+ return Status::ok();
+ }
+
+ return Status::fromServiceSpecificError(EREMOTEIO);
+}
+
+Status PeripheralManagerClient::LedSetBrightness(const std::string& name,
+ int brightness) {
+ if (!leds_.count(name))
+ return Status::fromServiceSpecificError(EPERM);
+
+ if (leds_.find(name)->second->SetBrightness(brightness))
+ return Status::ok();
+
+ return Status::fromServiceSpecificError(EREMOTEIO);
+}
+
} // namespace android
diff --git a/daemon/peripheral_manager_client.h b/daemon/peripheral_manager_client.h
index 4d57ba6..8b15618 100644
--- a/daemon/peripheral_manager_client.h
+++ b/daemon/peripheral_manager_client.h
@@ -26,6 +26,7 @@
#include <android/os/BnPeripheralManagerClient.h>
#include "gpio_manager.h"
+#include "led_manager.h"
#include "spi_manager.h"
using android::binder::Status;
@@ -90,9 +91,23 @@ class PeripheralManagerClient : public BnPeripheralManagerClient {
virtual Status SpiDeviceSetBitsPerWord(const std::string& name,
int nbits) override;
+ virtual Status ListLeds(std::vector<std::string>* leds) override;
+
+ virtual Status OpenLed(const std::string& name) override;
+
+ virtual Status ReleaseLed(const std::string& name) override;
+
+ virtual Status LedGetBrightness(const std::string& name,
+ int* brightness) override;
+ virtual Status LedGetMaxBrightness(const std::string& name,
+ int* max_brightness) override;
+ virtual Status LedSetBrightness(const std::string& name,
+ int brightness) override;
+
private:
std::map<std::string, std::unique_ptr<GpioPin>> gpios_;
std::map<std::string, std::unique_ptr<SpiDevice>> spi_devices_;
+ std::map<std::string, std::unique_ptr<Led>> leds_;
DISALLOW_COPY_AND_ASSIGN(PeripheralManagerClient);
};
diff --git a/example/Android.mk b/example/Android.mk
index c807cf9..eb9b3f5 100644
--- a/example/Android.mk
+++ b/example/Android.mk
@@ -69,3 +69,19 @@ LOCAL_SRC_FILES := \
pio_flash_apa10c.cc \
include $(BUILD_EXECUTABLE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := peripheralman_blink_led
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter
+LOCAL_CFLAGS += -Wno-sign-promo # for libchrome
+LOCAL_SHARED_LIBRARIES := \
+ libbrillo \
+ libchrome \
+ libperipheralman \
+ libutils \
+
+LOCAL_SRC_FILES := \
+ led_example.cc \
+
+include $(BUILD_EXECUTABLE)
diff --git a/example/led_example.cc b/example/led_example.cc
new file mode 100644
index 0000000..70a374d
--- /dev/null
+++ b/example/led_example.cc
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+#include <unistd.h>
+
+#include <memory>
+
+#include <base/logging.h>
+#include <brillo/flag_helper.h>
+
+#include <peripheralmanager/peripheral_manager_client.h>
+
+int main(int argc, char* argv[]) {
+ DEFINE_string(led, "", "Led to toggle");
+ brillo::FlagHelper::Init(argc, argv, "Example client blinking a light.");
+ logging::InitLogging(logging::LoggingSettings());
+
+ if (FLAGS_led.empty()) {
+ LOG(ERROR) << "Led name not specified.";
+ return 1;
+ }
+
+ LOG(INFO) << "Blinking " << FLAGS_led;
+
+ // Get a client to the PeripheralManager.
+ BPeripheralManagerClient* client = BPeripheralManagerClient_new();
+
+ if (!client) {
+ LOG(ERROR) << "Failed to connect to client";
+ return 1;
+ }
+
+ // Open the LED.
+ BLed* led;
+ int ret = BPeripheralManagerClient_openLed(client, FLAGS_led.c_str(), &led);
+ if (ret) {
+ LOG(ERROR) << "Failed to open LED: " << strerror(ret);
+ return 1;
+ }
+
+ uint32_t max_brightness = 0;
+
+ // Get the maximum brightness possible.
+ ret = BLed_getMaxBrightness(led, &max_brightness);
+ if (ret) {
+ LOG(ERROR) << "Failed to get the maximum brightness: " << strerror(ret);
+ return 1;
+ }
+
+ // Toggle the output.
+ BLed_setBrightness(led, 0);
+ sleep(1);
+ BLed_setBrightness(led, max_brightness / 2);
+ sleep(1);
+ BLed_setBrightness(led, max_brightness);
+ sleep(1);
+ BLed_setBrightness(led, max_brightness / 2);
+ sleep(1);
+ BLed_setBrightness(led, 0);
+
+ // Make sure the led is turned off.
+ uint32_t brightness;
+ ret = BLed_getBrightness(led, &brightness);
+ if (ret) {
+ LOG(ERROR) << "Failed to read the brightness: " << strerror(ret);
+ return 1;
+ }
+
+ if (brightness != 0) {
+ LOG(ERROR) << "Failed to turn the LED off, led is at: " << brightness;
+ }
+
+ // Release the LED
+ BLed_delete(led);
+
+ // Close the connection to PeripheralManager.
+ BPeripheralManagerClient_delete(client);
+
+ LOG(INFO) << "Exiting";
+ return 0;
+}
diff --git a/include/peripheralmanager/led.h b/include/peripheralmanager/led.h
new file mode 100644
index 0000000..c8cc19b
--- /dev/null
+++ b/include/peripheralmanager/led.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+#ifndef SYSTEM_PERIPHERALMANAGER_LED_H_
+#define SYSTEM_PERIPHERALMANAGER_LED_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+/// @defgroup Led Led Interface
+/// @brief Functions to control onboard LEDs.
+///
+/// These functions can be used to query and control LEDs.
+/// @{
+
+typedef struct BLed BLed;
+
+/// Sets the LED brightness.
+/// @param led Pointer to the BLed object.
+/// @param brightness Brightness to set. If the brightness exceeds the maximum
+/// brightness supported, sets the maximum supported.
+/// @return 0 on success, errno on error.
+int BLed_setBrightness(const BLed* led, uint32_t brightness);
+
+/// Gets the LED brightness.
+/// @param led Pointer to the BLed object.
+/// @param brightness Output pointer to the current brightness.
+/// @return 0 on success, errno on error.
+int BLed_getBrightness(const BLed* led, uint32_t* brightness);
+
+/// Gets the LED max brightness.
+/// @param led Pointer to the BLed object.
+/// @param max_brightness Output pointer to the maximum brightness supported.
+/// @return 0 on success, errno on error.
+int BLed_getMaxBrightness(const BLed* led, uint32_t* max_brightness);
+
+/// Destroys a BLed object.
+/// @param led Pointer to the BLed object to destroy.
+void BLed_delete(BLed* led);
+
+/// @}
+
+__END_DECLS
+
+#endif // SYSTEM_PERIPHERALMANAGER_LED_H_
diff --git a/include/peripheralmanager/peripheral_manager_client.h b/include/peripheralmanager/peripheral_manager_client.h
index 36159c3..bb76099 100644
--- a/include/peripheralmanager/peripheral_manager_client.h
+++ b/include/peripheralmanager/peripheral_manager_client.h
@@ -20,6 +20,7 @@
#include <sys/cdefs.h>
#include "peripheralmanager/gpio.h"
+#include "peripheralmanager/led.h"
#include "peripheralmanager/spi_device.h"
__BEGIN_DECLS
@@ -77,6 +78,22 @@ int BPeripheralManagerClient_openSpiDevice(
const char* name,
BSpiDevice** dev);
+/// Returns the list of LEDs available.
+/// @param client Pointer to the BPeripheralManagerClient struct.
+/// @param num_leds Output pointer to the number of leds.
+/// @return The list of LEDs. The list must be freed by the caller.
+char** BPeripheralManagerClient_listLeds(const BPeripheralManagerClient* client,
+ int* num_leds);
+
+/// Opens an LED and takes ownership of it.
+/// @oaram client Pointer to the BPeripheralManagerClient struct.
+/// @param name Name of the LED.
+/// @param dev Output pointer to the BLed struct. Empty on error.
+/// @return 0 on success, errno on error.
+int BPeripheralManagerClient_openLed(const BPeripheralManagerClient* client,
+ const char* name,
+ BLed** led);
+
/// Creates a new client.
/// @return A pointer to the created client. nullptr on errors.
BPeripheralManagerClient* BPeripheralManagerClient_new();
diff --git a/ipc/android/os/IPeripheralManagerClient.aidl b/ipc/android/os/IPeripheralManagerClient.aidl
index 60aca42..978057e 100644
--- a/ipc/android/os/IPeripheralManagerClient.aidl
+++ b/ipc/android/os/IPeripheralManagerClient.aidl
@@ -56,4 +56,16 @@ interface IPeripheralManagerClient {
void SpiDeviceSetMode(@utf8InCpp String name, int mode);
void SpiDeviceSetBitsPerWord(@utf8InCpp String name, int nbits);
+
+ void ListLeds(out @utf8InCpp List<String> leds);
+
+ void OpenLed(@utf8InCpp String name);
+
+ void ReleaseLed(@utf8InCpp String name);
+
+ int LedGetBrightness(@utf8InCpp String name);
+
+ int LedGetMaxBrightness(@utf8InCpp String name);
+
+ void LedSetBrightness(@utf8InCpp String name, int brightness);
}