• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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