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 AudioNanoapp : public TestNanoapp {
40 public:
AudioNanoapp()41 AudioNanoapp()
42 : TestNanoapp(
43 TestNanoappInfo{.perms = NanoappPermissions::CHRE_PERMS_AUDIO}) {}
44
start()45 bool start() override {
46 chreUserSettingConfigureEvents(CHRE_USER_SETTING_MICROPHONE,
47 true /* enable */);
48 return true;
49 }
50 };
51
TEST_F(TestBase,AudioCanSubscribeAndUnsubscribeToDataEvents)52 TEST_F(TestBase, AudioCanSubscribeAndUnsubscribeToDataEvents) {
53 CREATE_CHRE_TEST_EVENT(CONFIGURE, 0);
54
55 class App : public AudioNanoapp {
56 public:
57 void handleEvent(uint32_t, uint16_t eventType,
58 const void *eventData) override {
59 switch (eventType) {
60 case CHRE_EVENT_AUDIO_DATA: {
61 auto event =
62 static_cast<const struct chreAudioDataEvent *>(eventData);
63 if (event->handle == 0) {
64 mCount++;
65 if (mCount == 3) {
66 TestEventQueueSingleton::get()->pushEvent(CHRE_EVENT_AUDIO_DATA);
67 }
68 }
69 break;
70 }
71
72 case CHRE_EVENT_AUDIO_SAMPLING_CHANGE: {
73 auto event =
74 static_cast<const struct chreAudioSourceStatusEvent *>(eventData);
75 if (event->handle == 0) {
76 TestEventQueueSingleton::get()->pushEvent(
77 CHRE_EVENT_AUDIO_SAMPLING_CHANGE);
78 }
79 break;
80 }
81
82 case CHRE_EVENT_TEST_EVENT: {
83 auto event = static_cast<const TestEvent *>(eventData);
84 switch (event->type) {
85 case CONFIGURE: {
86 auto enable = static_cast<const bool *>(event->data);
87 const bool success = chreAudioConfigureSource(
88 0 /*handle*/, *enable, 1000000 /*bufferDuration*/,
89 1000000 /*deliveryInterval*/);
90 TestEventQueueSingleton::get()->pushEvent(CONFIGURE, success);
91 break;
92 }
93 }
94 }
95 }
96 }
97
98 protected:
99 int mCount = 0;
100 };
101
102 uint64_t appId = loadNanoapp(MakeUnique<App>());
103 EXPECT_FALSE(chrePalAudioIsHandle0Enabled());
104
105 bool enable = true;
106 bool success;
107 sendEventToNanoapp(appId, CONFIGURE, enable);
108 waitForEvent(CONFIGURE, &success);
109 EXPECT_TRUE(success);
110 waitForEvent(CHRE_EVENT_AUDIO_SAMPLING_CHANGE);
111 EXPECT_TRUE(chrePalAudioIsHandle0Enabled());
112
113 waitForEvent(CHRE_EVENT_AUDIO_DATA);
114
115 enable = false;
116 sendEventToNanoapp(appId, CONFIGURE, enable);
117 waitForEvent(CONFIGURE, &success);
118 EXPECT_TRUE(success);
119 EXPECT_FALSE(chrePalAudioIsHandle0Enabled());
120 }
121
TEST_F(TestBase,AudioUnsubscribeToDataEventsOnUnload)122 TEST_F(TestBase, AudioUnsubscribeToDataEventsOnUnload) {
123 CREATE_CHRE_TEST_EVENT(CONFIGURE, 0);
124
125 class App : public AudioNanoapp {
126 public:
127 void handleEvent(uint32_t, uint16_t eventType, const void *eventData) {
128 switch (eventType) {
129 case CHRE_EVENT_AUDIO_SAMPLING_CHANGE: {
130 auto event =
131 static_cast<const struct chreAudioSourceStatusEvent *>(eventData);
132 if (event->handle == 0) {
133 TestEventQueueSingleton::get()->pushEvent(
134 CHRE_EVENT_AUDIO_SAMPLING_CHANGE);
135 }
136 break;
137 }
138
139 case CHRE_EVENT_TEST_EVENT: {
140 auto event = static_cast<const TestEvent *>(eventData);
141 switch (event->type) {
142 case CONFIGURE: {
143 auto enable = static_cast<const bool *>(event->data);
144 const bool success = chreAudioConfigureSource(
145 0 /*handle*/, *enable, 1000000 /*bufferDuration*/,
146 1000000 /*deliveryInterval*/);
147 TestEventQueueSingleton::get()->pushEvent(CONFIGURE, success);
148 break;
149 }
150 }
151 }
152 }
153 }
154 };
155
156 uint64_t appId = loadNanoapp(MakeUnique<App>());
157 EXPECT_FALSE(chrePalAudioIsHandle0Enabled());
158
159 bool enable = true;
160 bool success;
161 sendEventToNanoapp(appId, CONFIGURE, enable);
162 waitForEvent(CONFIGURE, &success);
163 EXPECT_TRUE(success);
164 waitForEvent(CHRE_EVENT_AUDIO_SAMPLING_CHANGE);
165 EXPECT_TRUE(chrePalAudioIsHandle0Enabled());
166
167 unloadNanoapp(appId);
168 EXPECT_FALSE(chrePalAudioIsHandle0Enabled());
169 }
170
171 } // namespace
172 } // namespace chre