diff options
author | Bertrand SIMONNET <bsimonnet@google.com> | 2016-03-14 13:56:31 -0700 |
---|---|---|
committer | Lee Campbell <leecam@google.com> | 2016-03-15 16:31:18 +0000 |
commit | 7d12dacad6018701dac2b1a1b3e378d295ffe544 (patch) | |
tree | 06b519837779c3f4a1566b50b5d4a4369a9892c9 | |
parent | a733d4aefdba57cd752783e19db1b0f906ff2877 (diff) | |
download | peripheralmanager-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.mk | 1 | ||||
-rw-r--r-- | client/led_impl.cc | 51 | ||||
-rw-r--r-- | client/led_impl.h | 40 | ||||
-rw-r--r-- | client/peripheral_manager_client_impl.cc | 13 | ||||
-rw-r--r-- | client/peripheral_manager_client_impl.h | 4 | ||||
-rw-r--r-- | client/wrapper.cc | 42 | ||||
-rw-r--r-- | daemon/peripheral_manager_client.cc | 63 | ||||
-rw-r--r-- | daemon/peripheral_manager_client.h | 15 | ||||
-rw-r--r-- | example/Android.mk | 16 | ||||
-rw-r--r-- | example/led_example.cc | 94 | ||||
-rw-r--r-- | include/peripheralmanager/led.h | 60 | ||||
-rw-r--r-- | include/peripheralmanager/peripheral_manager_client.h | 17 | ||||
-rw-r--r-- | ipc/android/os/IPeripheralManagerClient.aidl | 12 |
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); } |