Merge lp:~thomas-voss/platform-api/hw-alarms-api into lp:platform-api

Proposed by Thomas Voß
Status: Merged
Approved by: Ricardo Salveti
Approved revision: 214
Merged at revision: 218
Proposed branch: lp:~thomas-voss/platform-api/hw-alarms-api
Merge into: lp:platform-api
Diff against target: 704 lines (+540/-8)
15 files modified
data/CMakeLists.txt (+6/-2)
data/ubuntu-platform-hardware-api.pc.in (+10/-0)
debian/control (+2/-1)
debian/libplatform-api1-hybris-tests.install (+2/-1)
debian/libplatform-hardware-api1-dev.install (+1/-1)
debian/libubuntu-platform-hardware-api1.symbols (+7/-0)
include/ubuntu/hardware/CMakeLists.txt (+2/-1)
include/ubuntu/hardware/alarm.h (+104/-0)
src/ubuntu/CMakeLists.txt (+7/-0)
src/ubuntu/hardware/CMakeLists.txt (+9/-0)
src/ubuntu/hardware/alarm.cpp (+304/-0)
src/ubuntu/hybris/CMakeLists.txt (+7/-2)
src/ubuntu/hybris/tests/CMakeLists.txt (+4/-0)
src/ubuntu/hybris/tests/test_alarms_api.cpp (+74/-0)
src/ubuntu/hybris/ubuntu_platform_hardware_api.cpp (+1/-0)
To merge this branch: bzr merge lp:~thomas-voss/platform-api/hw-alarms-api
Reviewer Review Type Date Requested Status
Ricardo Salveti (community) Approve
PS Jenkins bot continuous-integration Approve
Charles Kerr (community) Approve
Review via email: mp+210592@code.launchpad.net

Commit message

Add hw alarm api implementation for android's /dev/alarm.
Add simple test executable for hw alarm api implementation on android.
Adjust interface signatures to make sure that status of operations is reported correctly.
Add HW Alarms API interface definition.
Add Ubuntu implementation that will bridge over to the android world.

Description of the change

Add hw alarm api implementation for android's /dev/alarm.
Add simple test executable for hw alarm api implementation on android.
Adjust interface signatures to make sure that status of operations is reported correctly.
Add HW Alarms API interface definition.
Add Ubuntu implementation that will bridge over to the android world.

* Is your branch in sync with latest trunk: yes
* Did you build your software in a clean sbuild/pbuilder chroot or ppa? yes
* Did you build your software in a clean sbuild/pbuilder armhf chroot or ppa? yes
* Has a 5 minute exploratory testing run been executed on N4? yes
* If you changed the packaging (debian), did you subscribe a core-dev to this MP? N/A
* If you changed the UI, did you subscribe the design-reviewers to this MP? N/A
* What components might get impacted by your changes? Indicator-Datetime, Clock App
* Have you requested review by the teams of these owning components? Yes

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ricardo Salveti (rsalveti) wrote :

31 + libEGL \
32 + libGLESv2 \

Do we really need to link to EGL/GLESv2 in here?

Can you also add a simple test that can be consumed from the ubuntu side as well?

review: Needs Fixing
201. By Thomas Voß

Add test-case runnable from the Ubuntu side.
Adjust linker flags according to review.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ricardo Salveti (rsalveti) wrote :

dh_install: usr/bin/test_hardware_alarms_api exists in debian/tmp but is not installed to anywhere

Need to add it to be installed.

review: Needs Fixing
202. By Thomas Voß

Add newly added test executable to packaging setup.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Omer Akram (om26er) wrote :

57 + * Copyright © 2013 Canonical Ltd.

maybe change that and other headers to 2014 :)

Revision history for this message
Charles Kerr (charlesk) wrote :

A couple of small points and one question:

* in include/ubuntu/hardware/CMakeLists.txt, need to add 'alarm.h' to UBUNTU_HARDWARE_HEADERS

* in UbuntuHardwareAlarm::set() if ioctl(fd, ANDROID_ALARM_SET(type), ts) fails, we should include strerror(errno) in the ALOGE call.

* in UbuntuHardwareAlarm::~UbuntuHardwareAlarm(), need to check fd is valid before closing. If open() couldn't fail, is_valid() wouldn't be needed...

* in u_hardware_alarm_set_timezone() (a) I'm unclear on the use case for this function and (b) it's got a questionable use of settimeofday(NULL, tz). settimeofday(2) says:

       Under Linux there are some peculiar "warp clock" semantics associated
       with the settimeofday() system call if on the very first call (after
       booting) that has a non-NULL tz argument, the tv argument is NULL and
       the tz_minuteswest field is nonzero. (The tz_dsttime field should be
       zero for this case.) In such a case it is assumed that the CMOS clock
       is on local time, and that it has to be incremented by this amount to
       get UTC system time. No doubt it is a bad idea to use this feature.

review: Needs Information
Revision history for this message
Charles Kerr (charlesk) wrote :

* I blame my self for not asking sooner, since I did review the API when it was just in header form, but what are the steps for cancelling an alarm to reset it?

Consider indicator-datetime. It doesn't know when the hardware is going to sleep, so whenever there are alarms set it's going to need a thread that's blocked inside ua_hardware_alarm_wait_for_next_alarm(). Then the user edits/deletes the EDS alarm that was going to trigger next. indicator-datetime is going to need to reset the alarm and call wait again. What should happen to the first wait?

203. By Thomas Voß

Address reviewer comments.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Thomas Voß (thomas-voss) wrote :

> * I blame my self for not asking sooner, since I did review the API when it
> was just in header form, but what are the steps for cancelling an alarm to
> reset it?
>
> Consider indicator-datetime. It doesn't know when the hardware is going to
> sleep, so whenever there are alarms set it's going to need a thread that's
> blocked inside ua_hardware_alarm_wait_for_next_alarm(). Then the user
> edits/deletes the EDS alarm that was going to trigger next. indicator-datetime
> is going to need to reset the alarm and call wait again. What should happen to
> the first wait?

You only need one wait, no need to reset the blocking wait. The android alarm service takes a very similar approach when using /dev/alarm:

  * http://androidxref.com/4.4.2_r2/xref/frameworks/base/services/java/com/android/server/AlarmManagerService.java#655
  * http://androidxref.com/4.4.2_r2/xref/frameworks/base/services/java/com/android/server/AlarmManagerService.java#1155

Revision history for this message
Charles Kerr (charlesk) wrote :

LGTM.

review: Approve
204. By Thomas Voß

Add a pkgconfig file for the hardware portions of the platform api.
Install hardware/alarm.h.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
205. By Thomas Voß

Make sure that pkgconfig file for hardware abstractions is installed in debian package.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
206. By Thomas Voß

Remove exception-based error handling.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
207. By Thomas Voß

[ Gerry Boland ]
* Manually call mir's SurfacePlacementStrategy::place and
  SessionListener::surface_created methods for in process client
  Surface Mir 0.1.8 refactoring causes in-process client surfaces to
  be an implementation detail of Mir's surface stack, and prevents
  shell from getting access to its surface to position it and define
  input areas on it. To fix this,we perform the following: 1. Create
  an InProcessClientSession to represent the in-process client 2. Get
  access to Mir's SurfacePlacementStrategy object and call its place
  method explicitly, to allow shell to position its surface 3. Get
  access to Mir's SessionListener object and call its surface_created
  method explicitly, to notify shell its surface was created
[ Alan Griffiths ]
* Changes for compatibility with Mir 0.1.8
[ Ubuntu daily release ]
* New rebuild forced
[ Andreas Pokorny ]
* CMakeLists adaptation to make platform-api cross compile with a
  simple chroot setup. Note that <PKG_NAME>_LINK_LIBRARIES variables
  were removed from link_directories and respective <PKG_NAME>_LDFLAGS
  variables were instead put into target_link_libraries. Those
  informations attached to targets are transitively forwarded to the
  user of the library. link_directories only attaches the information
  to the source directory.
[ Chris Gagnon ]
* enable getting coverage in CI
[ Ubuntu daily release ]
* New rebuild forced
[ Kevin Gunn ]
* bump to mir0.1.7
[ Kevin Gunn ]
* bump debian dep to mir0.1.6
[ Łukasz 'sil2100' Zemczak ]
* Bump the build-dependency on dbus-cpp due to the ABI change

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
208. By Thomas Voß

Rename enumeration constant in alarms from _NOW to _RTC.
[ Alberto Aguirre ]
* needed for mir019
[ Ubuntu daily release ]
* New rebuild forced

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
209. By Thomas Voß

Adjust test case to account for adjusted naming of enumeration value.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
210. By Thomas Voß

Add a function for querying the time since boot from /dev/alarm.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
211. By Thomas Voß

Adjust test case on the Ubuntu side.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
212. By Thomas Voß

Add missing header.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
213. By Thomas Voß

[ Gerry Boland ]
[Daniel d'Andrada]
* Add ua_ui_window_get_size().

[Gerry Boland]
* Bump package version to match library version.
[ Ricardo Mendoza ]
* Change sensors API to allow for GCC 4.8 building across all clients
  Ubuntu-side

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Please correct me if I'm wrong, but we don't need a hybris implementation for such feature, as it uses ioctl on a known hardware device (/dev/alarm).

Did you try executing the same abstraction natively on ubuntu? I'd prefer it to not touch the android side unless it's really needed.

review: Needs Information
214. By Thomas Voß

Refactored hw-alarms implementation to live on the Ubuntu-side.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Looks fine and test seems to be working as expected.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'data/CMakeLists.txt'
--- data/CMakeLists.txt 2013-06-13 12:04:14 +0000
+++ data/CMakeLists.txt 2014-05-21 07:20:43 +0000
@@ -2,7 +2,11 @@
2 ubuntu-platform-api.pc.in ubuntu-platform-api.pc @ONLY2 ubuntu-platform-api.pc.in ubuntu-platform-api.pc @ONLY
3)3)
44
5configure_file(
6 ubuntu-platform-hardware-api.pc.in ubuntu-platform-hardware-api.pc @ONLY
7)
8
5install(9install(
6 FILES ${CMAKE_CURRENT_BINARY_DIR}/ubuntu-platform-api.pc10 FILES ${CMAKE_CURRENT_BINARY_DIR}/ubuntu-platform-api.pc ${CMAKE_CURRENT_BINARY_DIR}/ubuntu-platform-hardware-api.pc
7 DESTINATION lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig11 DESTINATION lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig
8)
9\ No newline at end of file12\ No newline at end of file
13)
1014
=== added file 'data/ubuntu-platform-hardware-api.pc.in'
--- data/ubuntu-platform-hardware-api.pc.in 1970-01-01 00:00:00 +0000
+++ data/ubuntu-platform-hardware-api.pc.in 2014-05-21 07:20:43 +0000
@@ -0,0 +1,10 @@
1prefix=@CMAKE_INSTALL_PREFIX@
2exec_prefix=${prefix}
3libdir=${prefix}/@LIB_INSTALL_DIR@
4includedir=${exec_prefix}/include
5
6Name: ubuntu_platform_hardware_api
7Description: Ubuntu's platform hardware abstraction layer.
8Version: @UBUNTU_PLATFORM_API_VERSION_MAJOR@.@UBUNTU_PLATFORM_API_VERSION_MINOR@.@UBUNTU_PLATFORM_API_VERSION_PATCH@
9Libs: -L${libdir} -lubuntu_platform_hardware_api
10Cflags: -I${includedir}/ubuntu
011
=== modified file 'debian/control'
--- debian/control 2014-05-07 07:39:57 +0000
+++ debian/control 2014-05-21 07:20:43 +0000
@@ -2,7 +2,8 @@
2Priority: optional2Priority: optional
3Section: devel3Section: devel
4Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>4Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
5Build-Depends: cmake,5Build-Depends: android-headers,
6 cmake,
6 debhelper (>= 9),7 debhelper (>= 9),
7 doxygen,8 doxygen,
8 graphviz,9 graphviz,
910
=== modified file 'debian/libplatform-api1-hybris-tests.install'
--- debian/libplatform-api1-hybris-tests.install 2013-08-17 05:22:31 +0000
+++ debian/libplatform-api1-hybris-tests.install 2014-05-21 07:20:43 +0000
@@ -3,4 +3,5 @@
3usr/bin/test_android_ubuntu_app_api3usr/bin/test_android_ubuntu_app_api
4usr/bin/test_android_ubuntu_app_api_multiple_surfaces4usr/bin/test_android_ubuntu_app_api_multiple_surfaces
5usr/bin/test_android_ubuntu_session_api5usr/bin/test_android_ubuntu_session_api
6usr/bin/test_ubuntu_app_api_location_service
7\ No newline at end of file6\ No newline at end of file
7usr/bin/test_ubuntu_app_api_location_service
8usr/bin/test_hardware_alarms_api
89
=== modified file 'debian/libplatform-hardware-api1-dev.install'
--- debian/libplatform-hardware-api1-dev.install 2013-07-08 10:39:36 +0000
+++ debian/libplatform-hardware-api1-dev.install 2014-05-21 07:20:43 +0000
@@ -1,2 +1,2 @@
1usr/lib/*/libubuntu_platform_hardware_api.so1usr/lib/*/libubuntu_platform_hardware_api.so
22usr/lib/*/pkgconfig/ubuntu-platform-hardware-api.pc
33
=== modified file 'debian/libubuntu-platform-hardware-api1.symbols'
--- debian/libubuntu-platform-hardware-api1.symbols 2013-07-17 14:29:04 +0000
+++ debian/libubuntu-platform-hardware-api1.symbols 2014-05-21 07:20:43 +0000
@@ -1,4 +1,11 @@
1libubuntu_platform_hardware_api.so.1 libubuntu-platform-hardware-api1 #MINVER#1libubuntu_platform_hardware_api.so.1 libubuntu-platform-hardware-api1 #MINVER#
2 u_hardware_alarm_create@Base 0replaceme
3 u_hardware_alarm_get_elapsed_real_time@Base 0replaceme
4 u_hardware_alarm_ref@Base 0replaceme
5 u_hardware_alarm_set_relative_to_with_behavior@Base 0replaceme
6 u_hardware_alarm_set_timezone@Base 0replaceme
7 u_hardware_alarm_unref@Base 0replaceme
8 u_hardware_alarm_wait_for_next_alarm@Base 0replaceme
2 u_hardware_gps_delete@Base 0.18.2+13.10.201307099 u_hardware_gps_delete@Base 0.18.2+13.10.20130709
3 u_hardware_gps_delete_aiding_data@Base 0.18.2+13.10.2013070910 u_hardware_gps_delete_aiding_data@Base 0.18.2+13.10.20130709
4 u_hardware_gps_inject_location@Base 0.18.2+13.10.2013070911 u_hardware_gps_inject_location@Base 0.18.2+13.10.20130709
512
=== modified file 'include/ubuntu/hardware/CMakeLists.txt'
--- include/ubuntu/hardware/CMakeLists.txt 2013-07-18 09:08:17 +0000
+++ include/ubuntu/hardware/CMakeLists.txt 2014-05-21 07:20:43 +0000
@@ -1,9 +1,10 @@
1set(1set(
2 UBUNTU_HARDWARE_HEADERS2 UBUNTU_HARDWARE_HEADERS
3 alarm.h
3 gps.h4 gps.h
4)5)
56
6install(7install(
7 FILES ${UBUNTU_HARDWARE_HEADERS}8 FILES ${UBUNTU_HARDWARE_HEADERS}
8 DESTINATION include/ubuntu/hardware9 DESTINATION include/ubuntu/hardware
9)
10\ No newline at end of file10\ No newline at end of file
11)
1112
=== added file 'include/ubuntu/hardware/alarm.h'
--- include/ubuntu/hardware/alarm.h 1970-01-01 00:00:00 +0000
+++ include/ubuntu/hardware/alarm.h 2014-05-21 07:20:43 +0000
@@ -0,0 +1,104 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 */
18#ifndef UBUNTU_HARDWARE_ALARM_H_
19#define UBUNTU_HARDWARE_ALARM_H_
20
21#include <ubuntu/status.h>
22#include <ubuntu/visibility.h>
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28/** The time reference that alarms are setup to. */
29typedef enum
30{
31 U_HARDWARE_ALARM_TIME_REFERENCE_BOOT, /**< Relative to the device's boot time, including sleep. */
32 U_HARDWARE_ALARM_TIME_REFERENCE_RTC /**< Wall clock time in UTC. */
33} UbuntuHardwareAlarmTimeReference;
34
35typedef UbuntuHardwareAlarmTimeReference UHardwareAlarmTimeReference;
36
37/** Describes if an alarm is able to wakup the device from sleep. */
38typedef enum
39{
40 /** Alarm will wakeup the device from sleep. */
41 U_HARDWARE_ALARM_SLEEP_BEHAVIOR_WAKEUP_DEVICE,
42 /** Alarm will not wakeup the device and will be delivered on the next wakeup of the device */
43 U_HARDWARE_ALARM_SLEEP_BEHAVIOR_KEEP_DEVICE_ASLEEP
44} UbuntuHardwareAlarmSleepBehavior;
45
46typedef UbuntuHardwareAlarmSleepBehavior UHardwareAlarmSleepBehavior;
47
48/** Bundles the time reference and sleep/wakeup behavior when waiting for an alarm to happen. */
49typedef struct
50{
51 UHardwareAlarmTimeReference reference;
52 UHardwareAlarmSleepBehavior sleep_behavior;
53} UbuntuHardwareAlarmWaitResult;
54
55typedef UbuntuHardwareAlarmWaitResult UHardwareAlarmWaitResult;
56
57/** Opaque type modelling access to the kernel/hw-level alarm capabilities. */
58typedef struct UbuntuHardwareAlarm* UHardwareAlarm;
59
60/** Creates an instance and/or increments its refcount. */
61UBUNTU_DLL_PUBLIC UHardwareAlarm
62u_hardware_alarm_create();
63
64/** Increments the instance's ref count. */
65UBUNTU_DLL_PUBLIC void
66u_hardware_alarm_ref(
67 UHardwareAlarm alarm);
68
69/** Decrements the instance's ref count. */
70UBUNTU_DLL_PUBLIC void
71u_hardware_alarm_unref(
72 UHardwareAlarm alarm);
73
74/** Query the time that elapsed since boot, including deep sleeps. */
75UBUNTU_DLL_PUBLIC UStatus
76u_hardware_alarm_get_elapsed_real_time(
77 UHardwareAlarm alarm,
78 struct timespec *tz);
79
80/** Reports a timezone change to kernel and HW. */
81UBUNTU_DLL_PUBLIC UStatus
82u_hardware_alarm_set_timezone(
83 UHardwareAlarm alarm,
84 const struct timezone *tz);
85
86/** Sets and arms a timer. */
87UBUNTU_DLL_PUBLIC UStatus
88u_hardware_alarm_set_relative_to_with_behavior(
89 UHardwareAlarm alarm,
90 UHardwareAlarmTimeReference time_reference,
91 UHardwareAlarmSleepBehavior behavior,
92 const struct timespec *ts);
93
94/** Blocks until the next alarm occurs. */
95UBUNTU_DLL_PUBLIC UStatus
96u_hardware_alarm_wait_for_next_alarm(
97 UHardwareAlarm alarm,
98 UHardwareAlarmWaitResult *result);
99
100#ifdef __cplusplus
101}
102#endif
103
104#endif
0105
=== modified file 'src/ubuntu/CMakeLists.txt'
--- src/ubuntu/CMakeLists.txt 2013-12-02 17:03:45 +0000
+++ src/ubuntu/CMakeLists.txt 2014-05-21 07:20:43 +0000
@@ -3,6 +3,7 @@
3)3)
44
5add_subdirectory(application)5add_subdirectory(application)
6add_subdirectory(hardware)
6add_subdirectory(testbackend)7add_subdirectory(testbackend)
78
8set(9set(
@@ -12,6 +13,12 @@
12 ubuntu_application_url_dispatcher13 ubuntu_application_url_dispatcher
13)14)
1415
16set(
17 UBUNTU_HARDWARE_API_LINK_LIBRARIES
18
19 ubuntu_hardware_alarm
20)
21
15if(ENABLE_HYBRIS_IMPLEMENTATION)22if(ENABLE_HYBRIS_IMPLEMENTATION)
16 add_subdirectory(hybris/)23 add_subdirectory(hybris/)
17endif()24endif()
1825
=== added directory 'src/ubuntu/hardware'
=== added file 'src/ubuntu/hardware/CMakeLists.txt'
--- src/ubuntu/hardware/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ src/ubuntu/hardware/CMakeLists.txt 2014-05-21 07:20:43 +0000
@@ -0,0 +1,9 @@
1set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11 -fPIC")
2
3include_directories(/usr/include/android)
4
5add_library(
6 ubuntu_hardware_alarm
7
8 alarm.cpp
9)
0\ No newline at end of file10\ No newline at end of file
111
=== added file 'src/ubuntu/hardware/alarm.cpp'
--- src/ubuntu/hardware/alarm.cpp 1970-01-01 00:00:00 +0000
+++ src/ubuntu/hardware/alarm.cpp 2014-05-21 07:20:43 +0000
@@ -0,0 +1,304 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 */
18
19#include <android/linux/android_alarm.h>
20
21#include <ubuntu/hardware/alarm.h>
22
23#include <cstdio>
24#include <cstring>
25
26#include <stdexcept>
27#include <string>
28
29#include <unistd.h>
30
31#include <errno.h>
32#include <fcntl.h>
33
34#include <sys/ioctl.h>
35#include <sys/time.h>
36#include <sys/types.h>
37
38namespace
39{
40struct HardwareAlarm
41{
42 HardwareAlarm() = default;
43 virtual ~HardwareAlarm() = default;
44
45 // Blocks the calling thread until an alarm fires or
46 // an error occurs. Returns an int with bool semantics.
47 virtual int wait_for() = 0;
48
49 // Arms the alarm with the given properties.
50 // Returns true if the alarm has been armed successfully, false otherwise.
51 virtual bool set(
52 UHardwareAlarmTimeReference time_reference,
53 UHardwareAlarmSleepBehavior behavior,
54 const struct timespec *ts) = 0;
55
56 // Queries the time since last boot including deep sleep periods.
57 virtual bool get_elapsed_realtime(struct timespec* ts) = 0;
58};
59
60// An implementation of HardwareAlarm based on Android's /dev/alarm.
61struct DevAlarmHardwareAlarm : public HardwareAlarm
62{
63 int fd; // file descriptor referring to /dev/alarm
64
65 DevAlarmHardwareAlarm() : fd(open("/dev/alarm", O_RDWR))
66 {
67 if (fd == -1)
68 {
69 auto error = errno;
70
71 std::string what
72 {
73 "Could not open /dev/alarm: "
74 };
75 throw std::runtime_error
76 {
77 (what + strerror(error)).c_str()
78 };
79 }
80 }
81
82 ~DevAlarmHardwareAlarm()
83 {
84 // No need to check if fd is valid here.
85 // Ctor would have thrown if fd was invalid.
86 ::close(fd);
87 }
88
89 int wait_for()
90 {
91 int result{-1};
92
93 do
94 {
95 result = ::ioctl(fd, ANDROID_ALARM_WAIT);
96 } while (result < 0 && errno == EINTR);
97
98 if (result < 0)
99 fprintf(stderr, "Waiting for hw alarm failed with: %s\n", strerror(errno));
100
101 return result;
102 }
103
104 bool set(UHardwareAlarmTimeReference time_reference,
105 UHardwareAlarmSleepBehavior behavior,
106 const struct timespec *ts)
107 {
108 if (not ts)
109 return false;
110
111 int type = 0;
112
113 if (time_reference == U_HARDWARE_ALARM_TIME_REFERENCE_BOOT)
114 switch(behavior)
115 {
116 case U_HARDWARE_ALARM_SLEEP_BEHAVIOR_WAKEUP_DEVICE:
117 type = ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK;
118 break;
119 case U_HARDWARE_ALARM_SLEEP_BEHAVIOR_KEEP_DEVICE_ASLEEP:
120 type = ANDROID_ALARM_ELAPSED_REALTIME_MASK;
121 break;
122 }
123 else if (time_reference == U_HARDWARE_ALARM_TIME_REFERENCE_RTC)
124 switch(behavior)
125 {
126 case U_HARDWARE_ALARM_SLEEP_BEHAVIOR_WAKEUP_DEVICE:
127 type = ANDROID_ALARM_RTC_WAKEUP_MASK;
128 break;
129 case U_HARDWARE_ALARM_SLEEP_BEHAVIOR_KEEP_DEVICE_ASLEEP:
130 type = ANDROID_ALARM_RTC_MASK;
131 break;
132 }
133
134 int result = ::ioctl(fd, ANDROID_ALARM_SET(type), ts);
135
136 if (result < 0)
137 fprintf(stderr, "Unable to set alarm: %s\n", strerror(errno));
138
139 return not (result < 0);
140 }
141
142 bool get_elapsed_realtime(struct timespec* ts)
143 {
144 if (not ts)
145 return false;
146
147 int result = ::ioctl(
148 fd,
149 ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME),
150 ts);
151
152 return result == 0;
153 }
154};
155}
156
157class UbuntuHardwareAlarm
158{
159 public:
160 static UbuntuHardwareAlarm& instance()
161 {
162 static UbuntuHardwareAlarm ha;
163 return ha;
164 }
165
166 int wait_for()
167 {
168 return impl->wait_for();
169 }
170
171 bool set(UHardwareAlarmTimeReference time_reference,
172 UHardwareAlarmSleepBehavior behavior,
173 const struct timespec *ts)
174 {
175 return impl->set(time_reference, behavior, ts);
176 }
177
178 bool get_elapsed_realtime(struct timespec* ts)
179 {
180 return impl->get_elapsed_realtime(ts);
181 }
182
183 bool is_valid() const
184 {
185 return impl != nullptr;
186 }
187
188 private:
189 UbuntuHardwareAlarm()
190 {
191 try
192 {
193 impl = new DevAlarmHardwareAlarm();
194 } catch(const std::runtime_error& e)
195 {
196 fprintf(
197 stderr, "%s: Error creating /dev/alarm-based implementation with: %s\n",
198 __PRETTY_FUNCTION__,
199 e.what());
200
201 // TODO: Should we fallback to a timer-fd implementation here? I'm not
202 // convinced that we should do so as a timer-fd wouldn't wakeup the device
203 // from any sort of sleep mode.
204 }
205 }
206
207 ~UbuntuHardwareAlarm()
208 {
209 delete impl;
210 }
211
212 HardwareAlarm* impl
213 {
214 nullptr
215 };
216};
217
218UHardwareAlarm
219u_hardware_alarm_create()
220{
221 auto result = &UbuntuHardwareAlarm::instance();
222
223 if (result)
224 if (result->is_valid())
225 return result;
226
227 return NULL;
228}
229
230void
231u_hardware_alarm_ref(
232 UHardwareAlarm alarm)
233{
234 // Considering a singleton pattern here, just voiding the argument.
235 (void) alarm;
236}
237
238void
239u_hardware_alarm_unref(
240 UHardwareAlarm alarm)
241{
242 // Considering a singleton pattern here, just voiding the argument.
243 (void) alarm;
244}
245
246UStatus
247u_hardware_alarm_get_elapsed_real_time(
248 UHardwareAlarm alarm,
249 struct timespec* ts)
250{
251 return alarm->get_elapsed_realtime(ts) ? U_STATUS_SUCCESS : U_STATUS_ERROR;
252}
253
254UStatus
255u_hardware_alarm_set_timezone(
256 UHardwareAlarm alarm,
257 const struct timezone *tz)
258{
259 int result = settimeofday(NULL, tz);
260
261 if (result < 0)
262 return U_STATUS_ERROR;
263
264 return U_STATUS_SUCCESS;
265}
266
267UStatus
268u_hardware_alarm_set_relative_to_with_behavior(
269 UHardwareAlarm alarm,
270 UHardwareAlarmTimeReference time_reference,
271 UHardwareAlarmSleepBehavior behavior,
272 const struct timespec *ts)
273{
274 return alarm->set(time_reference, behavior, ts) ?
275 U_STATUS_SUCCESS :
276 U_STATUS_ERROR;
277
278}
279
280UStatus
281u_hardware_alarm_wait_for_next_alarm(
282 UHardwareAlarm alarm,
283 UHardwareAlarmWaitResult *result)
284{
285 int rc = alarm->wait_for();
286
287 if (rc < 0)
288 return U_STATUS_ERROR;
289
290 if ((rc & ANDROID_ALARM_RTC_MASK) ||
291 (rc & ANDROID_ALARM_RTC_WAKEUP_MASK))
292 result->reference = U_HARDWARE_ALARM_TIME_REFERENCE_BOOT;
293 else if ((rc & ANDROID_ALARM_ELAPSED_REALTIME_MASK) ||
294 (rc & ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK))
295 result->reference = U_HARDWARE_ALARM_TIME_REFERENCE_RTC;
296
297 if ((rc & ANDROID_ALARM_RTC_WAKEUP_MASK) ||
298 (rc & ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK))
299 result->sleep_behavior = U_HARDWARE_ALARM_SLEEP_BEHAVIOR_WAKEUP_DEVICE;
300 else
301 result->sleep_behavior = U_HARDWARE_ALARM_SLEEP_BEHAVIOR_KEEP_DEVICE_ASLEEP;
302
303 return U_STATUS_SUCCESS;
304}
0305
=== modified file 'src/ubuntu/hybris/CMakeLists.txt'
--- src/ubuntu/hybris/CMakeLists.txt 2014-02-12 07:35:37 +0000
+++ src/ubuntu/hybris/CMakeLists.txt 2014-05-21 07:20:43 +0000
@@ -20,13 +20,18 @@
20 ubuntu_application_api20 ubuntu_application_api
2121
22 "-Wl,--whole-archive"22 "-Wl,--whole-archive"
23 ${UBUNTU_APPLICATION_API_LINK_LIBRARIES} 23 ${UBUNTU_APPLICATION_API_LINK_LIBRARIES}
24 "-Wl,--no-whole-archive"24 "-Wl,--no-whole-archive"
25 ${Hybris}25 ${Hybris}
26)26)
2727
28target_link_libraries(28target_link_libraries(
29 ubuntu_platform_hardware_api29 ubuntu_platform_hardware_api
30
31 "-Wl,--whole-archive"
32 ${UBUNTU_HARDWARE_API_LINK_LIBRARIES}
33 "-Wl,--no-whole-archive"
34
30 dl35 dl
31 ${Hybris}36 ${Hybris}
32)37)
@@ -46,7 +51,7 @@
46)51)
4752
48install(53install(
49 TARGETS ubuntu_application_api 54 TARGETS ubuntu_application_api
50 ${INSTALL_TARGETS_DEFAULT_ARGS}55 ${INSTALL_TARGETS_DEFAULT_ARGS}
51)56)
5257
5358
=== modified file 'src/ubuntu/hybris/tests/CMakeLists.txt'
--- src/ubuntu/hybris/tests/CMakeLists.txt 2013-08-17 05:22:31 +0000
+++ src/ubuntu/hybris/tests/CMakeLists.txt 2014-05-21 07:20:43 +0000
@@ -18,6 +18,9 @@
18add_executable(test_ubuntu_app_api_location_service test_location_api.cpp)18add_executable(test_ubuntu_app_api_location_service test_location_api.cpp)
19target_link_libraries(test_ubuntu_app_api_location_service ubuntu_application_api)19target_link_libraries(test_ubuntu_app_api_location_service ubuntu_application_api)
2020
21add_executable(test_hardware_alarms_api test_alarms_api.cpp)
22target_link_libraries(test_hardware_alarms_api ubuntu_platform_hardware_api)
23
21install(TARGETS24install(TARGETS
22 test_android_ubuntu_app_api25 test_android_ubuntu_app_api
23 test_android_gps_api26 test_android_gps_api
@@ -25,5 +28,6 @@
25 test_android_sensors_api28 test_android_sensors_api
26 test_android_ubuntu_session_api29 test_android_ubuntu_session_api
27 test_ubuntu_app_api_location_service30 test_ubuntu_app_api_location_service
31 test_hardware_alarms_api
28 DESTINATION bin32 DESTINATION bin
29)33)
3034
=== added file 'src/ubuntu/hybris/tests/test_alarms_api.cpp'
--- src/ubuntu/hybris/tests/test_alarms_api.cpp 1970-01-01 00:00:00 +0000
+++ src/ubuntu/hybris/tests/test_alarms_api.cpp 2014-05-21 07:20:43 +0000
@@ -0,0 +1,74 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonicalcom>
17 */
18
19#include <ubuntu/hardware/alarm.h>
20
21#include <cstdio>
22#include <cstdlib>
23#include <ctime>
24
25int main(int argc, char** argv)
26{
27 UHardwareAlarm alarm = u_hardware_alarm_create();
28
29 if (!alarm)
30 {
31 printf("Error creating handle to hardware alarms.\n");
32 return 1;
33 }
34
35 // Alarm in two seconds.
36 timespec ts { 0, 0 };
37 clock_gettime(CLOCK_REALTIME, &ts);
38
39 int timeout_in_seconds = 5;
40
41 // Let's see if a timeout has been specified on the command line
42 if (argc > 1)
43 {
44 timeout_in_seconds = atoi(argv[1]);
45 }
46
47 // Alarm in two seconds.
48 ts.tv_sec += timeout_in_seconds;
49
50 UStatus rc = u_hardware_alarm_set_relative_to_with_behavior(
51 alarm,
52 U_HARDWARE_ALARM_TIME_REFERENCE_RTC,
53 U_HARDWARE_ALARM_SLEEP_BEHAVIOR_WAKEUP_DEVICE,
54 &ts);
55
56 if (rc != U_STATUS_SUCCESS)
57 {
58 printf("Problem setting hardware alarm.\n");
59 return 1;
60 }
61
62 UHardwareAlarmWaitResult wait_result;
63 rc = u_hardware_alarm_wait_for_next_alarm(alarm, &wait_result);
64
65 if (rc != U_STATUS_SUCCESS)
66 {
67 printf("Problem waiting for hardware alarm to go off.\n");
68 return 1;
69 }
70
71 printf("Successfully created and waited for a hw alarm.\n");
72
73 return 0;
74}
075
=== modified file 'src/ubuntu/hybris/ubuntu_platform_hardware_api.cpp'
--- src/ubuntu/hybris/ubuntu_platform_hardware_api.cpp 2013-06-13 08:37:52 +0000
+++ src/ubuntu/hybris/ubuntu_platform_hardware_api.cpp 2014-05-21 07:20:43 +0000
@@ -18,6 +18,7 @@
18 */18 */
1919
20// C APIs20// C APIs
21#include <ubuntu/hardware/alarm.h>
21#include <ubuntu/hardware/gps.h>22#include <ubuntu/hardware/gps.h>
2223
23#include "bridge.h"24#include "bridge.h"

Subscribers

People subscribed via source and target branches