1/*
2 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/modules/audio_device/android/low_latency_event.h"
12
13#include "testing/gtest/include/gtest/gtest.h"
14#include "webrtc/system_wrappers/interface/scoped_ptr.h"
15#include "webrtc/system_wrappers/interface/sleep.h"
16#include "webrtc/system_wrappers/interface/thread_wrapper.h"
17
18namespace webrtc {
19
20static const int kEventMsg = 1;
21
22class LowLatencyEventTest : public testing::Test {
23 public:
24  LowLatencyEventTest()
25      : process_thread_(ThreadWrapper::CreateThread(CbThread,
26                                                    this,
27                                                    kRealtimePriority,
28                                                    "test_thread")),
29        terminated_(false),
30        iteration_count_(0),
31        allowed_iterations_(0) {
32    EXPECT_TRUE(event_.Start());
33    Start();
34  }
35  ~LowLatencyEventTest() {
36    EXPECT_GE(allowed_iterations_, 1);
37    EXPECT_GE(iteration_count_, 1);
38    Stop();
39  }
40
41  void AllowOneIteration() {
42    ++allowed_iterations_;
43    event_.SignalEvent(allowed_iterations_, kEventMsg);
44  }
45
46 private:
47  void Start() {
48    unsigned int thread_id = 0;
49    EXPECT_TRUE(process_thread_->Start(thread_id));
50  }
51  void Stop() {
52    terminated_ = true;
53    event_.Stop();
54    process_thread_->Stop();
55  }
56
57  static bool CbThread(void* context) {
58    return reinterpret_cast<LowLatencyEventTest*>(context)->CbThreadImpl();
59  }
60  bool CbThreadImpl() {
61    int allowed_iterations;
62    int message;
63    ++iteration_count_;
64    event_.WaitOnEvent(&allowed_iterations, &message);
65    EXPECT_EQ(iteration_count_, allowed_iterations);
66    EXPECT_EQ(message, kEventMsg);
67    return !terminated_;
68  }
69
70  LowLatencyEvent event_;
71
72  scoped_ptr<ThreadWrapper> process_thread_;
73  bool terminated_;
74  int iteration_count_;
75  int allowed_iterations_;
76};
77
78
79TEST_F(LowLatencyEventTest, TriggerEvent) {
80  for (int i = 0; i < 3; ++i) {
81    AllowOneIteration();
82  }
83}
84
85// Events trigger in less than 3ms. Wait for 3 ms to ensure there are no
86// spurious wakeups.
87TEST_F(LowLatencyEventTest, NoTriggerEvent) {
88  SleepMs(3);
89  // If there were spurious wakeups either the wakeups would have triggered a
90  // failure as we haven't allowed an iteration yet. Or the wakeup happened
91  // to signal 0, 0 in which case the mismatch will be discovered when allowing
92  // an iteration to happen.
93  AllowOneIteration();
94}
95
96}  // namespace webrtc
97