1 /*
2 * Copyright 2021 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 //#define LOG_NDEBUG 0
18 #define LOG_TAG "AData_test"
19
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22 #include <utils/RefBase.h>
23
24 #include <media/stagefright/foundation/AMessage.h>
25 #include <media/stagefright/foundation/AHandler.h>
26 #include <media/stagefright/foundation/ALooper.h>
27
28 using namespace android;
29
30 using ::testing::InSequence;
31 using ::testing::NiceMock;
32
33 class LooperWithSettableClock : public ALooper {
34 public:
LooperWithSettableClock()35 LooperWithSettableClock() : mClockUs(0) {}
36
setClockUs(int64_t nowUs)37 void setClockUs(int64_t nowUs) {
38 mClockUs = nowUs;
39 }
40
getNowUs()41 int64_t getNowUs() override {
42 return mClockUs;
43 }
44
45 private:
46 int64_t mClockUs;
47 };
48
49 timespec millis100 = {0, 100L*1000*1000};
50
51 class MockHandler : public AHandler {
52 public:
53 MOCK_METHOD(void, onMessageReceived, (const sp<AMessage>&), (override));
54 };
55
TEST(AMessage_tests,countsAndLimits)56 TEST(AMessage_tests, countsAndLimits) {
57 sp<AMessage> m1 = new AMessage();
58
59 // clear, countEntries, maxAllowedEntries
60
61 EXPECT_EQ(0, m1->countEntries());
62
63 m1->setInt32("smaller", INT32_MAX - 2);
64 m1->setInt64("big", INT64_MAX);
65 m1->setString("bigBallOfString", "whatever");
66 EXPECT_EQ(3, m1->countEntries());
67
68 m1->clear();
69 EXPECT_EQ(0, m1->countEntries());
70
71 EXPECT_TRUE(m1->maxAllowedEntries() > 0);
72 EXPECT_TRUE(AMessage::maxAllowedEntries() > 0);
73
74 // static function, make sure we get a consistent answer
75 EXPECT_EQ(m1->maxAllowedEntries(), AMessage::maxAllowedEntries());
76 }
77
TEST(AMessage_tests,settersAndGetters)78 TEST(AMessage_tests, settersAndGetters) {
79 sp<AMessage> m1 = new AMessage();
80
81 m1->setInt32("value", 2);
82 m1->setInt32("bar", 3);
83
84 int32_t i32;
85 EXPECT_TRUE(m1->findInt32("value", &i32));
86 EXPECT_EQ(2, i32);
87
88 EXPECT_TRUE(m1->findInt32("bar", &i32));
89 EXPECT_EQ(3, i32);
90
91
92 m1->setInt64("big", INT64_MAX);
93 m1->setInt64("smaller", INT64_MAX - 2);
94 m1->setInt64("smallest", 257);
95
96 int64_t i64;
97 EXPECT_TRUE(m1->findInt64("big", &i64));
98 EXPECT_EQ(INT64_MAX, i64);
99
100 EXPECT_TRUE(m1->findInt64("smaller", &i64));
101 EXPECT_EQ(INT64_MAX - 2, i64);
102
103 m1->setSize("size1", 257);
104 m1->setSize("size2", 1023);
105
106 size_t sizing;
107 EXPECT_TRUE(m1->findSize("size2", &sizing));
108 EXPECT_EQ(1023, sizing);
109 EXPECT_TRUE(m1->findSize("size1", &sizing));
110 EXPECT_EQ(257, sizing);
111
112 m1->setDouble("precise", 10.5);
113 m1->setDouble("small", 0.125);
114
115 double d;
116 EXPECT_TRUE(m1->findDouble("precise", &d));
117 EXPECT_EQ(10.5, d);
118
119 EXPECT_TRUE(m1->findDouble("small", &d));
120 EXPECT_EQ(0.125, d);
121
122 // should be unchanged from the top of the test
123 EXPECT_TRUE(m1->findInt32("bar", &i32));
124 EXPECT_EQ(3, i32);
125
126 EXPECT_FALSE(m1->findInt32("nonesuch", &i32));
127 EXPECT_FALSE(m1->findInt64("nonesuch2", &i64));
128 // types disagree, not found
129 EXPECT_FALSE(m1->findInt32("big", &i32));
130 EXPECT_FALSE(m1->findInt32("precise", &i32));
131
132 // integral types should come back true
133 EXPECT_TRUE(m1->findAsInt64("big", &i64));
134 EXPECT_EQ(INT64_MAX, i64);
135 EXPECT_TRUE(m1->findAsInt64("bar", &i64));
136 EXPECT_EQ(3, i64);
137 EXPECT_FALSE(m1->findAsInt64("precise", &i64));
138
139 // recovers ints, size, and floating point values
140 float value;
141 EXPECT_TRUE(m1->findAsFloat("value", &value));
142 EXPECT_EQ(2, value);
143 EXPECT_TRUE(m1->findAsFloat("smallest", &value));
144 EXPECT_EQ(257, value);
145 EXPECT_TRUE(m1->findAsFloat("size2", &value));
146 EXPECT_EQ(1023, value);
147 EXPECT_TRUE(m1->findAsFloat("precise", &value));
148 EXPECT_EQ(10.5, value);
149 EXPECT_TRUE(m1->findAsFloat("small", &value));
150 EXPECT_EQ(0.125, value);
151
152
153 // need to handle still:
154 // strings
155 // Object
156 // Buffer
157 // Message (nested)
158 //
159
160 // removal
161 m1->setInt32("shortlived", 2);
162 m1->setInt32("alittlelonger", 2);
163 EXPECT_EQ(OK, m1->removeEntryByName("shortlived"));
164 EXPECT_EQ(BAD_VALUE, m1->removeEntryByName(nullptr));
165 EXPECT_EQ(BAD_INDEX, m1->removeEntryByName("themythicalnonesuch"));
166 EXPECT_FALSE(m1->findInt32("shortlived", &i32));
167 EXPECT_TRUE(m1->findInt32("alittlelonger", &i32));
168
169 EXPECT_NE(OK, m1->removeEntryByName("notpresent"));
170 }
171
TEST(AMessage_tests,deliversMultipleMessagesInOrderImmediately)172 TEST(AMessage_tests, deliversMultipleMessagesInOrderImmediately) {
173 sp<NiceMock<MockHandler>> mockHandler = new NiceMock<MockHandler>;
174 sp<LooperWithSettableClock> looper = new LooperWithSettableClock();
175 looper->registerHandler(mockHandler);
176
177 sp<AMessage> msgNow1 = new AMessage(0, mockHandler);
178 msgNow1->post();
179 sp<AMessage> msgNow2 = new AMessage(0, mockHandler);
180 msgNow2->post();
181
182 {
183 InSequence inSequence;
184 EXPECT_CALL(*mockHandler, onMessageReceived(msgNow1)).Times(1);
185 EXPECT_CALL(*mockHandler, onMessageReceived(msgNow2)).Times(1);
186 }
187 looper->start();
188 nanosleep(&millis100, nullptr); // just enough time for the looper thread to run
189 }
190
TEST(AMessage_tests,doesNotDeliverDelayedMessageImmediately)191 TEST(AMessage_tests, doesNotDeliverDelayedMessageImmediately) {
192 sp<NiceMock<MockHandler>> mockHandler = new NiceMock<MockHandler>;
193 sp<LooperWithSettableClock> looper = new LooperWithSettableClock();
194 looper->registerHandler(mockHandler);
195
196 sp<AMessage> msgNow = new AMessage(0, mockHandler);
197 msgNow->post();
198 sp<AMessage> msgDelayed = new AMessage(0, mockHandler);
199 msgDelayed->post(100);
200
201 EXPECT_CALL(*mockHandler, onMessageReceived(msgNow)).Times(1);
202 // note: never called
203 EXPECT_CALL(*mockHandler, onMessageReceived(msgDelayed)).Times(0);
204 looper->start();
205 nanosleep(&millis100, nullptr); // just enough time for the looper thread to run
206 }
207
TEST(AMessage_tests,deliversDelayedMessagesInSequence)208 TEST(AMessage_tests, deliversDelayedMessagesInSequence) {
209 sp<NiceMock<MockHandler>> mockHandler = new NiceMock<MockHandler>;
210 sp<LooperWithSettableClock> looper = new LooperWithSettableClock();
211 looper->registerHandler(mockHandler);
212
213 sp<AMessage> msgIn500 = new AMessage(0, mockHandler);
214 msgIn500->post(500);
215 sp<AMessage> msgNow = new AMessage(0, mockHandler);
216 msgNow->post();
217 sp<AMessage> msgIn100 = new AMessage(0, mockHandler);
218 msgIn100->post(100);
219 // not expected to be received
220 sp<AMessage> msgIn1000 = new AMessage(0, mockHandler);
221 msgIn1000->post(1000);
222
223 looper->setClockUs(500);
224 {
225 InSequence inSequence;
226
227 EXPECT_CALL(*mockHandler, onMessageReceived(msgNow)).Times(1);
228 EXPECT_CALL(*mockHandler, onMessageReceived(msgIn100)).Times(1);
229 EXPECT_CALL(*mockHandler, onMessageReceived(msgIn500)).Times(1);
230 }
231 // note: never called
232 EXPECT_CALL(*mockHandler, onMessageReceived(msgIn1000)).Times(0);
233 looper->start();
234 nanosleep(&millis100, nullptr); // just enough time for the looper thread to run
235 }
236
TEST(AMessage_tests,deliversDelayedUniqueMessage)237 TEST(AMessage_tests, deliversDelayedUniqueMessage) {
238 sp<NiceMock<MockHandler>> mockHandler = new NiceMock<MockHandler>;
239 sp<LooperWithSettableClock> looper = new LooperWithSettableClock();
240 looper->registerHandler(mockHandler);
241
242 sp<AMessage> msg = new AMessage(0, mockHandler);
243 msg->postUnique(msg, 50);
244
245 looper->setClockUs(50);
246 EXPECT_CALL(*mockHandler, onMessageReceived(msg)).Times(1);
247 looper->start();
248 nanosleep(&millis100, nullptr); // just enough time for the looper thread to run
249 }
250
TEST(AMessage_tests,deliversImmediateUniqueMessage)251 TEST(AMessage_tests, deliversImmediateUniqueMessage) {
252 sp<NiceMock<MockHandler>> mockHandler = new NiceMock<MockHandler>;
253 // note: we don't need to set the clock, but we do want a stable clock that doesn't advance
254 sp<LooperWithSettableClock> looper = new LooperWithSettableClock();
255 looper->registerHandler(mockHandler);
256
257 sp<AMessage> msg = new AMessage(0, mockHandler);
258 msg->postUnique(msg, 0);
259
260 EXPECT_CALL(*mockHandler, onMessageReceived(msg)).Times(1);
261 looper->start();
262 nanosleep(&millis100, nullptr); // just enough time for the looper thread to run
263 }
264
TEST(AMessage_tests,doesNotDeliverUniqueMessageAfterRescheduleLater)265 TEST(AMessage_tests, doesNotDeliverUniqueMessageAfterRescheduleLater) {
266 sp<NiceMock<MockHandler>> mockHandler = new NiceMock<MockHandler>;
267 sp<LooperWithSettableClock> looper = new LooperWithSettableClock();
268 looper->registerHandler(mockHandler);
269
270 sp<AMessage> msg = new AMessage(0, mockHandler);
271 msg->postUnique(msg, 50);
272 msg->postUnique(msg, 100); // reschedule for later
273
274 looper->setClockUs(50); // if the message is correctly rescheduled, it should not be delivered
275 // Never called because the message was rescheduled to a later point in time
276 EXPECT_CALL(*mockHandler, onMessageReceived(msg)).Times(0);
277 looper->start();
278 nanosleep(&millis100, nullptr); // just enough time for the looper thread to run
279 }
280
TEST(AMessage_tests,deliversUniqueMessageAfterRescheduleEarlier)281 TEST(AMessage_tests, deliversUniqueMessageAfterRescheduleEarlier) {
282 sp<NiceMock<MockHandler>> mockHandler = new NiceMock<MockHandler>;
283 sp<LooperWithSettableClock> looper = new LooperWithSettableClock();
284 looper->registerHandler(mockHandler);
285
286 sp<AMessage> msg = new AMessage(0, mockHandler);
287 msg->postUnique(msg, 100);
288 msg->postUnique(msg, 50); // reschedule to fire earlier
289
290 looper->setClockUs(50); // if the message is rescheduled correctly, it should be delivered
291 EXPECT_CALL(*mockHandler, onMessageReceived(msg)).Times(1);
292 looper->start();
293 nanosleep(&millis100, nullptr); // just enough time for the looper thread to run
294 }
295
TEST(AMessage_tests,deliversSameMessageTwice)296 TEST(AMessage_tests, deliversSameMessageTwice) {
297 sp<NiceMock<MockHandler>> mockHandler = new NiceMock<MockHandler>;
298 sp<LooperWithSettableClock> looper = new LooperWithSettableClock();
299 looper->registerHandler(mockHandler);
300
301 sp<AMessage> msg = new AMessage(0, mockHandler);
302 msg->post(50);
303 msg->post(100);
304
305 looper->setClockUs(100);
306 EXPECT_CALL(*mockHandler, onMessageReceived(msg)).Times(2);
307 looper->start();
308 nanosleep(&millis100, nullptr); // just enough time for the looper thread to run
309 }
310
311 // When messages are posted twice with the same token, it will only be delivered once after being
312 // rescheduled.
TEST(AMessage_tests,deliversUniqueMessageOnce)313 TEST(AMessage_tests, deliversUniqueMessageOnce) {
314 sp<NiceMock<MockHandler>> mockHandler = new NiceMock<MockHandler>;
315 sp<LooperWithSettableClock> looper = new LooperWithSettableClock();
316 looper->registerHandler(mockHandler);
317
318 sp<AMessage> msg1 = new AMessage(0, mockHandler);
319 msg1->postUnique(msg1, 50);
320 sp<AMessage> msg2 = new AMessage(0, mockHandler);
321 msg2->postUnique(msg1, 75); // note, using the same token as msg1
322
323 looper->setClockUs(100);
324 EXPECT_CALL(*mockHandler, onMessageReceived(msg1)).Times(0);
325 EXPECT_CALL(*mockHandler, onMessageReceived(msg2)).Times(1);
326 looper->start();
327 nanosleep(&millis100, nullptr); // just enough time for the looper thread to run
328 }
329
TEST(AMessage_tests,postUnique_withNullToken_returnsInvalidArgument)330 TEST(AMessage_tests, postUnique_withNullToken_returnsInvalidArgument) {
331 sp<NiceMock<MockHandler>> mockHandler = new NiceMock<MockHandler>;
332 sp<ALooper> looper = new ALooper();
333 looper->registerHandler(mockHandler);
334
335 sp<AMessage> msg = new AMessage(0, mockHandler);
336 EXPECT_EQ(msg->postUnique(nullptr, 0), -EINVAL);
337 }
338