1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "chre_api/chre/audio.h"
18
19 #include <cstdint>
20
21 #include "chre/core/event_loop_manager.h"
22 #include "chre/core/settings.h"
23 #include "chre/platform/linux/pal_audio.h"
24 #include "chre/platform/log.h"
25 #include "chre/util/system/napp_permissions.h"
26 #include "chre_api/chre/event.h"
27 #include "chre_api/chre/user_settings.h"
28
29 #include "gtest/gtest.h"
30 #include "inc/test_util.h"
31 #include "test_base.h"
32 #include "test_event.h"
33 #include "test_event_queue.h"
34 #include "test_util.h"
35
36 namespace chre {
37 namespace {
38
39 class AudioTest : public TestBase {};
40
41 class AudioNanoapp : public TestNanoapp {
42 public:
AudioNanoapp()43 AudioNanoapp()
44 : TestNanoapp(
45 TestNanoappInfo{.perms = NanoappPermissions::CHRE_PERMS_AUDIO}) {}
46
start()47 bool start() override {
48 chreUserSettingConfigureEvents(CHRE_USER_SETTING_MICROPHONE,
49 true /* enable */);
50 return true;
51 }
52 };
53
TEST_F(AudioTest,AudioCanSubscribeAndUnsubscribeToDataEvents)54 TEST_F(AudioTest, AudioCanSubscribeAndUnsubscribeToDataEvents) {
55 CREATE_CHRE_TEST_EVENT(CONFIGURE, 0);
56
57 class App : public AudioNanoapp {
58 public:
59 void handleEvent(uint32_t, uint16_t eventType,
60 const void *eventData) override {
61 switch (eventType) {
62 case CHRE_EVENT_AUDIO_DATA: {
63 auto event =
64 static_cast<const struct chreAudioDataEvent *>(eventData);
65 if (event->handle == 0) {
66 mCount++;
67 if (mCount == 3) {
68 TestEventQueueSingleton::get()->pushEvent(CHRE_EVENT_AUDIO_DATA);
69 }
70 }
71 break;
72 }
73
74 case CHRE_EVENT_AUDIO_SAMPLING_CHANGE: {
75 auto event =
76 static_cast<const struct chreAudioSourceStatusEvent *>(eventData);
77 if (event->handle == 0) {
78 TestEventQueueSingleton::get()->pushEvent(
79 CHRE_EVENT_AUDIO_SAMPLING_CHANGE);
80 }
81 break;
82 }
83
84 case CHRE_EVENT_TEST_EVENT: {
85 auto event = static_cast<const TestEvent *>(eventData);
86 switch (event->type) {
87 case CONFIGURE: {
88 auto enable = static_cast<const bool *>(event->data);
89 const bool success = chreAudioConfigureSource(
90 0 /*handle*/, *enable, 1000000 /*bufferDuration*/,
91 1000000 /*deliveryInterval*/);
92 TestEventQueueSingleton::get()->pushEvent(CONFIGURE, success);
93 break;
94 }
95 }
96 }
97 }
98 }
99
100 protected:
101 int mCount = 0;
102 };
103
104 uint64_t appId = loadNanoapp(MakeUnique<App>());
105 EXPECT_FALSE(chrePalAudioIsHandle0Enabled());
106
107 bool enable = true;
108 bool success;
109 sendEventToNanoapp(appId, CONFIGURE, enable);
110 waitForEvent(CONFIGURE, &success);
111 EXPECT_TRUE(success);
112 waitForEvent(CHRE_EVENT_AUDIO_SAMPLING_CHANGE);
113 EXPECT_TRUE(chrePalAudioIsHandle0Enabled());
114
115 waitForEvent(CHRE_EVENT_AUDIO_DATA);
116
117 enable = false;
118 sendEventToNanoapp(appId, CONFIGURE, enable);
119 waitForEvent(CONFIGURE, &success);
120 EXPECT_TRUE(success);
121 EXPECT_FALSE(chrePalAudioIsHandle0Enabled());
122 }
123
TEST_F(AudioTest,AudioUnsubscribeToDataEventsOnUnload)124 TEST_F(AudioTest, AudioUnsubscribeToDataEventsOnUnload) {
125 CREATE_CHRE_TEST_EVENT(CONFIGURE, 0);
126
127 class App : public AudioNanoapp {
128 public:
129 void handleEvent(uint32_t, uint16_t eventType, const void *eventData) {
130 switch (eventType) {
131 case CHRE_EVENT_AUDIO_SAMPLING_CHANGE: {
132 auto event =
133 static_cast<const struct chreAudioSourceStatusEvent *>(eventData);
134 if (event->handle == 0) {
135 TestEventQueueSingleton::get()->pushEvent(
136 CHRE_EVENT_AUDIO_SAMPLING_CHANGE);
137 }
138 break;
139 }
140
141 case CHRE_EVENT_TEST_EVENT: {
142 auto event = static_cast<const TestEvent *>(eventData);
143 switch (event->type) {
144 case CONFIGURE: {
145 auto enable = static_cast<const bool *>(event->data);
146 const bool success = chreAudioConfigureSource(
147 0 /*handle*/, *enable, 1000000 /*bufferDuration*/,
148 1000000 /*deliveryInterval*/);
149 TestEventQueueSingleton::get()->pushEvent(CONFIGURE, success);
150 break;
151 }
152 }
153 }
154 }
155 }
156 };
157
158 uint64_t appId = loadNanoapp(MakeUnique<App>());
159 EXPECT_FALSE(chrePalAudioIsHandle0Enabled());
160
161 bool enable = true;
162 bool success;
163 sendEventToNanoapp(appId, CONFIGURE, enable);
164 waitForEvent(CONFIGURE, &success);
165 EXPECT_TRUE(success);
166 waitForEvent(CHRE_EVENT_AUDIO_SAMPLING_CHANGE);
167 EXPECT_TRUE(chrePalAudioIsHandle0Enabled());
168
169 unloadNanoapp(appId);
170 EXPECT_FALSE(chrePalAudioIsHandle0Enabled());
171 }
172
173 } // namespace
174 } // namespace chre