1 /*
2 * Copyright (C) 2019 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 // Unit Test for MediaTranscodingService.
18
19 //#define LOG_NDEBUG 0
20 #define LOG_TAG "MediaTranscodingServiceRealTest"
21
22 #include "MediaTranscodingServiceTestHelper.h"
23
24 /*
25 * Tests media transcoding service with real transcoder.
26 *
27 * Uses the same test assets as the MediaTranscoder unit tests. Before running the test,
28 * please make sure to push the test assets to /sdcard:
29 *
30 * adb push $TOP/frameworks/av/media/libmediatranscoding/transcoder/tests/assets /data/local/tmp/TranscodingTestAssets
31 */
32 namespace android {
33
34 namespace media {
35
36 constexpr int64_t kPaddingUs = 1000000;
37 constexpr int64_t kSessionWithPaddingUs = 10000000 + kPaddingUs;
38 constexpr int32_t kBitRate = 8 * 1000 * 1000; // 8Mbs
39
40 constexpr const char* kShortSrcPath =
41 "/data/local/tmp/TranscodingTestAssets/cubicle_avc_480x240_aac_24KHz.mp4";
42 constexpr const char* kLongSrcPath = "/data/local/tmp/TranscodingTestAssets/longtest_15s.mp4";
43
44 #define OUTPATH(name) "/data/local/tmp/MediaTranscodingService_" #name ".MP4"
45
46 class MediaTranscodingServiceRealTest : public MediaTranscodingServiceTestBase {
47 public:
MediaTranscodingServiceRealTest()48 MediaTranscodingServiceRealTest() { ALOGI("MediaTranscodingServiceResourceTest created"); }
49
~MediaTranscodingServiceRealTest()50 virtual ~MediaTranscodingServiceRealTest() {
51 ALOGI("MediaTranscodingServiceResourceTest destroyed");
52 }
53 };
54
TEST_F(MediaTranscodingServiceRealTest,TestInvalidSource)55 TEST_F(MediaTranscodingServiceRealTest, TestInvalidSource) {
56 registerMultipleClients();
57
58 const char* srcPath = "bad_file_uri";
59 const char* dstPath = prepareOutputFile(OUTPATH(TestInvalidSource));
60
61 // Submit one session.
62 EXPECT_TRUE(
63 mClient1->submit(0, srcPath, dstPath, TranscodingSessionPriority::kNormal, kBitRate));
64
65 // Check expected error.
66 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Failed(CLIENT(1), 0));
67 EXPECT_EQ(mClient1->getLastError(), TranscodingErrorCode::kErrorIO);
68
69 unregisterMultipleClients();
70 }
71
TEST_F(MediaTranscodingServiceRealTest,TestPassthru)72 TEST_F(MediaTranscodingServiceRealTest, TestPassthru) {
73 registerMultipleClients();
74
75 const char* dstPath = prepareOutputFile(OUTPATH(TestPassthru));
76
77 // Submit one session.
78 EXPECT_TRUE(mClient1->submit(0, kShortSrcPath, dstPath));
79
80 // Wait for session to finish.
81 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 0));
82 EXPECT_EQ(mClient1->pop(kSessionWithPaddingUs), EventTracker::Finished(CLIENT(1), 0));
83
84 unregisterMultipleClients();
85 }
86
TEST_F(MediaTranscodingServiceRealTest,TestTranscodeVideo)87 TEST_F(MediaTranscodingServiceRealTest, TestTranscodeVideo) {
88 registerMultipleClients();
89
90 const char* dstPath = prepareOutputFile(OUTPATH(TestTranscodeVideo));
91
92 // Submit one session.
93 EXPECT_TRUE(mClient1->submit(0, kShortSrcPath, dstPath, TranscodingSessionPriority::kNormal,
94 kBitRate));
95
96 // Wait for session to finish.
97 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 0));
98 EXPECT_EQ(mClient1->pop(kSessionWithPaddingUs), EventTracker::Finished(CLIENT(1), 0));
99
100 unregisterMultipleClients();
101 }
102
TEST_F(MediaTranscodingServiceRealTest,TestTranscodeVideoProgress)103 TEST_F(MediaTranscodingServiceRealTest, TestTranscodeVideoProgress) {
104 registerMultipleClients();
105
106 const char* dstPath = prepareOutputFile(OUTPATH(TestTranscodeVideoProgress));
107
108 // Submit one session.
109 EXPECT_TRUE(mClient1->submit(0, kLongSrcPath, dstPath, TranscodingSessionPriority::kNormal,
110 kBitRate));
111
112 // Wait for session to finish.
113 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 0));
114 EXPECT_EQ(mClient1->pop(kSessionWithPaddingUs), EventTracker::Finished(CLIENT(1), 0));
115
116 // Check the progress update messages are received. For this clip (around ~15 second long),
117 // expect at least 10 updates, and the last update should be 100.
118 int lastProgress;
119 EXPECT_GE(mClient1->getUpdateCount(&lastProgress), 10);
120 EXPECT_EQ(lastProgress, 100);
121
122 unregisterMultipleClients();
123 }
124
125 /*
126 * Test cancel immediately after start.
127 */
TEST_F(MediaTranscodingServiceRealTest,TestCancelImmediately)128 TEST_F(MediaTranscodingServiceRealTest, TestCancelImmediately) {
129 registerMultipleClients();
130
131 const char* srcPath0 = kLongSrcPath;
132 const char* srcPath1 = kShortSrcPath;
133 const char* dstPath0 = prepareOutputFile(OUTPATH(TestCancelImmediately_Session0));
134 const char* dstPath1 = prepareOutputFile(OUTPATH(TestCancelImmediately_Session1));
135
136 // Submit one session, should start immediately.
137 EXPECT_TRUE(
138 mClient1->submit(0, srcPath0, dstPath0, TranscodingSessionPriority::kNormal, kBitRate));
139 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 0));
140 EXPECT_TRUE(mClient1->getSession(0, srcPath0, dstPath0));
141
142 // Test cancel session immediately, getSession should fail after cancel.
143 EXPECT_TRUE(mClient1->cancel(0));
144 EXPECT_TRUE(mClient1->getSession<fail>(0, "", ""));
145
146 // Submit new session, new session should start immediately and finish.
147 EXPECT_TRUE(
148 mClient1->submit(1, srcPath1, dstPath1, TranscodingSessionPriority::kNormal, kBitRate));
149 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 1));
150 EXPECT_EQ(mClient1->pop(kSessionWithPaddingUs), EventTracker::Finished(CLIENT(1), 1));
151
152 unregisterMultipleClients();
153 }
154
155 /*
156 * Test cancel in the middle of transcoding.
157 */
TEST_F(MediaTranscodingServiceRealTest,TestCancelWhileRunning)158 TEST_F(MediaTranscodingServiceRealTest, TestCancelWhileRunning) {
159 registerMultipleClients();
160
161 const char* srcPath0 = kLongSrcPath;
162 const char* srcPath1 = kShortSrcPath;
163 const char* dstPath0 = prepareOutputFile(OUTPATH(TestCancelWhileRunning_Session0));
164 const char* dstPath1 = prepareOutputFile(OUTPATH(TestCancelWhileRunning_Session1));
165
166 // Submit two sessions, session 0 should start immediately, session 1 should be queued.
167 EXPECT_TRUE(
168 mClient1->submit(0, srcPath0, dstPath0, TranscodingSessionPriority::kNormal, kBitRate));
169 EXPECT_TRUE(
170 mClient1->submit(1, srcPath1, dstPath1, TranscodingSessionPriority::kNormal, kBitRate));
171 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 0));
172 EXPECT_TRUE(mClient1->getSession(0, srcPath0, dstPath0));
173 EXPECT_TRUE(mClient1->getSession(1, srcPath1, dstPath1));
174
175 // Session 0 (longtest) shouldn't finish in 1 seconds.
176 EXPECT_EQ(mClient1->pop(1000000), EventTracker::NoEvent);
177
178 // Now cancel session 0. Session 1 should start immediately and finish.
179 EXPECT_TRUE(mClient1->cancel(0));
180 EXPECT_TRUE(mClient1->getSession<fail>(0, "", ""));
181 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 1));
182 EXPECT_EQ(mClient1->pop(kSessionWithPaddingUs), EventTracker::Finished(CLIENT(1), 1));
183
184 unregisterMultipleClients();
185 }
186
TEST_F(MediaTranscodingServiceRealTest,TestPauseResumeSingleClient)187 TEST_F(MediaTranscodingServiceRealTest, TestPauseResumeSingleClient) {
188 registerMultipleClients();
189
190 const char* srcPath0 = kLongSrcPath;
191 const char* srcPath1 = kShortSrcPath;
192 const char* dstPath0 = prepareOutputFile(OUTPATH(TestPauseResumeSingleClient_Session0));
193 const char* dstPath1 = prepareOutputFile(OUTPATH(TestPauseResumeSingleClient_Session1));
194
195 // Submit one offline session, should start immediately.
196 EXPECT_TRUE(mClient1->submit(0, srcPath0, dstPath0, TranscodingSessionPriority::kUnspecified,
197 kBitRate));
198 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 0));
199 // Test get session after starts.
200 EXPECT_TRUE(mClient1->getSession(0, srcPath0, dstPath0));
201
202 // Submit one realtime session.
203 EXPECT_TRUE(
204 mClient1->submit(1, srcPath1, dstPath1, TranscodingSessionPriority::kNormal, kBitRate));
205
206 // Offline session should pause.
207 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Pause(CLIENT(1), 0));
208 EXPECT_TRUE(mClient1->getSession(0, srcPath0, dstPath0));
209
210 // Realtime session should start immediately, and run to finish.
211 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 1));
212 EXPECT_EQ(mClient1->pop(kSessionWithPaddingUs), EventTracker::Finished(CLIENT(1), 1));
213
214 // Test get session after finish fails.
215 EXPECT_TRUE(mClient1->getSession<fail>(1, "", ""));
216
217 // Then offline session should resume.
218 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Resume(CLIENT(1), 0));
219 // Test get session after resume.
220 EXPECT_TRUE(mClient1->getSession(0, srcPath0, dstPath0));
221
222 // Offline session should finish.
223 EXPECT_EQ(mClient1->pop(kSessionWithPaddingUs), EventTracker::Finished(CLIENT(1), 0));
224 // Test get session after finish fails.
225 EXPECT_TRUE(mClient1->getSession<fail>(0, "", ""));
226
227 unregisterMultipleClients();
228 }
229
230 /*
231 * Basic test for pause/resume with two clients, with one session each.
232 * Top app's session should preempt the other app's session.
233 */
TEST_F(MediaTranscodingServiceRealTest,TestPauseResumeMultiClients)234 TEST_F(MediaTranscodingServiceRealTest, TestPauseResumeMultiClients) {
235 ALOGD("TestPauseResumeMultiClients starting...");
236
237 dismissKeyguard();
238 stopAppPackages();
239
240 registerMultipleClients();
241
242 const char* srcPath0 = kLongSrcPath;
243 const char* srcPath1 = kShortSrcPath;
244 const char* dstPath0 = prepareOutputFile(OUTPATH(TestPauseResumeMultiClients_Client0));
245 const char* dstPath1 = prepareOutputFile(OUTPATH(TestPauseResumeMultiClients_Client1));
246
247 ALOGD("Moving app A to top...");
248 EXPECT_TRUE(ShellHelper::Start(kClientPackageA, kTestActivityName));
249
250 // Submit session to Client1.
251 ALOGD("Submitting session to client1 (app A) ...");
252 EXPECT_TRUE(
253 mClient1->submit(0, srcPath0, dstPath0, TranscodingSessionPriority::kNormal, kBitRate));
254
255 // Client1's session should start immediately.
256 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 0));
257
258 ALOGD("Moving app B to top...");
259 EXPECT_TRUE(ShellHelper::Start(kClientPackageB, kTestActivityName));
260
261 // Client1's session should continue to run, since Client2 (app B) doesn't have any session.
262 EXPECT_EQ(mClient1->pop(1000000), EventTracker::NoEvent);
263
264 // Submit session to Client2.
265 ALOGD("Submitting session to client2 (app B) ...");
266 EXPECT_TRUE(
267 mClient2->submit(0, srcPath1, dstPath1, TranscodingSessionPriority::kNormal, kBitRate));
268
269 // Client1's session should pause, client2's session should start.
270 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Pause(CLIENT(1), 0));
271 EXPECT_EQ(mClient2->pop(kPaddingUs), EventTracker::Start(CLIENT(2), 0));
272
273 // Client2's session should finish, then Client1's session should resume.
274 EXPECT_EQ(mClient2->pop(kSessionWithPaddingUs), EventTracker::Finished(CLIENT(2), 0));
275 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Resume(CLIENT(1), 0));
276
277 // Client1's session should finish.
278 EXPECT_EQ(mClient1->pop(kSessionWithPaddingUs), EventTracker::Finished(CLIENT(1), 0));
279
280 unregisterMultipleClients();
281
282 stopAppPackages();
283
284 ALOGD("TestPauseResumeMultiClients finished.");
285 }
286
TEST_F(MediaTranscodingServiceRealTest,TestUidGoneForeground)287 TEST_F(MediaTranscodingServiceRealTest, TestUidGoneForeground) {
288 ALOGD("TestUidGoneForeground starting...");
289
290 dismissKeyguard();
291 stopAppPackages();
292
293 registerMultipleClients();
294
295 const char* dstPath0 = prepareOutputFile(OUTPATH(TestUidGoneForegroundSession0));
296 const char* dstPath1 = prepareOutputFile(OUTPATH(TestUidGoneForegroundSession1));
297
298 // Test kill foreground app, using only 1 uid.
299 ALOGD("Moving app A to top...");
300 EXPECT_TRUE(ShellHelper::Start(kClientPackageA, kTestActivityName));
301
302 // Submit sessions to Client1 (app A).
303 ALOGD("Submitting sessions to client1 (app A) ...");
304 EXPECT_TRUE(mClient1->submit(0, kLongSrcPath, dstPath0, TranscodingSessionPriority::kNormal,
305 kBitRate));
306 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 0));
307 EXPECT_TRUE(mClient1->submit(1, kLongSrcPath, dstPath1, TranscodingSessionPriority::kNormal,
308 kBitRate));
309 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::NoEvent);
310
311 // Kill app A, expect to see A's session pause followed by B's session start,
312 // then A's session cancelled with error code kUidGoneCancelled.
313 EXPECT_TRUE(ShellHelper::Stop(kClientPackageA));
314 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Failed(CLIENT(1), 0));
315 EXPECT_EQ(mClient1->getLastError(), TranscodingErrorCode::kUidGoneCancelled);
316 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Failed(CLIENT(1), 1));
317 EXPECT_EQ(mClient1->getLastError(), TranscodingErrorCode::kUidGoneCancelled);
318
319 unregisterMultipleClients();
320
321 stopAppPackages();
322
323 ALOGD("TestUidGoneForeground finished.");
324 }
325
TEST_F(MediaTranscodingServiceRealTest,TestUidGoneForegroundMultiUids)326 TEST_F(MediaTranscodingServiceRealTest, TestUidGoneForegroundMultiUids) {
327 ALOGD("TestUidGoneForegroundMultiUids starting...");
328
329 dismissKeyguard();
330 stopAppPackages();
331
332 registerMultipleClients();
333
334 const char* dstPath0 = prepareOutputFile(OUTPATH(TestUidGoneForegroundSession0));
335 const char* dstPath1 = prepareOutputFile(OUTPATH(TestUidGoneForegroundSession1));
336
337 // Test kill foreground app, using two uids.
338 ALOGD("Moving app B to top...");
339 EXPECT_TRUE(ShellHelper::Start(kClientPackageB, kTestActivityName));
340 EXPECT_TRUE(mClient2->submit(0, kLongSrcPath, dstPath0, TranscodingSessionPriority::kNormal,
341 kBitRate));
342 EXPECT_EQ(mClient2->pop(kPaddingUs), EventTracker::Start(CLIENT(2), 0));
343 EXPECT_TRUE(mClient2->submit(1, kLongSrcPath, dstPath1, TranscodingSessionPriority::kNormal,
344 kBitRate));
345 EXPECT_EQ(mClient2->pop(kPaddingUs), EventTracker::NoEvent);
346 // Make app A also requesting session 1.
347 EXPECT_TRUE(mClient2->addClientUid(1, mClient1->mClientUid));
348
349 ALOGD("Moving app A to top...");
350 EXPECT_TRUE(ShellHelper::Start(kClientPackageA, kTestActivityName));
351 EXPECT_EQ(mClient2->pop(kPaddingUs), EventTracker::Pause(CLIENT(2), 0));
352 EXPECT_EQ(mClient2->pop(kPaddingUs), EventTracker::Start(CLIENT(2), 1));
353
354 // Kill app A, CLIENT(2)'s session 1 should continue because it's also requested by app B.
355 EXPECT_TRUE(ShellHelper::Stop(kClientPackageA));
356 EXPECT_EQ(mClient2->pop(kPaddingUs), EventTracker::NoEvent);
357
358 // Kill app B, sessions should be cancelled.
359 EXPECT_TRUE(ShellHelper::Stop(kClientPackageB));
360 EXPECT_EQ(mClient2->pop(kPaddingUs), EventTracker::Failed(CLIENT(2), 0));
361 EXPECT_EQ(mClient2->getLastError(), TranscodingErrorCode::kUidGoneCancelled);
362 EXPECT_EQ(mClient2->pop(kPaddingUs), EventTracker::Failed(CLIENT(2), 1));
363 EXPECT_EQ(mClient2->getLastError(), TranscodingErrorCode::kUidGoneCancelled);
364
365 unregisterMultipleClients();
366
367 stopAppPackages();
368
369 ALOGD("TestUidGoneForegroundMultiUids finished.");
370 }
TEST_F(MediaTranscodingServiceRealTest,TestUidGoneBackground)371 TEST_F(MediaTranscodingServiceRealTest, TestUidGoneBackground) {
372 ALOGD("TestUidGoneBackground starting...");
373
374 dismissKeyguard();
375 stopAppPackages();
376
377 registerMultipleClients();
378
379 const char* dstPath0 = prepareOutputFile(OUTPATH(TestUidGoneForegroundSession0));
380 const char* dstPath1 = prepareOutputFile(OUTPATH(TestUidGoneForegroundSession1));
381
382 // Test kill background app, using two uids.
383 ALOGD("Moving app B to top...");
384 EXPECT_TRUE(ShellHelper::Start(kClientPackageB, kTestActivityName));
385 EXPECT_TRUE(mClient2->submit(0, kLongSrcPath, dstPath0, TranscodingSessionPriority::kNormal,
386 kBitRate));
387 EXPECT_EQ(mClient2->pop(kPaddingUs), EventTracker::Start(CLIENT(2), 0));
388 EXPECT_TRUE(mClient2->submit(1, kLongSrcPath, dstPath1, TranscodingSessionPriority::kNormal,
389 kBitRate));
390 EXPECT_EQ(mClient2->pop(kPaddingUs), EventTracker::NoEvent);
391
392 ALOGD("Moving app A to top...");
393 EXPECT_TRUE(ShellHelper::Start(kClientPackageA, kTestActivityName));
394 EXPECT_TRUE(mClient1->submit(0, kLongSrcPath, dstPath0, TranscodingSessionPriority::kNormal,
395 kBitRate));
396 EXPECT_EQ(mClient2->pop(kPaddingUs), EventTracker::Pause(CLIENT(2), 0));
397 EXPECT_EQ(mClient1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 0));
398
399 // Kill app B, all its sessions should be cancelled.
400 EXPECT_TRUE(ShellHelper::Stop(kClientPackageB));
401 EXPECT_EQ(mClient2->pop(kPaddingUs), EventTracker::Failed(CLIENT(2), 0));
402 EXPECT_EQ(mClient2->getLastError(), TranscodingErrorCode::kUidGoneCancelled);
403 EXPECT_EQ(mClient2->pop(kPaddingUs), EventTracker::Failed(CLIENT(2), 1));
404 EXPECT_EQ(mClient2->getLastError(), TranscodingErrorCode::kUidGoneCancelled);
405
406 unregisterMultipleClients();
407
408 stopAppPackages();
409
410 ALOGD("TestUidGoneBackground finished.");
411 }
412
TEST_F(MediaTranscodingServiceRealTest,TestUidGoneBackgroundMultiUids)413 TEST_F(MediaTranscodingServiceRealTest, TestUidGoneBackgroundMultiUids) {
414 ALOGD("TestUidGoneBackgroundMultiUids starting...");
415
416 dismissKeyguard();
417 stopAppPackages();
418
419 registerMultipleClients();
420
421 const char* dstPath0 = prepareOutputFile(OUTPATH(TestUidGoneForegroundSession0));
422 const char* dstPath1 = prepareOutputFile(OUTPATH(TestUidGoneForegroundSession1));
423
424 // Test kill background app, using two uids.
425 ALOGD("Moving app B to top...");
426 EXPECT_TRUE(ShellHelper::Start(kClientPackageB, kTestActivityName));
427 EXPECT_TRUE(mClient2->submit(0, kLongSrcPath, dstPath0, TranscodingSessionPriority::kNormal,
428 kBitRate));
429 EXPECT_EQ(mClient2->pop(kPaddingUs), EventTracker::Start(CLIENT(2), 0));
430 EXPECT_TRUE(mClient2->submit(1, kLongSrcPath, dstPath1, TranscodingSessionPriority::kNormal,
431 kBitRate));
432 EXPECT_EQ(mClient2->pop(kPaddingUs), EventTracker::NoEvent);
433 // Make app A also requesting session 1.
434 EXPECT_TRUE(mClient2->addClientUid(1, mClient1->mClientUid));
435
436 ALOGD("Moving app A to top...");
437 EXPECT_TRUE(ShellHelper::Start(kClientPackageA, kTestActivityName));
438 EXPECT_EQ(mClient2->pop(kPaddingUs), EventTracker::Pause(CLIENT(2), 0));
439 EXPECT_EQ(mClient2->pop(kPaddingUs), EventTracker::Start(CLIENT(2), 1));
440
441 // Kill app B, CLIENT(2)'s session 1 should continue to run, session 0 on
442 // the other hand should be cancelled.
443 EXPECT_TRUE(ShellHelper::Stop(kClientPackageB));
444 EXPECT_EQ(mClient2->pop(kPaddingUs), EventTracker::Failed(CLIENT(2), 0));
445 EXPECT_EQ(mClient2->getLastError(), TranscodingErrorCode::kUidGoneCancelled);
446
447 unregisterMultipleClients();
448
449 stopAppPackages();
450
451 ALOGD("TestUidGoneBackgroundMultiUids finished.");
452 }
453
454 } // namespace media
455 } // namespace android
456