summaryrefslogtreecommitdiff
path: root/osi
diff options
context:
space:
mode:
authorMarie Janssen <jamuraa@google.com>2015-11-16 10:35:17 -0800
committerAndre Eisenbach <eisenbach@google.com>2015-12-02 18:14:57 +0000
commit1b2bd2c8b5b7be80cb4ce0ecf4e021ad16e4a540 (patch)
tree202eacdb707418c621c4b042a9c10f9eb018e744 /osi
parent13bb0897a951f267680268b800084302c071e4cc (diff)
downloadandroid-system-bt-1b2bd2c8b5b7be80cb4ce0ecf4e021ad16e4a540.tar.gz
android-system-bt-1b2bd2c8b5b7be80cb4ce0ecf4e021ad16e4a540.tar.xz
tests: don't use bt_os_callouts for wakelocks
Introduces alarm_set_wake_lock_paths so wake lock paths can be changed for testing, and adds AlarmTestHarness::WakeLockHeld to test whether a wake lock is currently held. Bug: 25387683 Change-Id: I9a41ae8266e252a3d436f8d41ea3f9e7ecb45cdc
Diffstat (limited to 'osi')
-rw-r--r--osi/include/alarm.h7
-rw-r--r--osi/src/alarm.c50
-rw-r--r--osi/test/AlarmTestHarness.cpp95
-rw-r--r--osi/test/AlarmTestHarness.h7
-rw-r--r--osi/test/AllocationTestHarness.h2
-rw-r--r--osi/test/alarm_test.cpp28
6 files changed, 136 insertions, 53 deletions
diff --git a/osi/include/alarm.h b/osi/include/alarm.h
index 9307aac..4b3e395 100644
--- a/osi/include/alarm.h
+++ b/osi/include/alarm.h
@@ -59,3 +59,10 @@ period_ms_t alarm_get_remaining_ms(const alarm_t *alarm);
// Alarm-related state cleanup
void alarm_cleanup(void);
+
+// This function should not need to be called normally.
+// /sys/power/wake_{|un}lock are used by default.
+// This is not guaranteed to have any effect after an alarm has been
+// set with alarm_set.
+// If |lock_path| or |unlock_path| are NULL, that path is not changed.
+void alarm_set_wake_lock_paths(const char *lock_path, const char *unlock_path);
diff --git a/osi/src/alarm.c b/osi/src/alarm.c
index 3e7115f..9308ad2 100644
--- a/osi/src/alarm.c
+++ b/osi/src/alarm.c
@@ -24,6 +24,7 @@
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
+#include <limits.h>
#include <malloc.h>
#include <pthread.h>
#include <signal.h>
@@ -70,8 +71,10 @@ int64_t TIMER_INTERVAL_FOR_WAKELOCK_IN_MS = 3000;
static const clockid_t CLOCK_ID = CLOCK_BOOTTIME;
static const clockid_t CLOCK_ID_ALARM = CLOCK_BOOTTIME_ALARM;
static const char *WAKE_LOCK_ID = "bluetooth_timer";
-static const char *WAKE_LOCK_PATH = "/sys/power/wake_lock";
-static const char *WAKE_UNLOCK_PATH = "/sys/power/wake_unlock";
+static char *DEFAULT_WAKE_LOCK_PATH = "/sys/power/wake_lock";
+static char *DEFAULT_WAKE_UNLOCK_PATH = "/sys/power/wake_unlock";
+static char *wake_lock_path = NULL;
+static char *wake_unlock_path = NULL;
static ssize_t locked_id_len = -1;
static pthread_once_t wake_fds_initialized = PTHREAD_ONCE_INIT;
static int wake_lock_fd = INVALID_FD;
@@ -214,7 +217,17 @@ void alarm_cancel(alarm_t *alarm) {
}
void alarm_cleanup(void) {
- // If lazy_initialize never ran there is nothing to do
+ if (wake_lock_path && wake_lock_path != DEFAULT_WAKE_LOCK_PATH) {
+ osi_free(wake_lock_path);
+ wake_lock_path = NULL;
+ }
+
+ if (wake_unlock_path && wake_unlock_path != DEFAULT_WAKE_UNLOCK_PATH) {
+ osi_free(wake_unlock_path);
+ wake_unlock_path = NULL;
+ }
+
+ // If lazy_initialize never ran there is nothing else to do
if (!alarms)
return;
@@ -229,9 +242,26 @@ void alarm_cleanup(void) {
list_free(alarms);
alarms = NULL;
+ wake_fds_initialized = PTHREAD_ONCE_INIT;
+
pthread_mutex_destroy(&monitor);
}
+void alarm_set_wake_lock_paths(const char *lock_path, const char *unlock_path) {
+ if (lock_path) {
+ if (wake_lock_path && wake_lock_path != DEFAULT_WAKE_LOCK_PATH)
+ osi_free(wake_lock_path);
+ wake_lock_path = osi_strndup(lock_path, PATH_MAX);
+ }
+
+ if (unlock_path) {
+ if (wake_unlock_path && wake_unlock_path != DEFAULT_WAKE_UNLOCK_PATH)
+ osi_free(wake_unlock_path);
+ wake_unlock_path = osi_strndup(unlock_path, PATH_MAX);
+ }
+
+}
+
static bool lazy_initialize(void) {
assert(alarms == NULL);
@@ -478,16 +508,22 @@ static void callback_dispatch(UNUSED_ATTR void *context) {
static void initialize_wake_fds(void) {
LOG_DEBUG(LOG_TAG, "%s opening wake locks", __func__);
- wake_lock_fd = open(WAKE_LOCK_PATH, O_RDWR | O_CLOEXEC);
+ if (!wake_lock_path)
+ wake_lock_path = DEFAULT_WAKE_LOCK_PATH;
+
+ wake_lock_fd = open(wake_lock_path, O_RDWR | O_CLOEXEC);
if (wake_lock_fd == INVALID_FD) {
LOG_ERROR(LOG_TAG, "%s can't open wake lock %s: %s",
- __func__, WAKE_LOCK_PATH, strerror(errno));
+ __func__, wake_lock_path, strerror(errno));
}
- wake_unlock_fd = open(WAKE_UNLOCK_PATH, O_RDWR | O_CLOEXEC);
+ if (!wake_unlock_path)
+ wake_unlock_path = DEFAULT_WAKE_UNLOCK_PATH;
+
+ wake_unlock_fd = open(wake_unlock_path, O_RDWR | O_CLOEXEC);
if (wake_unlock_fd == INVALID_FD) {
LOG_ERROR(LOG_TAG, "%s can't open wake unlock %s: %s",
- __func__, WAKE_UNLOCK_PATH, strerror(errno));
+ __func__, wake_unlock_path, strerror(errno));
}
}
diff --git a/osi/test/AlarmTestHarness.cpp b/osi/test/AlarmTestHarness.cpp
index 1f0cdb5..39407dd 100644
--- a/osi/test/AlarmTestHarness.cpp
+++ b/osi/test/AlarmTestHarness.cpp
@@ -16,11 +16,13 @@
*
******************************************************************************/
-#include <gtest/gtest.h>
-#include <hardware/bluetooth.h>
+#include "AlarmTestHarness.h"
+
+#include <fcntl.h>
+#include <sys/mman.h>
#include <unistd.h>
-#include "AlarmTestHarness.h"
+#include <hardware/bluetooth.h>
extern "C" {
#include "osi/include/alarm.h"
@@ -41,7 +43,6 @@ void AlarmTestHarness::SetUp() {
current_harness = this;
TIMER_INTERVAL_FOR_WAKELOCK_IN_MS = 100;
- lock_count = 0;
struct sigevent sigevent;
memset(&sigevent, 0, sizeof(sigevent));
@@ -49,44 +50,76 @@ void AlarmTestHarness::SetUp() {
sigevent.sigev_notify_function = (void (*)(union sigval))timer_callback;
sigevent.sigev_value.sival_ptr = NULL;
timer_create(CLOCK_BOOTTIME, &sigevent, &timer);
+
+ // TODO (jamuraa): maybe use base::CreateNewTempDirectory instead?
+#if defined(OS_GENERIC)
+ tmp_dir_ = "/tmp/btwlXXXXXX";
+#else // !defined(OS_GENERIC)
+ tmp_dir_ = "/data/local/tmp/btwlXXXXXX";
+#endif // !defined(OS_GENERIC)
+
+ char *buffer = const_cast<char *>(tmp_dir_.c_str());
+ char *dtemp = mkdtemp(buffer);
+ if (!dtemp) {
+ perror("Can't make wake lock test directory: ");
+ assert(false);
+ }
+
+ lock_path_ = tmp_dir_ + "/wake_lock";
+ unlock_path_ = tmp_dir_ + "/wake_unlock";
+
+ creat(lock_path_.c_str(), S_IRWXU);
+ creat(unlock_path_.c_str(), S_IRWXU);
+
+ alarm_set_wake_lock_paths(lock_path_.c_str(), unlock_path_.c_str());
}
void AlarmTestHarness::TearDown() {
alarm_cleanup();
+
+ // clean up the temp wake lock directory
+ unlink(lock_path_.c_str());
+ unlink(unlock_path_.c_str());
+ rmdir(tmp_dir_.c_str());
+
timer_delete(timer);
AllocationTestHarness::TearDown();
}
-static bool set_wake_alarm(uint64_t delay_millis, bool, alarm_cb cb, void *data) {
- saved_callback = cb;
- saved_data = data;
- struct itimerspec wakeup_time;
- memset(&wakeup_time, 0, sizeof(wakeup_time));
- wakeup_time.it_value.tv_sec = (delay_millis / 1000);
- wakeup_time.it_value.tv_nsec = (delay_millis % 1000) * 1000000LL;
- timer_settime(timer, 0, &wakeup_time, NULL);
- return true;
-}
+bool AlarmTestHarness::WakeLockHeld() {
+ bool held = false;
-static int acquire_wake_lock(const char *) {
- if (!current_harness->lock_count)
- current_harness->lock_count = 1;
- return BT_STATUS_SUCCESS;
-}
+ int lock_fd = open(lock_path_.c_str(), O_RDONLY);
+ assert(lock_fd >= 0);
-static int release_wake_lock(const char *) {
- if (current_harness->lock_count)
- current_harness->lock_count = 0;
- return BT_STATUS_SUCCESS;
-}
+ int unlock_fd = open(unlock_path_.c_str(), O_RDONLY);
+ assert(unlock_fd >= 0);
-static bt_os_callouts_t stub = {
- sizeof(bt_os_callouts_t),
- set_wake_alarm,
- acquire_wake_lock,
- release_wake_lock,
-};
+ struct stat lock_stat, unlock_stat;
+ fstat(lock_fd, &lock_stat);
+ fstat(unlock_fd, &unlock_stat);
-bt_os_callouts_t *bt_os_callouts = &stub;
+ assert(lock_stat.st_size >= unlock_stat.st_size);
+ void *lock_file = mmap(nullptr, lock_stat.st_size, PROT_READ,
+ MAP_PRIVATE, lock_fd, 0);
+
+ void *unlock_file = mmap(nullptr, unlock_stat.st_size, PROT_READ,
+ MAP_PRIVATE, unlock_fd, 0);
+
+ if (memcmp(lock_file, unlock_file, unlock_stat.st_size) == 0) {
+ held = lock_stat.st_size > unlock_stat.st_size;
+ } else {
+ // these files should always either be with a lock that has more,
+ // or equal.
+ assert(false);
+ }
+
+ munmap(lock_file, lock_stat.st_size);
+ munmap(unlock_file, unlock_stat.st_size);
+ close(lock_fd);
+ close(unlock_fd);
+
+ return held;
+}
diff --git a/osi/test/AlarmTestHarness.h b/osi/test/AlarmTestHarness.h
index d4146bb..dbd09b0 100644
--- a/osi/test/AlarmTestHarness.h
+++ b/osi/test/AlarmTestHarness.h
@@ -27,6 +27,11 @@ class AlarmTestHarness : public AllocationTestHarness {
virtual void SetUp();
virtual void TearDown();
+ std::string tmp_dir_;
+ std::string lock_path_;
+ std::string unlock_path_;
+
public:
- int lock_count;
+ // Returns true if a wake lock is held.
+ bool WakeLockHeld();
};
diff --git a/osi/test/AllocationTestHarness.h b/osi/test/AllocationTestHarness.h
index b906936..65fc0b0 100644
--- a/osi/test/AllocationTestHarness.h
+++ b/osi/test/AllocationTestHarness.h
@@ -18,6 +18,8 @@
#pragma once
+#include <gtest/gtest.h>
+
class AllocationTestHarness : public ::testing::Test {
protected:
virtual void SetUp();
diff --git a/osi/test/alarm_test.cpp b/osi/test/alarm_test.cpp
index 32e1103..1b4895c 100644
--- a/osi/test/alarm_test.cpp
+++ b/osi/test/alarm_test.cpp
@@ -79,7 +79,7 @@ TEST_F(AlarmTest, test_cancel) {
msleep(10 + EPSILON_MS);
EXPECT_EQ(cb_counter, 0);
- EXPECT_EQ(lock_count, 0);
+ EXPECT_FALSE(WakeLockHeld());;
alarm_free(alarm);
}
@@ -97,12 +97,12 @@ TEST_F(AlarmTest, test_set_short) {
alarm_set(alarm, 10, cb, NULL);
EXPECT_EQ(cb_counter, 0);
- EXPECT_EQ(lock_count, 1);
+ EXPECT_TRUE(WakeLockHeld());
semaphore_wait(semaphore);
EXPECT_EQ(cb_counter, 1);
- EXPECT_EQ(lock_count, 0);
+ EXPECT_FALSE(WakeLockHeld());
alarm_free(alarm);
}
@@ -112,12 +112,12 @@ TEST_F(AlarmTest, test_set_long) {
alarm_set(alarm, TIMER_INTERVAL_FOR_WAKELOCK_IN_MS, cb, NULL);
EXPECT_EQ(cb_counter, 0);
- EXPECT_EQ(lock_count, 0);
+ EXPECT_FALSE(WakeLockHeld());
semaphore_wait(semaphore);
EXPECT_EQ(cb_counter, 1);
- EXPECT_EQ(lock_count, 0);
+ EXPECT_FALSE(WakeLockHeld());
alarm_free(alarm);
}
@@ -132,17 +132,17 @@ TEST_F(AlarmTest, test_set_short_short) {
alarm_set(alarm[1], 20, cb, NULL);
EXPECT_EQ(cb_counter, 0);
- EXPECT_EQ(lock_count, 1);
+ EXPECT_TRUE(WakeLockHeld());
semaphore_wait(semaphore);
EXPECT_EQ(cb_counter, 1);
- EXPECT_EQ(lock_count, 1);
+ EXPECT_TRUE(WakeLockHeld());
semaphore_wait(semaphore);
EXPECT_EQ(cb_counter, 2);
- EXPECT_EQ(lock_count, 0);
+ EXPECT_FALSE(WakeLockHeld());
alarm_free(alarm[0]);
alarm_free(alarm[1]);
@@ -158,17 +158,17 @@ TEST_F(AlarmTest, test_set_short_long) {
alarm_set(alarm[1], 10 + TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL);
EXPECT_EQ(cb_counter, 0);
- EXPECT_EQ(lock_count, 1);
+ EXPECT_TRUE(WakeLockHeld());
semaphore_wait(semaphore);
EXPECT_EQ(cb_counter, 1);
- EXPECT_EQ(lock_count, 0);
+ EXPECT_FALSE(WakeLockHeld());
semaphore_wait(semaphore);
EXPECT_EQ(cb_counter, 2);
- EXPECT_EQ(lock_count, 0);
+ EXPECT_FALSE(WakeLockHeld());
alarm_free(alarm[0]);
alarm_free(alarm[1]);
@@ -184,17 +184,17 @@ TEST_F(AlarmTest, test_set_long_long) {
alarm_set(alarm[1], 2 * TIMER_INTERVAL_FOR_WAKELOCK_IN_MS + EPSILON_MS, cb, NULL);
EXPECT_EQ(cb_counter, 0);
- EXPECT_EQ(lock_count, 0);
+ EXPECT_FALSE(WakeLockHeld());
semaphore_wait(semaphore);
EXPECT_EQ(cb_counter, 1);
- EXPECT_EQ(lock_count, 0);
+ EXPECT_FALSE(WakeLockHeld());
semaphore_wait(semaphore);
EXPECT_EQ(cb_counter, 2);
- EXPECT_EQ(lock_count, 0);
+ EXPECT_FALSE(WakeLockHeld());
alarm_free(alarm[0]);
alarm_free(alarm[1]);