1 /*
2 **
3 ** Copyright 2008, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 // Proxy for media player implementations
19 
20 //#define LOG_NDEBUG 0
21 #define LOG_TAG "MediaPlayerService"
22 #include <utils/Log.h>
23 
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <sys/time.h>
27 #include <dirent.h>
28 #include <unistd.h>
29 
30 #include <string.h>
31 
32 #include <cutils/atomic.h>
33 #include <cutils/properties.h> // for property_get
34 
35 #include <utils/misc.h>
36 
37 #include <binder/IPCThreadState.h>
38 #include <binder/IServiceManager.h>
39 #include <binder/MemoryHeapBase.h>
40 #include <binder/MemoryBase.h>
41 #include <gui/Surface.h>
42 #include <utils/Errors.h>  // for status_t
43 #include <utils/String8.h>
44 #include <utils/SystemClock.h>
45 #include <utils/Timers.h>
46 #include <utils/Vector.h>
47 
48 #include <media/AudioPolicyHelper.h>
49 #include <media/IMediaHTTPService.h>
50 #include <media/IRemoteDisplay.h>
51 #include <media/IRemoteDisplayClient.h>
52 #include <media/MediaPlayerInterface.h>
53 #include <media/mediarecorder.h>
54 #include <media/MediaMetadataRetrieverInterface.h>
55 #include <media/Metadata.h>
56 #include <media/AudioTrack.h>
57 #include <media/MemoryLeakTrackUtil.h>
58 #include <media/stagefright/MediaCodecList.h>
59 #include <media/stagefright/MediaErrors.h>
60 #include <media/stagefright/Utils.h>
61 #include <media/stagefright/foundation/ADebug.h>
62 #include <media/stagefright/foundation/ALooperRoster.h>
63 #include <mediautils/BatteryNotifier.h>
64 
65 #include <memunreachable/memunreachable.h>
66 #include <system/audio.h>
67 
68 #include <private/android_filesystem_config.h>
69 
70 #include "ActivityManager.h"
71 #include "MediaRecorderClient.h"
72 #include "MediaPlayerService.h"
73 #include "MetadataRetrieverClient.h"
74 #include "MediaPlayerFactory.h"
75 
76 #include "TestPlayerStub.h"
77 #include "nuplayer/NuPlayerDriver.h"
78 
79 #include <OMX.h>
80 
81 #include "HDCP.h"
82 #include "HTTPBase.h"
83 #include "RemoteDisplay.h"
84 
85 namespace {
86 using android::media::Metadata;
87 using android::status_t;
88 using android::OK;
89 using android::BAD_VALUE;
90 using android::NOT_ENOUGH_DATA;
91 using android::Parcel;
92 
93 // Max number of entries in the filter.
94 const int kMaxFilterSize = 64;  // I pulled that out of thin air.
95 
96 const float kMaxRequiredSpeed = 8.0f; // for PCM tracks allow up to 8x speedup.
97 
98 // FIXME: Move all the metadata related function in the Metadata.cpp
99 
100 
101 // Unmarshall a filter from a Parcel.
102 // Filter format in a parcel:
103 //
104 //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
105 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
106 // |                       number of entries (n)                   |
107 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
108 // |                       metadata type 1                         |
109 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
110 // |                       metadata type 2                         |
111 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
112 //  ....
113 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
114 // |                       metadata type n                         |
115 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
116 //
117 // @param p Parcel that should start with a filter.
118 // @param[out] filter On exit contains the list of metadata type to be
119 //                    filtered.
120 // @param[out] status On exit contains the status code to be returned.
121 // @return true if the parcel starts with a valid filter.
unmarshallFilter(const Parcel & p,Metadata::Filter * filter,status_t * status)122 bool unmarshallFilter(const Parcel& p,
123                       Metadata::Filter *filter,
124                       status_t *status)
125 {
126     int32_t val;
127     if (p.readInt32(&val) != OK)
128     {
129         ALOGE("Failed to read filter's length");
130         *status = NOT_ENOUGH_DATA;
131         return false;
132     }
133 
134     if( val > kMaxFilterSize || val < 0)
135     {
136         ALOGE("Invalid filter len %d", val);
137         *status = BAD_VALUE;
138         return false;
139     }
140 
141     const size_t num = val;
142 
143     filter->clear();
144     filter->setCapacity(num);
145 
146     size_t size = num * sizeof(Metadata::Type);
147 
148 
149     if (p.dataAvail() < size)
150     {
151         ALOGE("Filter too short expected %zu but got %zu", size, p.dataAvail());
152         *status = NOT_ENOUGH_DATA;
153         return false;
154     }
155 
156     const Metadata::Type *data =
157             static_cast<const Metadata::Type*>(p.readInplace(size));
158 
159     if (NULL == data)
160     {
161         ALOGE("Filter had no data");
162         *status = BAD_VALUE;
163         return false;
164     }
165 
166     // TODO: The stl impl of vector would be more efficient here
167     // because it degenerates into a memcpy on pod types. Try to
168     // replace later or use stl::set.
169     for (size_t i = 0; i < num; ++i)
170     {
171         filter->add(*data);
172         ++data;
173     }
174     *status = OK;
175     return true;
176 }
177 
178 // @param filter Of metadata type.
179 // @param val To be searched.
180 // @return true if a match was found.
findMetadata(const Metadata::Filter & filter,const int32_t val)181 bool findMetadata(const Metadata::Filter& filter, const int32_t val)
182 {
183     // Deal with empty and ANY right away
184     if (filter.isEmpty()) return false;
185     if (filter[0] == Metadata::kAny) return true;
186 
187     return filter.indexOf(val) >= 0;
188 }
189 
190 }  // anonymous namespace
191 
192 
193 namespace {
194 using android::Parcel;
195 using android::String16;
196 
197 // marshalling tag indicating flattened utf16 tags
198 // keep in sync with frameworks/base/media/java/android/media/AudioAttributes.java
199 const int32_t kAudioAttributesMarshallTagFlattenTags = 1;
200 
201 // Audio attributes format in a parcel:
202 //
203 //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
204 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
205 // |                       usage                                   |
206 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
207 // |                       content_type                            |
208 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
209 // |                       source                                  |
210 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
211 // |                       flags                                   |
212 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
213 // |                       kAudioAttributesMarshallTagFlattenTags  | // ignore tags if not found
214 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
215 // |                       flattened tags in UTF16                 |
216 // |                         ...                                   |
217 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
218 //
219 // @param p Parcel that contains audio attributes.
220 // @param[out] attributes On exit points to an initialized audio_attributes_t structure
221 // @param[out] status On exit contains the status code to be returned.
unmarshallAudioAttributes(const Parcel & parcel,audio_attributes_t * attributes)222 void unmarshallAudioAttributes(const Parcel& parcel, audio_attributes_t *attributes)
223 {
224     attributes->usage = (audio_usage_t) parcel.readInt32();
225     attributes->content_type = (audio_content_type_t) parcel.readInt32();
226     attributes->source = (audio_source_t) parcel.readInt32();
227     attributes->flags = (audio_flags_mask_t) parcel.readInt32();
228     const bool hasFlattenedTag = (parcel.readInt32() == kAudioAttributesMarshallTagFlattenTags);
229     if (hasFlattenedTag) {
230         // the tags are UTF16, convert to UTF8
231         String16 tags = parcel.readString16();
232         ssize_t realTagSize = utf16_to_utf8_length(tags.string(), tags.size());
233         if (realTagSize <= 0) {
234             strcpy(attributes->tags, "");
235         } else {
236             // copy the flattened string into the attributes as the destination for the conversion:
237             // copying array size -1, array for tags was calloc'd, no need to NULL-terminate it
238             size_t tagSize = realTagSize > AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 ?
239                     AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 : realTagSize;
240             utf16_to_utf8(tags.string(), tagSize, attributes->tags);
241         }
242     } else {
243         ALOGE("unmarshallAudioAttributes() received unflattened tags, ignoring tag values");
244         strcpy(attributes->tags, "");
245     }
246 }
247 } // anonymous namespace
248 
249 
250 namespace android {
251 
252 extern ALooperRoster gLooperRoster;
253 
254 
checkPermission(const char * permissionString)255 static bool checkPermission(const char* permissionString) {
256     if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
257     bool ok = checkCallingPermission(String16(permissionString));
258     if (!ok) ALOGE("Request requires %s", permissionString);
259     return ok;
260 }
261 
262 // TODO: Find real cause of Audio/Video delay in PV framework and remove this workaround
263 /* static */ int MediaPlayerService::AudioOutput::mMinBufferCount = 4;
264 /* static */ bool MediaPlayerService::AudioOutput::mIsOnEmulator = false;
265 
instantiate()266 void MediaPlayerService::instantiate() {
267     defaultServiceManager()->addService(
268             String16("media.player"), new MediaPlayerService());
269 }
270 
MediaPlayerService()271 MediaPlayerService::MediaPlayerService()
272 {
273     ALOGV("MediaPlayerService created");
274     mNextConnId = 1;
275 
276     mBatteryAudio.refCount = 0;
277     for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
278         mBatteryAudio.deviceOn[i] = 0;
279         mBatteryAudio.lastTime[i] = 0;
280         mBatteryAudio.totalTime[i] = 0;
281     }
282     // speaker is on by default
283     mBatteryAudio.deviceOn[SPEAKER] = 1;
284 
285     // reset battery stats
286     // if the mediaserver has crashed, battery stats could be left
287     // in bad state, reset the state upon service start.
288     BatteryNotifier::getInstance().noteResetVideo();
289 
290     MediaPlayerFactory::registerBuiltinFactories();
291 }
292 
~MediaPlayerService()293 MediaPlayerService::~MediaPlayerService()
294 {
295     ALOGV("MediaPlayerService destroyed");
296 }
297 
createMediaRecorder(const String16 & opPackageName)298 sp<IMediaRecorder> MediaPlayerService::createMediaRecorder(const String16 &opPackageName)
299 {
300     pid_t pid = IPCThreadState::self()->getCallingPid();
301     sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid, opPackageName);
302     wp<MediaRecorderClient> w = recorder;
303     Mutex::Autolock lock(mLock);
304     mMediaRecorderClients.add(w);
305     ALOGV("Create new media recorder client from pid %d", pid);
306     return recorder;
307 }
308 
removeMediaRecorderClient(wp<MediaRecorderClient> client)309 void MediaPlayerService::removeMediaRecorderClient(wp<MediaRecorderClient> client)
310 {
311     Mutex::Autolock lock(mLock);
312     mMediaRecorderClients.remove(client);
313     ALOGV("Delete media recorder client");
314 }
315 
createMetadataRetriever()316 sp<IMediaMetadataRetriever> MediaPlayerService::createMetadataRetriever()
317 {
318     pid_t pid = IPCThreadState::self()->getCallingPid();
319     sp<MetadataRetrieverClient> retriever = new MetadataRetrieverClient(pid);
320     ALOGV("Create new media retriever from pid %d", pid);
321     return retriever;
322 }
323 
create(const sp<IMediaPlayerClient> & client,audio_session_t audioSessionId)324 sp<IMediaPlayer> MediaPlayerService::create(const sp<IMediaPlayerClient>& client,
325         audio_session_t audioSessionId)
326 {
327     pid_t pid = IPCThreadState::self()->getCallingPid();
328     int32_t connId = android_atomic_inc(&mNextConnId);
329 
330     sp<Client> c = new Client(
331             this, pid, connId, client, audioSessionId,
332             IPCThreadState::self()->getCallingUid());
333 
334     ALOGV("Create new client(%d) from pid %d, uid %d, ", connId, pid,
335          IPCThreadState::self()->getCallingUid());
336 
337     wp<Client> w = c;
338     {
339         Mutex::Autolock lock(mLock);
340         mClients.add(w);
341     }
342     return c;
343 }
344 
getCodecList() const345 sp<IMediaCodecList> MediaPlayerService::getCodecList() const {
346     return MediaCodecList::getLocalInstance();
347 }
348 
getOMX()349 sp<IOMX> MediaPlayerService::getOMX() {
350     ALOGI("MediaPlayerService::getOMX");
351     Mutex::Autolock autoLock(mLock);
352 
353     if (mOMX.get() == NULL) {
354         mOMX = new OMX;
355     }
356 
357     return mOMX;
358 }
359 
makeHDCP(bool createEncryptionModule)360 sp<IHDCP> MediaPlayerService::makeHDCP(bool createEncryptionModule) {
361     return new HDCP(createEncryptionModule);
362 }
363 
listenForRemoteDisplay(const String16 & opPackageName,const sp<IRemoteDisplayClient> & client,const String8 & iface)364 sp<IRemoteDisplay> MediaPlayerService::listenForRemoteDisplay(
365         const String16 &opPackageName,
366         const sp<IRemoteDisplayClient>& client, const String8& iface) {
367     if (!checkPermission("android.permission.CONTROL_WIFI_DISPLAY")) {
368         return NULL;
369     }
370 
371     return new RemoteDisplay(opPackageName, client, iface.string());
372 }
373 
dump(int fd,const Vector<String16> & args) const374 status_t MediaPlayerService::AudioOutput::dump(int fd, const Vector<String16>& args) const
375 {
376     const size_t SIZE = 256;
377     char buffer[SIZE];
378     String8 result;
379 
380     result.append(" AudioOutput\n");
381     snprintf(buffer, 255, "  stream type(%d), left - right volume(%f, %f)\n",
382             mStreamType, mLeftVolume, mRightVolume);
383     result.append(buffer);
384     snprintf(buffer, 255, "  msec per frame(%f), latency (%d)\n",
385             mMsecsPerFrame, (mTrack != 0) ? mTrack->latency() : -1);
386     result.append(buffer);
387     snprintf(buffer, 255, "  aux effect id(%d), send level (%f)\n",
388             mAuxEffectId, mSendLevel);
389     result.append(buffer);
390 
391     ::write(fd, result.string(), result.size());
392     if (mTrack != 0) {
393         mTrack->dump(fd, args);
394     }
395     return NO_ERROR;
396 }
397 
dump(int fd,const Vector<String16> & args)398 status_t MediaPlayerService::Client::dump(int fd, const Vector<String16>& args)
399 {
400     const size_t SIZE = 256;
401     char buffer[SIZE];
402     String8 result;
403     result.append(" Client\n");
404     snprintf(buffer, 255, "  pid(%d), connId(%d), status(%d), looping(%s)\n",
405             mPid, mConnId, mStatus, mLoop?"true": "false");
406     result.append(buffer);
407     write(fd, result.string(), result.size());
408     if (mPlayer != NULL) {
409         mPlayer->dump(fd, args);
410     }
411     if (mAudioOutput != 0) {
412         mAudioOutput->dump(fd, args);
413     }
414     write(fd, "\n", 1);
415     return NO_ERROR;
416 }
417 
418 /**
419  * The only arguments this understands right now are -c, -von and -voff,
420  * which are parsed by ALooperRoster::dump()
421  */
dump(int fd,const Vector<String16> & args)422 status_t MediaPlayerService::dump(int fd, const Vector<String16>& args)
423 {
424     const size_t SIZE = 256;
425     char buffer[SIZE];
426     String8 result;
427     SortedVector< sp<Client> > clients; //to serialise the mutex unlock & client destruction.
428     SortedVector< sp<MediaRecorderClient> > mediaRecorderClients;
429 
430     if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
431         snprintf(buffer, SIZE, "Permission Denial: "
432                 "can't dump MediaPlayerService from pid=%d, uid=%d\n",
433                 IPCThreadState::self()->getCallingPid(),
434                 IPCThreadState::self()->getCallingUid());
435         result.append(buffer);
436     } else {
437         Mutex::Autolock lock(mLock);
438         for (int i = 0, n = mClients.size(); i < n; ++i) {
439             sp<Client> c = mClients[i].promote();
440             if (c != 0) c->dump(fd, args);
441             clients.add(c);
442         }
443         if (mMediaRecorderClients.size() == 0) {
444                 result.append(" No media recorder client\n\n");
445         } else {
446             for (int i = 0, n = mMediaRecorderClients.size(); i < n; ++i) {
447                 sp<MediaRecorderClient> c = mMediaRecorderClients[i].promote();
448                 if (c != 0) {
449                     snprintf(buffer, 255, " MediaRecorderClient pid(%d)\n", c->mPid);
450                     result.append(buffer);
451                     write(fd, result.string(), result.size());
452                     result = "\n";
453                     c->dump(fd, args);
454                     mediaRecorderClients.add(c);
455                 }
456             }
457         }
458 
459         result.append(" Files opened and/or mapped:\n");
460         snprintf(buffer, SIZE, "/proc/%d/maps", getpid());
461         FILE *f = fopen(buffer, "r");
462         if (f) {
463             while (!feof(f)) {
464                 fgets(buffer, SIZE, f);
465                 if (strstr(buffer, " /storage/") ||
466                     strstr(buffer, " /system/sounds/") ||
467                     strstr(buffer, " /data/") ||
468                     strstr(buffer, " /system/media/")) {
469                     result.append("  ");
470                     result.append(buffer);
471                 }
472             }
473             fclose(f);
474         } else {
475             result.append("couldn't open ");
476             result.append(buffer);
477             result.append("\n");
478         }
479 
480         snprintf(buffer, SIZE, "/proc/%d/fd", getpid());
481         DIR *d = opendir(buffer);
482         if (d) {
483             struct dirent *ent;
484             while((ent = readdir(d)) != NULL) {
485                 if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) {
486                     snprintf(buffer, SIZE, "/proc/%d/fd/%s", getpid(), ent->d_name);
487                     struct stat s;
488                     if (lstat(buffer, &s) == 0) {
489                         if ((s.st_mode & S_IFMT) == S_IFLNK) {
490                             char linkto[256];
491                             int len = readlink(buffer, linkto, sizeof(linkto));
492                             if(len > 0) {
493                                 if(len > 255) {
494                                     linkto[252] = '.';
495                                     linkto[253] = '.';
496                                     linkto[254] = '.';
497                                     linkto[255] = 0;
498                                 } else {
499                                     linkto[len] = 0;
500                                 }
501                                 if (strstr(linkto, "/storage/") == linkto ||
502                                     strstr(linkto, "/system/sounds/") == linkto ||
503                                     strstr(linkto, "/data/") == linkto ||
504                                     strstr(linkto, "/system/media/") == linkto) {
505                                     result.append("  ");
506                                     result.append(buffer);
507                                     result.append(" -> ");
508                                     result.append(linkto);
509                                     result.append("\n");
510                                 }
511                             }
512                         } else {
513                             result.append("  unexpected type for ");
514                             result.append(buffer);
515                             result.append("\n");
516                         }
517                     }
518                 }
519             }
520             closedir(d);
521         } else {
522             result.append("couldn't open ");
523             result.append(buffer);
524             result.append("\n");
525         }
526 
527         gLooperRoster.dump(fd, args);
528 
529         bool dumpMem = false;
530         bool unreachableMemory = false;
531         for (size_t i = 0; i < args.size(); i++) {
532             if (args[i] == String16("-m")) {
533                 dumpMem = true;
534             } else if (args[i] == String16("--unreachable")) {
535                 unreachableMemory = true;
536             }
537         }
538         if (dumpMem) {
539             result.append("\nDumping memory:\n");
540             std::string s = dumpMemoryAddresses(100 /* limit */);
541             result.append(s.c_str(), s.size());
542         }
543         if (unreachableMemory) {
544             result.append("\nDumping unreachable memory:\n");
545             // TODO - should limit be an argument parameter?
546             std::string s = GetUnreachableMemoryString(true /* contents */, 10000 /* limit */);
547             result.append(s.c_str(), s.size());
548         }
549     }
550     write(fd, result.string(), result.size());
551     return NO_ERROR;
552 }
553 
removeClient(wp<Client> client)554 void MediaPlayerService::removeClient(wp<Client> client)
555 {
556     Mutex::Autolock lock(mLock);
557     mClients.remove(client);
558 }
559 
Client(const sp<MediaPlayerService> & service,pid_t pid,int32_t connId,const sp<IMediaPlayerClient> & client,audio_session_t audioSessionId,uid_t uid)560 MediaPlayerService::Client::Client(
561         const sp<MediaPlayerService>& service, pid_t pid,
562         int32_t connId, const sp<IMediaPlayerClient>& client,
563         audio_session_t audioSessionId, uid_t uid)
564 {
565     ALOGV("Client(%d) constructor", connId);
566     mPid = pid;
567     mConnId = connId;
568     mService = service;
569     mClient = client;
570     mLoop = false;
571     mStatus = NO_INIT;
572     mAudioSessionId = audioSessionId;
573     mUID = uid;
574     mRetransmitEndpointValid = false;
575     mAudioAttributes = NULL;
576 
577 #if CALLBACK_ANTAGONIZER
578     ALOGD("create Antagonizer");
579     mAntagonizer = new Antagonizer(notify, this);
580 #endif
581 }
582 
~Client()583 MediaPlayerService::Client::~Client()
584 {
585     ALOGV("Client(%d) destructor pid = %d", mConnId, mPid);
586     mAudioOutput.clear();
587     wp<Client> client(this);
588     disconnect();
589     mService->removeClient(client);
590     if (mAudioAttributes != NULL) {
591         free(mAudioAttributes);
592     }
593 }
594 
disconnect()595 void MediaPlayerService::Client::disconnect()
596 {
597     ALOGV("disconnect(%d) from pid %d", mConnId, mPid);
598     // grab local reference and clear main reference to prevent future
599     // access to object
600     sp<MediaPlayerBase> p;
601     {
602         Mutex::Autolock l(mLock);
603         p = mPlayer;
604         mClient.clear();
605     }
606 
607     mPlayer.clear();
608 
609     // clear the notification to prevent callbacks to dead client
610     // and reset the player. We assume the player will serialize
611     // access to itself if necessary.
612     if (p != 0) {
613         p->setNotifyCallback(0, 0);
614 #if CALLBACK_ANTAGONIZER
615         ALOGD("kill Antagonizer");
616         mAntagonizer->kill();
617 #endif
618         p->reset();
619     }
620 
621     disconnectNativeWindow();
622 
623     IPCThreadState::self()->flushCommands();
624 }
625 
createPlayer(player_type playerType)626 sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)
627 {
628     // determine if we have the right player type
629     sp<MediaPlayerBase> p = mPlayer;
630     if ((p != NULL) && (p->playerType() != playerType)) {
631         ALOGV("delete player");
632         p.clear();
633     }
634     if (p == NULL) {
635         p = MediaPlayerFactory::createPlayer(playerType, this, notify, mPid);
636     }
637 
638     if (p != NULL) {
639         p->setUID(mUID);
640     }
641 
642     return p;
643 }
644 
ServiceDeathNotifier(const sp<IBinder> & service,const sp<MediaPlayerBase> & listener,int which)645 MediaPlayerService::Client::ServiceDeathNotifier::ServiceDeathNotifier(
646         const sp<IBinder>& service,
647         const sp<MediaPlayerBase>& listener,
648         int which) {
649     mService = service;
650     mListener = listener;
651     mWhich = which;
652 }
653 
~ServiceDeathNotifier()654 MediaPlayerService::Client::ServiceDeathNotifier::~ServiceDeathNotifier() {
655     mService->unlinkToDeath(this);
656 }
657 
binderDied(const wp<IBinder> &)658 void MediaPlayerService::Client::ServiceDeathNotifier::binderDied(const wp<IBinder>& /*who*/) {
659     sp<MediaPlayerBase> listener = mListener.promote();
660     if (listener != NULL) {
661         listener->sendEvent(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
662     } else {
663         ALOGW("listener for process %d death is gone", mWhich);
664     }
665 }
666 
setDataSource_pre(player_type playerType)667 sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(
668         player_type playerType)
669 {
670     ALOGV("player type = %d", playerType);
671 
672     // create the right type of player
673     sp<MediaPlayerBase> p = createPlayer(playerType);
674     if (p == NULL) {
675         return p;
676     }
677 
678     sp<IServiceManager> sm = defaultServiceManager();
679     sp<IBinder> binder = sm->getService(String16("media.extractor"));
680     mExtractorDeathListener = new ServiceDeathNotifier(binder, p, MEDIAEXTRACTOR_PROCESS_DEATH);
681     binder->linkToDeath(mExtractorDeathListener);
682 
683     binder = sm->getService(String16("media.codec"));
684     mCodecDeathListener = new ServiceDeathNotifier(binder, p, MEDIACODEC_PROCESS_DEATH);
685     binder->linkToDeath(mCodecDeathListener);
686 
687     if (!p->hardwareOutput()) {
688         Mutex::Autolock l(mLock);
689         mAudioOutput = new AudioOutput(mAudioSessionId, IPCThreadState::self()->getCallingUid(),
690                 mPid, mAudioAttributes);
691         static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
692     }
693 
694     return p;
695 }
696 
setDataSource_post(const sp<MediaPlayerBase> & p,status_t status)697 void MediaPlayerService::Client::setDataSource_post(
698         const sp<MediaPlayerBase>& p,
699         status_t status)
700 {
701     ALOGV(" setDataSource");
702     mStatus = status;
703     if (mStatus != OK) {
704         ALOGE("  error: %d", mStatus);
705         return;
706     }
707 
708     // Set the re-transmission endpoint if one was chosen.
709     if (mRetransmitEndpointValid) {
710         mStatus = p->setRetransmitEndpoint(&mRetransmitEndpoint);
711         if (mStatus != NO_ERROR) {
712             ALOGE("setRetransmitEndpoint error: %d", mStatus);
713         }
714     }
715 
716     if (mStatus == OK) {
717         mPlayer = p;
718     }
719 }
720 
setDataSource(const sp<IMediaHTTPService> & httpService,const char * url,const KeyedVector<String8,String8> * headers)721 status_t MediaPlayerService::Client::setDataSource(
722         const sp<IMediaHTTPService> &httpService,
723         const char *url,
724         const KeyedVector<String8, String8> *headers)
725 {
726     ALOGV("setDataSource(%s)", url);
727     if (url == NULL)
728         return UNKNOWN_ERROR;
729 
730     if ((strncmp(url, "http://", 7) == 0) ||
731         (strncmp(url, "https://", 8) == 0) ||
732         (strncmp(url, "rtsp://", 7) == 0)) {
733         if (!checkPermission("android.permission.INTERNET")) {
734             return PERMISSION_DENIED;
735         }
736     }
737 
738     if (strncmp(url, "content://", 10) == 0) {
739         // get a filedescriptor for the content Uri and
740         // pass it to the setDataSource(fd) method
741 
742         String16 url16(url);
743         int fd = android::openContentProviderFile(url16);
744         if (fd < 0)
745         {
746             ALOGE("Couldn't open fd for %s", url);
747             return UNKNOWN_ERROR;
748         }
749         setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus
750         close(fd);
751         return mStatus;
752     } else {
753         player_type playerType = MediaPlayerFactory::getPlayerType(this, url);
754         sp<MediaPlayerBase> p = setDataSource_pre(playerType);
755         if (p == NULL) {
756             return NO_INIT;
757         }
758 
759         setDataSource_post(p, p->setDataSource(httpService, url, headers));
760         return mStatus;
761     }
762 }
763 
setDataSource(int fd,int64_t offset,int64_t length)764 status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)
765 {
766     ALOGV("setDataSource fd=%d (%s), offset=%lld, length=%lld",
767             fd, nameForFd(fd).c_str(), (long long) offset, (long long) length);
768     struct stat sb;
769     int ret = fstat(fd, &sb);
770     if (ret != 0) {
771         ALOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno));
772         return UNKNOWN_ERROR;
773     }
774 
775     ALOGV("st_dev  = %llu", static_cast<unsigned long long>(sb.st_dev));
776     ALOGV("st_mode = %u", sb.st_mode);
777     ALOGV("st_uid  = %lu", static_cast<unsigned long>(sb.st_uid));
778     ALOGV("st_gid  = %lu", static_cast<unsigned long>(sb.st_gid));
779     ALOGV("st_size = %llu", static_cast<unsigned long long>(sb.st_size));
780 
781     if (offset >= sb.st_size) {
782         ALOGE("offset error");
783         return UNKNOWN_ERROR;
784     }
785     if (offset + length > sb.st_size) {
786         length = sb.st_size - offset;
787         ALOGV("calculated length = %lld", (long long)length);
788     }
789 
790     player_type playerType = MediaPlayerFactory::getPlayerType(this,
791                                                                fd,
792                                                                offset,
793                                                                length);
794     sp<MediaPlayerBase> p = setDataSource_pre(playerType);
795     if (p == NULL) {
796         return NO_INIT;
797     }
798 
799     // now set data source
800     setDataSource_post(p, p->setDataSource(fd, offset, length));
801     return mStatus;
802 }
803 
setDataSource(const sp<IStreamSource> & source)804 status_t MediaPlayerService::Client::setDataSource(
805         const sp<IStreamSource> &source) {
806     // create the right type of player
807     player_type playerType = MediaPlayerFactory::getPlayerType(this, source);
808     sp<MediaPlayerBase> p = setDataSource_pre(playerType);
809     if (p == NULL) {
810         return NO_INIT;
811     }
812 
813     // now set data source
814     setDataSource_post(p, p->setDataSource(source));
815     return mStatus;
816 }
817 
setDataSource(const sp<IDataSource> & source)818 status_t MediaPlayerService::Client::setDataSource(
819         const sp<IDataSource> &source) {
820     sp<DataSource> dataSource = DataSource::CreateFromIDataSource(source);
821     player_type playerType = MediaPlayerFactory::getPlayerType(this, dataSource);
822     sp<MediaPlayerBase> p = setDataSource_pre(playerType);
823     if (p == NULL) {
824         return NO_INIT;
825     }
826     // now set data source
827     setDataSource_post(p, p->setDataSource(dataSource));
828     return mStatus;
829 }
830 
disconnectNativeWindow()831 void MediaPlayerService::Client::disconnectNativeWindow() {
832     if (mConnectedWindow != NULL) {
833         status_t err = native_window_api_disconnect(mConnectedWindow.get(),
834                 NATIVE_WINDOW_API_MEDIA);
835 
836         if (err != OK) {
837             ALOGW("native_window_api_disconnect returned an error: %s (%d)",
838                     strerror(-err), err);
839         }
840     }
841     mConnectedWindow.clear();
842 }
843 
setVideoSurfaceTexture(const sp<IGraphicBufferProducer> & bufferProducer)844 status_t MediaPlayerService::Client::setVideoSurfaceTexture(
845         const sp<IGraphicBufferProducer>& bufferProducer)
846 {
847     ALOGV("[%d] setVideoSurfaceTexture(%p)", mConnId, bufferProducer.get());
848     sp<MediaPlayerBase> p = getPlayer();
849     if (p == 0) return UNKNOWN_ERROR;
850 
851     sp<IBinder> binder(IInterface::asBinder(bufferProducer));
852     if (mConnectedWindowBinder == binder) {
853         return OK;
854     }
855 
856     sp<ANativeWindow> anw;
857     if (bufferProducer != NULL) {
858         anw = new Surface(bufferProducer, true /* controlledByApp */);
859         status_t err = native_window_api_connect(anw.get(),
860                 NATIVE_WINDOW_API_MEDIA);
861 
862         if (err != OK) {
863             ALOGE("setVideoSurfaceTexture failed: %d", err);
864             // Note that we must do the reset before disconnecting from the ANW.
865             // Otherwise queue/dequeue calls could be made on the disconnected
866             // ANW, which may result in errors.
867             reset();
868 
869             disconnectNativeWindow();
870 
871             return err;
872         }
873     }
874 
875     // Note that we must set the player's new GraphicBufferProducer before
876     // disconnecting the old one.  Otherwise queue/dequeue calls could be made
877     // on the disconnected ANW, which may result in errors.
878     status_t err = p->setVideoSurfaceTexture(bufferProducer);
879 
880     disconnectNativeWindow();
881 
882     mConnectedWindow = anw;
883 
884     if (err == OK) {
885         mConnectedWindowBinder = binder;
886     } else {
887         disconnectNativeWindow();
888     }
889 
890     return err;
891 }
892 
invoke(const Parcel & request,Parcel * reply)893 status_t MediaPlayerService::Client::invoke(const Parcel& request,
894                                             Parcel *reply)
895 {
896     sp<MediaPlayerBase> p = getPlayer();
897     if (p == NULL) return UNKNOWN_ERROR;
898     return p->invoke(request, reply);
899 }
900 
901 // This call doesn't need to access the native player.
setMetadataFilter(const Parcel & filter)902 status_t MediaPlayerService::Client::setMetadataFilter(const Parcel& filter)
903 {
904     status_t status;
905     media::Metadata::Filter allow, drop;
906 
907     if (unmarshallFilter(filter, &allow, &status) &&
908         unmarshallFilter(filter, &drop, &status)) {
909         Mutex::Autolock lock(mLock);
910 
911         mMetadataAllow = allow;
912         mMetadataDrop = drop;
913     }
914     return status;
915 }
916 
getMetadata(bool update_only,bool,Parcel * reply)917 status_t MediaPlayerService::Client::getMetadata(
918         bool update_only, bool /*apply_filter*/, Parcel *reply)
919 {
920     sp<MediaPlayerBase> player = getPlayer();
921     if (player == 0) return UNKNOWN_ERROR;
922 
923     status_t status;
924     // Placeholder for the return code, updated by the caller.
925     reply->writeInt32(-1);
926 
927     media::Metadata::Filter ids;
928 
929     // We don't block notifications while we fetch the data. We clear
930     // mMetadataUpdated first so we don't lose notifications happening
931     // during the rest of this call.
932     {
933         Mutex::Autolock lock(mLock);
934         if (update_only) {
935             ids = mMetadataUpdated;
936         }
937         mMetadataUpdated.clear();
938     }
939 
940     media::Metadata metadata(reply);
941 
942     metadata.appendHeader();
943     status = player->getMetadata(ids, reply);
944 
945     if (status != OK) {
946         metadata.resetParcel();
947         ALOGE("getMetadata failed %d", status);
948         return status;
949     }
950 
951     // FIXME: Implement filtering on the result. Not critical since
952     // filtering takes place on the update notifications already. This
953     // would be when all the metadata are fetch and a filter is set.
954 
955     // Everything is fine, update the metadata length.
956     metadata.updateLength();
957     return OK;
958 }
959 
prepareAsync()960 status_t MediaPlayerService::Client::prepareAsync()
961 {
962     ALOGV("[%d] prepareAsync", mConnId);
963     sp<MediaPlayerBase> p = getPlayer();
964     if (p == 0) return UNKNOWN_ERROR;
965     status_t ret = p->prepareAsync();
966 #if CALLBACK_ANTAGONIZER
967     ALOGD("start Antagonizer");
968     if (ret == NO_ERROR) mAntagonizer->start();
969 #endif
970     return ret;
971 }
972 
start()973 status_t MediaPlayerService::Client::start()
974 {
975     ALOGV("[%d] start", mConnId);
976     sp<MediaPlayerBase> p = getPlayer();
977     if (p == 0) return UNKNOWN_ERROR;
978     p->setLooping(mLoop);
979     return p->start();
980 }
981 
stop()982 status_t MediaPlayerService::Client::stop()
983 {
984     ALOGV("[%d] stop", mConnId);
985     sp<MediaPlayerBase> p = getPlayer();
986     if (p == 0) return UNKNOWN_ERROR;
987     return p->stop();
988 }
989 
pause()990 status_t MediaPlayerService::Client::pause()
991 {
992     ALOGV("[%d] pause", mConnId);
993     sp<MediaPlayerBase> p = getPlayer();
994     if (p == 0) return UNKNOWN_ERROR;
995     return p->pause();
996 }
997 
isPlaying(bool * state)998 status_t MediaPlayerService::Client::isPlaying(bool* state)
999 {
1000     *state = false;
1001     sp<MediaPlayerBase> p = getPlayer();
1002     if (p == 0) return UNKNOWN_ERROR;
1003     *state = p->isPlaying();
1004     ALOGV("[%d] isPlaying: %d", mConnId, *state);
1005     return NO_ERROR;
1006 }
1007 
setPlaybackSettings(const AudioPlaybackRate & rate)1008 status_t MediaPlayerService::Client::setPlaybackSettings(const AudioPlaybackRate& rate)
1009 {
1010     ALOGV("[%d] setPlaybackSettings(%f, %f, %d, %d)",
1011             mConnId, rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode);
1012     sp<MediaPlayerBase> p = getPlayer();
1013     if (p == 0) return UNKNOWN_ERROR;
1014     return p->setPlaybackSettings(rate);
1015 }
1016 
getPlaybackSettings(AudioPlaybackRate * rate)1017 status_t MediaPlayerService::Client::getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */)
1018 {
1019     sp<MediaPlayerBase> p = getPlayer();
1020     if (p == 0) return UNKNOWN_ERROR;
1021     status_t ret = p->getPlaybackSettings(rate);
1022     if (ret == NO_ERROR) {
1023         ALOGV("[%d] getPlaybackSettings(%f, %f, %d, %d)",
1024                 mConnId, rate->mSpeed, rate->mPitch, rate->mFallbackMode, rate->mStretchMode);
1025     } else {
1026         ALOGV("[%d] getPlaybackSettings returned %d", mConnId, ret);
1027     }
1028     return ret;
1029 }
1030 
setSyncSettings(const AVSyncSettings & sync,float videoFpsHint)1031 status_t MediaPlayerService::Client::setSyncSettings(
1032         const AVSyncSettings& sync, float videoFpsHint)
1033 {
1034     ALOGV("[%d] setSyncSettings(%u, %u, %f, %f)",
1035             mConnId, sync.mSource, sync.mAudioAdjustMode, sync.mTolerance, videoFpsHint);
1036     sp<MediaPlayerBase> p = getPlayer();
1037     if (p == 0) return UNKNOWN_ERROR;
1038     return p->setSyncSettings(sync, videoFpsHint);
1039 }
1040 
getSyncSettings(AVSyncSettings * sync,float * videoFps)1041 status_t MediaPlayerService::Client::getSyncSettings(
1042         AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */)
1043 {
1044     sp<MediaPlayerBase> p = getPlayer();
1045     if (p == 0) return UNKNOWN_ERROR;
1046     status_t ret = p->getSyncSettings(sync, videoFps);
1047     if (ret == NO_ERROR) {
1048         ALOGV("[%d] getSyncSettings(%u, %u, %f, %f)",
1049                 mConnId, sync->mSource, sync->mAudioAdjustMode, sync->mTolerance, *videoFps);
1050     } else {
1051         ALOGV("[%d] getSyncSettings returned %d", mConnId, ret);
1052     }
1053     return ret;
1054 }
1055 
getCurrentPosition(int * msec)1056 status_t MediaPlayerService::Client::getCurrentPosition(int *msec)
1057 {
1058     ALOGV("getCurrentPosition");
1059     sp<MediaPlayerBase> p = getPlayer();
1060     if (p == 0) return UNKNOWN_ERROR;
1061     status_t ret = p->getCurrentPosition(msec);
1062     if (ret == NO_ERROR) {
1063         ALOGV("[%d] getCurrentPosition = %d", mConnId, *msec);
1064     } else {
1065         ALOGE("getCurrentPosition returned %d", ret);
1066     }
1067     return ret;
1068 }
1069 
getDuration(int * msec)1070 status_t MediaPlayerService::Client::getDuration(int *msec)
1071 {
1072     ALOGV("getDuration");
1073     sp<MediaPlayerBase> p = getPlayer();
1074     if (p == 0) return UNKNOWN_ERROR;
1075     status_t ret = p->getDuration(msec);
1076     if (ret == NO_ERROR) {
1077         ALOGV("[%d] getDuration = %d", mConnId, *msec);
1078     } else {
1079         ALOGE("getDuration returned %d", ret);
1080     }
1081     return ret;
1082 }
1083 
setNextPlayer(const sp<IMediaPlayer> & player)1084 status_t MediaPlayerService::Client::setNextPlayer(const sp<IMediaPlayer>& player) {
1085     ALOGV("setNextPlayer");
1086     Mutex::Autolock l(mLock);
1087     sp<Client> c = static_cast<Client*>(player.get());
1088     mNextClient = c;
1089 
1090     if (c != NULL) {
1091         if (mAudioOutput != NULL) {
1092             mAudioOutput->setNextOutput(c->mAudioOutput);
1093         } else if ((mPlayer != NULL) && !mPlayer->hardwareOutput()) {
1094             ALOGE("no current audio output");
1095         }
1096 
1097         if ((mPlayer != NULL) && (mNextClient->getPlayer() != NULL)) {
1098             mPlayer->setNextPlayer(mNextClient->getPlayer());
1099         }
1100     }
1101 
1102     return OK;
1103 }
1104 
seekTo(int msec)1105 status_t MediaPlayerService::Client::seekTo(int msec)
1106 {
1107     ALOGV("[%d] seekTo(%d)", mConnId, msec);
1108     sp<MediaPlayerBase> p = getPlayer();
1109     if (p == 0) return UNKNOWN_ERROR;
1110     return p->seekTo(msec);
1111 }
1112 
reset()1113 status_t MediaPlayerService::Client::reset()
1114 {
1115     ALOGV("[%d] reset", mConnId);
1116     mRetransmitEndpointValid = false;
1117     sp<MediaPlayerBase> p = getPlayer();
1118     if (p == 0) return UNKNOWN_ERROR;
1119     return p->reset();
1120 }
1121 
setAudioStreamType(audio_stream_type_t type)1122 status_t MediaPlayerService::Client::setAudioStreamType(audio_stream_type_t type)
1123 {
1124     ALOGV("[%d] setAudioStreamType(%d)", mConnId, type);
1125     // TODO: for hardware output, call player instead
1126     Mutex::Autolock l(mLock);
1127     if (mAudioOutput != 0) mAudioOutput->setAudioStreamType(type);
1128     return NO_ERROR;
1129 }
1130 
setAudioAttributes_l(const Parcel & parcel)1131 status_t MediaPlayerService::Client::setAudioAttributes_l(const Parcel &parcel)
1132 {
1133     if (mAudioAttributes != NULL) { free(mAudioAttributes); }
1134     mAudioAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
1135     if (mAudioAttributes == NULL) {
1136         return NO_MEMORY;
1137     }
1138     unmarshallAudioAttributes(parcel, mAudioAttributes);
1139 
1140     ALOGV("setAudioAttributes_l() usage=%d content=%d flags=0x%x tags=%s",
1141             mAudioAttributes->usage, mAudioAttributes->content_type, mAudioAttributes->flags,
1142             mAudioAttributes->tags);
1143 
1144     if (mAudioOutput != 0) {
1145         mAudioOutput->setAudioAttributes(mAudioAttributes);
1146     }
1147     return NO_ERROR;
1148 }
1149 
setLooping(int loop)1150 status_t MediaPlayerService::Client::setLooping(int loop)
1151 {
1152     ALOGV("[%d] setLooping(%d)", mConnId, loop);
1153     mLoop = loop;
1154     sp<MediaPlayerBase> p = getPlayer();
1155     if (p != 0) return p->setLooping(loop);
1156     return NO_ERROR;
1157 }
1158 
setVolume(float leftVolume,float rightVolume)1159 status_t MediaPlayerService::Client::setVolume(float leftVolume, float rightVolume)
1160 {
1161     ALOGV("[%d] setVolume(%f, %f)", mConnId, leftVolume, rightVolume);
1162 
1163     // for hardware output, call player instead
1164     sp<MediaPlayerBase> p = getPlayer();
1165     {
1166       Mutex::Autolock l(mLock);
1167       if (p != 0 && p->hardwareOutput()) {
1168           MediaPlayerHWInterface* hwp =
1169                   reinterpret_cast<MediaPlayerHWInterface*>(p.get());
1170           return hwp->setVolume(leftVolume, rightVolume);
1171       } else {
1172           if (mAudioOutput != 0) mAudioOutput->setVolume(leftVolume, rightVolume);
1173           return NO_ERROR;
1174       }
1175     }
1176 
1177     return NO_ERROR;
1178 }
1179 
setAuxEffectSendLevel(float level)1180 status_t MediaPlayerService::Client::setAuxEffectSendLevel(float level)
1181 {
1182     ALOGV("[%d] setAuxEffectSendLevel(%f)", mConnId, level);
1183     Mutex::Autolock l(mLock);
1184     if (mAudioOutput != 0) return mAudioOutput->setAuxEffectSendLevel(level);
1185     return NO_ERROR;
1186 }
1187 
attachAuxEffect(int effectId)1188 status_t MediaPlayerService::Client::attachAuxEffect(int effectId)
1189 {
1190     ALOGV("[%d] attachAuxEffect(%d)", mConnId, effectId);
1191     Mutex::Autolock l(mLock);
1192     if (mAudioOutput != 0) return mAudioOutput->attachAuxEffect(effectId);
1193     return NO_ERROR;
1194 }
1195 
setParameter(int key,const Parcel & request)1196 status_t MediaPlayerService::Client::setParameter(int key, const Parcel &request) {
1197     ALOGV("[%d] setParameter(%d)", mConnId, key);
1198     switch (key) {
1199     case KEY_PARAMETER_AUDIO_ATTRIBUTES:
1200     {
1201         Mutex::Autolock l(mLock);
1202         return setAudioAttributes_l(request);
1203     }
1204     default:
1205         sp<MediaPlayerBase> p = getPlayer();
1206         if (p == 0) { return UNKNOWN_ERROR; }
1207         return p->setParameter(key, request);
1208     }
1209 }
1210 
getParameter(int key,Parcel * reply)1211 status_t MediaPlayerService::Client::getParameter(int key, Parcel *reply) {
1212     ALOGV("[%d] getParameter(%d)", mConnId, key);
1213     sp<MediaPlayerBase> p = getPlayer();
1214     if (p == 0) return UNKNOWN_ERROR;
1215     return p->getParameter(key, reply);
1216 }
1217 
setRetransmitEndpoint(const struct sockaddr_in * endpoint)1218 status_t MediaPlayerService::Client::setRetransmitEndpoint(
1219         const struct sockaddr_in* endpoint) {
1220 
1221     if (NULL != endpoint) {
1222         uint32_t a = ntohl(endpoint->sin_addr.s_addr);
1223         uint16_t p = ntohs(endpoint->sin_port);
1224         ALOGV("[%d] setRetransmitEndpoint(%u.%u.%u.%u:%hu)", mConnId,
1225                 (a >> 24), (a >> 16) & 0xFF, (a >> 8) & 0xFF, (a & 0xFF), p);
1226     } else {
1227         ALOGV("[%d] setRetransmitEndpoint = <none>", mConnId);
1228     }
1229 
1230     sp<MediaPlayerBase> p = getPlayer();
1231 
1232     // Right now, the only valid time to set a retransmit endpoint is before
1233     // player selection has been made (since the presence or absence of a
1234     // retransmit endpoint is going to determine which player is selected during
1235     // setDataSource).
1236     if (p != 0) return INVALID_OPERATION;
1237 
1238     if (NULL != endpoint) {
1239         mRetransmitEndpoint = *endpoint;
1240         mRetransmitEndpointValid = true;
1241     } else {
1242         mRetransmitEndpointValid = false;
1243     }
1244 
1245     return NO_ERROR;
1246 }
1247 
getRetransmitEndpoint(struct sockaddr_in * endpoint)1248 status_t MediaPlayerService::Client::getRetransmitEndpoint(
1249         struct sockaddr_in* endpoint)
1250 {
1251     if (NULL == endpoint)
1252         return BAD_VALUE;
1253 
1254     sp<MediaPlayerBase> p = getPlayer();
1255 
1256     if (p != NULL)
1257         return p->getRetransmitEndpoint(endpoint);
1258 
1259     if (!mRetransmitEndpointValid)
1260         return NO_INIT;
1261 
1262     *endpoint = mRetransmitEndpoint;
1263 
1264     return NO_ERROR;
1265 }
1266 
notify(void * cookie,int msg,int ext1,int ext2,const Parcel * obj)1267 void MediaPlayerService::Client::notify(
1268         void* cookie, int msg, int ext1, int ext2, const Parcel *obj)
1269 {
1270     Client* client = static_cast<Client*>(cookie);
1271     if (client == NULL) {
1272         return;
1273     }
1274 
1275     sp<IMediaPlayerClient> c;
1276     {
1277         Mutex::Autolock l(client->mLock);
1278         c = client->mClient;
1279         if (msg == MEDIA_PLAYBACK_COMPLETE && client->mNextClient != NULL) {
1280             if (client->mAudioOutput != NULL)
1281                 client->mAudioOutput->switchToNextOutput();
1282             client->mNextClient->start();
1283             if (client->mNextClient->mClient != NULL) {
1284                 client->mNextClient->mClient->notify(
1285                         MEDIA_INFO, MEDIA_INFO_STARTED_AS_NEXT, 0, obj);
1286             }
1287         }
1288     }
1289 
1290     if (MEDIA_INFO == msg &&
1291         MEDIA_INFO_METADATA_UPDATE == ext1) {
1292         const media::Metadata::Type metadata_type = ext2;
1293 
1294         if(client->shouldDropMetadata(metadata_type)) {
1295             return;
1296         }
1297 
1298         // Update the list of metadata that have changed. getMetadata
1299         // also access mMetadataUpdated and clears it.
1300         client->addNewMetadataUpdate(metadata_type);
1301     }
1302 
1303     if (c != NULL) {
1304         ALOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, cookie, msg, ext1, ext2);
1305         c->notify(msg, ext1, ext2, obj);
1306     }
1307 }
1308 
1309 
shouldDropMetadata(media::Metadata::Type code) const1310 bool MediaPlayerService::Client::shouldDropMetadata(media::Metadata::Type code) const
1311 {
1312     Mutex::Autolock lock(mLock);
1313 
1314     if (findMetadata(mMetadataDrop, code)) {
1315         return true;
1316     }
1317 
1318     if (mMetadataAllow.isEmpty() || findMetadata(mMetadataAllow, code)) {
1319         return false;
1320     } else {
1321         return true;
1322     }
1323 }
1324 
1325 
addNewMetadataUpdate(media::Metadata::Type metadata_type)1326 void MediaPlayerService::Client::addNewMetadataUpdate(media::Metadata::Type metadata_type) {
1327     Mutex::Autolock lock(mLock);
1328     if (mMetadataUpdated.indexOf(metadata_type) < 0) {
1329         mMetadataUpdated.add(metadata_type);
1330     }
1331 }
1332 
1333 #if CALLBACK_ANTAGONIZER
1334 const int Antagonizer::interval = 10000; // 10 msecs
1335 
Antagonizer(notify_callback_f cb,void * client)1336 Antagonizer::Antagonizer(notify_callback_f cb, void* client) :
1337     mExit(false), mActive(false), mClient(client), mCb(cb)
1338 {
1339     createThread(callbackThread, this);
1340 }
1341 
kill()1342 void Antagonizer::kill()
1343 {
1344     Mutex::Autolock _l(mLock);
1345     mActive = false;
1346     mExit = true;
1347     mCondition.wait(mLock);
1348 }
1349 
callbackThread(void * user)1350 int Antagonizer::callbackThread(void* user)
1351 {
1352     ALOGD("Antagonizer started");
1353     Antagonizer* p = reinterpret_cast<Antagonizer*>(user);
1354     while (!p->mExit) {
1355         if (p->mActive) {
1356             ALOGV("send event");
1357             p->mCb(p->mClient, 0, 0, 0);
1358         }
1359         usleep(interval);
1360     }
1361     Mutex::Autolock _l(p->mLock);
1362     p->mCondition.signal();
1363     ALOGD("Antagonizer stopped");
1364     return 0;
1365 }
1366 #endif
1367 
1368 #undef LOG_TAG
1369 #define LOG_TAG "AudioSink"
AudioOutput(audio_session_t sessionId,int uid,int pid,const audio_attributes_t * attr)1370 MediaPlayerService::AudioOutput::AudioOutput(audio_session_t sessionId, int uid, int pid,
1371         const audio_attributes_t* attr)
1372     : mCallback(NULL),
1373       mCallbackCookie(NULL),
1374       mCallbackData(NULL),
1375       mStreamType(AUDIO_STREAM_MUSIC),
1376       mLeftVolume(1.0),
1377       mRightVolume(1.0),
1378       mPlaybackRate(AUDIO_PLAYBACK_RATE_DEFAULT),
1379       mSampleRateHz(0),
1380       mMsecsPerFrame(0),
1381       mFrameSize(0),
1382       mSessionId(sessionId),
1383       mUid(uid),
1384       mPid(pid),
1385       mSendLevel(0.0),
1386       mAuxEffectId(0),
1387       mFlags(AUDIO_OUTPUT_FLAG_NONE)
1388 {
1389     ALOGV("AudioOutput(%d)", sessionId);
1390     if (attr != NULL) {
1391         mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
1392         if (mAttributes != NULL) {
1393             memcpy(mAttributes, attr, sizeof(audio_attributes_t));
1394             mStreamType = audio_attributes_to_stream_type(attr);
1395         }
1396     } else {
1397         mAttributes = NULL;
1398     }
1399 
1400     setMinBufferCount();
1401 }
1402 
~AudioOutput()1403 MediaPlayerService::AudioOutput::~AudioOutput()
1404 {
1405     close();
1406     free(mAttributes);
1407     delete mCallbackData;
1408 }
1409 
1410 //static
setMinBufferCount()1411 void MediaPlayerService::AudioOutput::setMinBufferCount()
1412 {
1413     char value[PROPERTY_VALUE_MAX];
1414     if (property_get("ro.kernel.qemu", value, 0)) {
1415         mIsOnEmulator = true;
1416         mMinBufferCount = 12;  // to prevent systematic buffer underrun for emulator
1417     }
1418 }
1419 
1420 // static
isOnEmulator()1421 bool MediaPlayerService::AudioOutput::isOnEmulator()
1422 {
1423     setMinBufferCount(); // benign race wrt other threads
1424     return mIsOnEmulator;
1425 }
1426 
1427 // static
getMinBufferCount()1428 int MediaPlayerService::AudioOutput::getMinBufferCount()
1429 {
1430     setMinBufferCount(); // benign race wrt other threads
1431     return mMinBufferCount;
1432 }
1433 
bufferSize() const1434 ssize_t MediaPlayerService::AudioOutput::bufferSize() const
1435 {
1436     Mutex::Autolock lock(mLock);
1437     if (mTrack == 0) return NO_INIT;
1438     return mTrack->frameCount() * mFrameSize;
1439 }
1440 
frameCount() const1441 ssize_t MediaPlayerService::AudioOutput::frameCount() const
1442 {
1443     Mutex::Autolock lock(mLock);
1444     if (mTrack == 0) return NO_INIT;
1445     return mTrack->frameCount();
1446 }
1447 
channelCount() const1448 ssize_t MediaPlayerService::AudioOutput::channelCount() const
1449 {
1450     Mutex::Autolock lock(mLock);
1451     if (mTrack == 0) return NO_INIT;
1452     return mTrack->channelCount();
1453 }
1454 
frameSize() const1455 ssize_t MediaPlayerService::AudioOutput::frameSize() const
1456 {
1457     Mutex::Autolock lock(mLock);
1458     if (mTrack == 0) return NO_INIT;
1459     return mFrameSize;
1460 }
1461 
latency() const1462 uint32_t MediaPlayerService::AudioOutput::latency () const
1463 {
1464     Mutex::Autolock lock(mLock);
1465     if (mTrack == 0) return 0;
1466     return mTrack->latency();
1467 }
1468 
msecsPerFrame() const1469 float MediaPlayerService::AudioOutput::msecsPerFrame() const
1470 {
1471     Mutex::Autolock lock(mLock);
1472     return mMsecsPerFrame;
1473 }
1474 
getPosition(uint32_t * position) const1475 status_t MediaPlayerService::AudioOutput::getPosition(uint32_t *position) const
1476 {
1477     Mutex::Autolock lock(mLock);
1478     if (mTrack == 0) return NO_INIT;
1479     return mTrack->getPosition(position);
1480 }
1481 
getTimestamp(AudioTimestamp & ts) const1482 status_t MediaPlayerService::AudioOutput::getTimestamp(AudioTimestamp &ts) const
1483 {
1484     Mutex::Autolock lock(mLock);
1485     if (mTrack == 0) return NO_INIT;
1486     return mTrack->getTimestamp(ts);
1487 }
1488 
1489 // TODO: Remove unnecessary calls to getPlayedOutDurationUs()
1490 // as it acquires locks and may query the audio driver.
1491 //
1492 // Some calls could conceivably retrieve extrapolated data instead of
1493 // accessing getTimestamp() or getPosition() every time a data buffer with
1494 // a media time is received.
1495 //
1496 // Calculate duration of played samples if played at normal rate (i.e., 1.0).
getPlayedOutDurationUs(int64_t nowUs) const1497 int64_t MediaPlayerService::AudioOutput::getPlayedOutDurationUs(int64_t nowUs) const
1498 {
1499     Mutex::Autolock lock(mLock);
1500     if (mTrack == 0 || mSampleRateHz == 0) {
1501         return 0;
1502     }
1503 
1504     uint32_t numFramesPlayed;
1505     int64_t numFramesPlayedAt;
1506     AudioTimestamp ts;
1507     static const int64_t kStaleTimestamp100ms = 100000;
1508 
1509     status_t res = mTrack->getTimestamp(ts);
1510     if (res == OK) {                 // case 1: mixing audio tracks and offloaded tracks.
1511         numFramesPlayed = ts.mPosition;
1512         numFramesPlayedAt = ts.mTime.tv_sec * 1000000LL + ts.mTime.tv_nsec / 1000;
1513         const int64_t timestampAge = nowUs - numFramesPlayedAt;
1514         if (timestampAge > kStaleTimestamp100ms) {
1515             // This is an audio FIXME.
1516             // getTimestamp returns a timestamp which may come from audio mixing threads.
1517             // After pausing, the MixerThread may go idle, thus the mTime estimate may
1518             // become stale. Assuming that the MixerThread runs 20ms, with FastMixer at 5ms,
1519             // the max latency should be about 25ms with an average around 12ms (to be verified).
1520             // For safety we use 100ms.
1521             ALOGV("getTimestamp: returned stale timestamp nowUs(%lld) numFramesPlayedAt(%lld)",
1522                     (long long)nowUs, (long long)numFramesPlayedAt);
1523             numFramesPlayedAt = nowUs - kStaleTimestamp100ms;
1524         }
1525         //ALOGD("getTimestamp: OK %d %lld", numFramesPlayed, (long long)numFramesPlayedAt);
1526     } else if (res == WOULD_BLOCK) { // case 2: transitory state on start of a new track
1527         numFramesPlayed = 0;
1528         numFramesPlayedAt = nowUs;
1529         //ALOGD("getTimestamp: WOULD_BLOCK %d %lld",
1530         //        numFramesPlayed, (long long)numFramesPlayedAt);
1531     } else {                         // case 3: transitory at new track or audio fast tracks.
1532         res = mTrack->getPosition(&numFramesPlayed);
1533         CHECK_EQ(res, (status_t)OK);
1534         numFramesPlayedAt = nowUs;
1535         numFramesPlayedAt += 1000LL * mTrack->latency() / 2; /* XXX */
1536         //ALOGD("getPosition: %u %lld", numFramesPlayed, (long long)numFramesPlayedAt);
1537     }
1538 
1539     // CHECK_EQ(numFramesPlayed & (1 << 31), 0);  // can't be negative until 12.4 hrs, test
1540     // TODO: remove the (int32_t) casting below as it may overflow at 12.4 hours.
1541     int64_t durationUs = (int64_t)((int32_t)numFramesPlayed * 1000000LL / mSampleRateHz)
1542             + nowUs - numFramesPlayedAt;
1543     if (durationUs < 0) {
1544         // Occurs when numFramesPlayed position is very small and the following:
1545         // (1) In case 1, the time nowUs is computed before getTimestamp() is called and
1546         //     numFramesPlayedAt is greater than nowUs by time more than numFramesPlayed.
1547         // (2) In case 3, using getPosition and adding mAudioSink->latency() to
1548         //     numFramesPlayedAt, by a time amount greater than numFramesPlayed.
1549         //
1550         // Both of these are transitory conditions.
1551         ALOGV("getPlayedOutDurationUs: negative duration %lld set to zero", (long long)durationUs);
1552         durationUs = 0;
1553     }
1554     ALOGV("getPlayedOutDurationUs(%lld) nowUs(%lld) frames(%u) framesAt(%lld)",
1555             (long long)durationUs, (long long)nowUs, numFramesPlayed, (long long)numFramesPlayedAt);
1556     return durationUs;
1557 }
1558 
getFramesWritten(uint32_t * frameswritten) const1559 status_t MediaPlayerService::AudioOutput::getFramesWritten(uint32_t *frameswritten) const
1560 {
1561     Mutex::Autolock lock(mLock);
1562     if (mTrack == 0) return NO_INIT;
1563     ExtendedTimestamp ets;
1564     status_t status = mTrack->getTimestamp(&ets);
1565     if (status == OK || status == WOULD_BLOCK) {
1566         *frameswritten = (uint32_t)ets.mPosition[ExtendedTimestamp::LOCATION_CLIENT];
1567     }
1568     return status;
1569 }
1570 
setParameters(const String8 & keyValuePairs)1571 status_t MediaPlayerService::AudioOutput::setParameters(const String8& keyValuePairs)
1572 {
1573     Mutex::Autolock lock(mLock);
1574     if (mTrack == 0) return NO_INIT;
1575     return mTrack->setParameters(keyValuePairs);
1576 }
1577 
getParameters(const String8 & keys)1578 String8  MediaPlayerService::AudioOutput::getParameters(const String8& keys)
1579 {
1580     Mutex::Autolock lock(mLock);
1581     if (mTrack == 0) return String8::empty();
1582     return mTrack->getParameters(keys);
1583 }
1584 
setAudioAttributes(const audio_attributes_t * attributes)1585 void MediaPlayerService::AudioOutput::setAudioAttributes(const audio_attributes_t * attributes) {
1586     Mutex::Autolock lock(mLock);
1587     if (attributes == NULL) {
1588         free(mAttributes);
1589         mAttributes = NULL;
1590     } else {
1591         if (mAttributes == NULL) {
1592             mAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
1593         }
1594         memcpy(mAttributes, attributes, sizeof(audio_attributes_t));
1595         mStreamType = audio_attributes_to_stream_type(attributes);
1596     }
1597 }
1598 
setAudioStreamType(audio_stream_type_t streamType)1599 void MediaPlayerService::AudioOutput::setAudioStreamType(audio_stream_type_t streamType)
1600 {
1601     Mutex::Autolock lock(mLock);
1602     // do not allow direct stream type modification if attributes have been set
1603     if (mAttributes == NULL) {
1604         mStreamType = streamType;
1605     }
1606 }
1607 
deleteRecycledTrack_l()1608 void MediaPlayerService::AudioOutput::deleteRecycledTrack_l()
1609 {
1610     ALOGV("deleteRecycledTrack_l");
1611     if (mRecycledTrack != 0) {
1612 
1613         if (mCallbackData != NULL) {
1614             mCallbackData->setOutput(NULL);
1615             mCallbackData->endTrackSwitch();
1616         }
1617 
1618         if ((mRecycledTrack->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) {
1619             int32_t msec = 0;
1620             if (!mRecycledTrack->stopped()) { // check if active
1621                  (void)mRecycledTrack->pendingDuration(&msec);
1622             }
1623             mRecycledTrack->stop(); // ensure full data drain
1624             ALOGD("deleting recycled track, waiting for data drain (%d msec)", msec);
1625             if (msec > 0) {
1626                 static const int32_t WAIT_LIMIT_MS = 3000;
1627                 if (msec > WAIT_LIMIT_MS) {
1628                     msec = WAIT_LIMIT_MS;
1629                 }
1630                 usleep(msec * 1000LL);
1631             }
1632         }
1633         // An offloaded track isn't flushed because the STREAM_END is reported
1634         // slightly prematurely to allow time for the gapless track switch
1635         // but this means that if we decide not to recycle the track there
1636         // could be a small amount of residual data still playing. We leave
1637         // AudioFlinger to drain the track.
1638 
1639         mRecycledTrack.clear();
1640         close_l();
1641         delete mCallbackData;
1642         mCallbackData = NULL;
1643     }
1644 }
1645 
close_l()1646 void MediaPlayerService::AudioOutput::close_l()
1647 {
1648     mTrack.clear();
1649 }
1650 
open(uint32_t sampleRate,int channelCount,audio_channel_mask_t channelMask,audio_format_t format,int bufferCount,AudioCallback cb,void * cookie,audio_output_flags_t flags,const audio_offload_info_t * offloadInfo,bool doNotReconnect,uint32_t suggestedFrameCount)1651 status_t MediaPlayerService::AudioOutput::open(
1652         uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
1653         audio_format_t format, int bufferCount,
1654         AudioCallback cb, void *cookie,
1655         audio_output_flags_t flags,
1656         const audio_offload_info_t *offloadInfo,
1657         bool doNotReconnect,
1658         uint32_t suggestedFrameCount)
1659 {
1660     ALOGV("open(%u, %d, 0x%x, 0x%x, %d, %d 0x%x)", sampleRate, channelCount, channelMask,
1661                 format, bufferCount, mSessionId, flags);
1662 
1663     // offloading is only supported in callback mode for now.
1664     // offloadInfo must be present if offload flag is set
1665     if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) &&
1666             ((cb == NULL) || (offloadInfo == NULL))) {
1667         return BAD_VALUE;
1668     }
1669 
1670     // compute frame count for the AudioTrack internal buffer
1671     size_t frameCount;
1672     if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
1673         frameCount = 0; // AudioTrack will get frame count from AudioFlinger
1674     } else {
1675         // try to estimate the buffer processing fetch size from AudioFlinger.
1676         // framesPerBuffer is approximate and generally correct, except when it's not :-).
1677         uint32_t afSampleRate;
1678         size_t afFrameCount;
1679         if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) != NO_ERROR) {
1680             return NO_INIT;
1681         }
1682         if (AudioSystem::getOutputSamplingRate(&afSampleRate, mStreamType) != NO_ERROR) {
1683             return NO_INIT;
1684         }
1685         const size_t framesPerBuffer =
1686                 (unsigned long long)sampleRate * afFrameCount / afSampleRate;
1687 
1688         if (bufferCount == 0) {
1689             // use suggestedFrameCount
1690             bufferCount = (suggestedFrameCount + framesPerBuffer - 1) / framesPerBuffer;
1691         }
1692         // Check argument bufferCount against the mininum buffer count
1693         if (bufferCount != 0 && bufferCount < mMinBufferCount) {
1694             ALOGV("bufferCount (%d) increased to %d", bufferCount, mMinBufferCount);
1695             bufferCount = mMinBufferCount;
1696         }
1697         // if frameCount is 0, then AudioTrack will get frame count from AudioFlinger
1698         // which will be the minimum size permitted.
1699         frameCount = bufferCount * framesPerBuffer;
1700     }
1701 
1702     if (channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER) {
1703         channelMask = audio_channel_out_mask_from_count(channelCount);
1704         if (0 == channelMask) {
1705             ALOGE("open() error, can\'t derive mask for %d audio channels", channelCount);
1706             return NO_INIT;
1707         }
1708     }
1709 
1710     Mutex::Autolock lock(mLock);
1711     mCallback = cb;
1712     mCallbackCookie = cookie;
1713 
1714     // Check whether we can recycle the track
1715     bool reuse = false;
1716     bool bothOffloaded = false;
1717 
1718     if (mRecycledTrack != 0) {
1719         // check whether we are switching between two offloaded tracks
1720         bothOffloaded = (flags & mRecycledTrack->getFlags()
1721                                 & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0;
1722 
1723         // check if the existing track can be reused as-is, or if a new track needs to be created.
1724         reuse = true;
1725 
1726         if ((mCallbackData == NULL && mCallback != NULL) ||
1727                 (mCallbackData != NULL && mCallback == NULL)) {
1728             // recycled track uses callbacks but the caller wants to use writes, or vice versa
1729             ALOGV("can't chain callback and write");
1730             reuse = false;
1731         } else if ((mRecycledTrack->getSampleRate() != sampleRate) ||
1732                 (mRecycledTrack->channelCount() != (uint32_t)channelCount) ) {
1733             ALOGV("samplerate, channelcount differ: %u/%u Hz, %u/%d ch",
1734                   mRecycledTrack->getSampleRate(), sampleRate,
1735                   mRecycledTrack->channelCount(), channelCount);
1736             reuse = false;
1737         } else if (flags != mFlags) {
1738             ALOGV("output flags differ %08x/%08x", flags, mFlags);
1739             reuse = false;
1740         } else if (mRecycledTrack->format() != format) {
1741             reuse = false;
1742         }
1743     } else {
1744         ALOGV("no track available to recycle");
1745     }
1746 
1747     ALOGV_IF(bothOffloaded, "both tracks offloaded");
1748 
1749     // If we can't recycle and both tracks are offloaded
1750     // we must close the previous output before opening a new one
1751     if (bothOffloaded && !reuse) {
1752         ALOGV("both offloaded and not recycling");
1753         deleteRecycledTrack_l();
1754     }
1755 
1756     sp<AudioTrack> t;
1757     CallbackData *newcbd = NULL;
1758 
1759     // We don't attempt to create a new track if we are recycling an
1760     // offloaded track. But, if we are recycling a non-offloaded or we
1761     // are switching where one is offloaded and one isn't then we create
1762     // the new track in advance so that we can read additional stream info
1763 
1764     if (!(reuse && bothOffloaded)) {
1765         ALOGV("creating new AudioTrack");
1766 
1767         if (mCallback != NULL) {
1768             newcbd = new CallbackData(this);
1769             t = new AudioTrack(
1770                     mStreamType,
1771                     sampleRate,
1772                     format,
1773                     channelMask,
1774                     frameCount,
1775                     flags,
1776                     CallbackWrapper,
1777                     newcbd,
1778                     0,  // notification frames
1779                     mSessionId,
1780                     AudioTrack::TRANSFER_CALLBACK,
1781                     offloadInfo,
1782                     mUid,
1783                     mPid,
1784                     mAttributes,
1785                     doNotReconnect);
1786         } else {
1787             // TODO: Due to buffer memory concerns, we use a max target playback speed
1788             // based on mPlaybackRate at the time of open (instead of kMaxRequiredSpeed),
1789             // also clamping the target speed to 1.0 <= targetSpeed <= kMaxRequiredSpeed.
1790             const float targetSpeed =
1791                     std::min(std::max(mPlaybackRate.mSpeed, 1.0f), kMaxRequiredSpeed);
1792             ALOGW_IF(targetSpeed != mPlaybackRate.mSpeed,
1793                     "track target speed:%f clamped from playback speed:%f",
1794                     targetSpeed, mPlaybackRate.mSpeed);
1795             t = new AudioTrack(
1796                     mStreamType,
1797                     sampleRate,
1798                     format,
1799                     channelMask,
1800                     frameCount,
1801                     flags,
1802                     NULL, // callback
1803                     NULL, // user data
1804                     0, // notification frames
1805                     mSessionId,
1806                     AudioTrack::TRANSFER_DEFAULT,
1807                     NULL, // offload info
1808                     mUid,
1809                     mPid,
1810                     mAttributes,
1811                     doNotReconnect,
1812                     targetSpeed);
1813         }
1814 
1815         if ((t == 0) || (t->initCheck() != NO_ERROR)) {
1816             ALOGE("Unable to create audio track");
1817             delete newcbd;
1818             // t goes out of scope, so reference count drops to zero
1819             return NO_INIT;
1820         } else {
1821             // successful AudioTrack initialization implies a legacy stream type was generated
1822             // from the audio attributes
1823             mStreamType = t->streamType();
1824         }
1825     }
1826 
1827     if (reuse) {
1828         CHECK(mRecycledTrack != NULL);
1829 
1830         if (!bothOffloaded) {
1831             if (mRecycledTrack->frameCount() != t->frameCount()) {
1832                 ALOGV("framecount differs: %zu/%zu frames",
1833                       mRecycledTrack->frameCount(), t->frameCount());
1834                 reuse = false;
1835             }
1836         }
1837 
1838         if (reuse) {
1839             ALOGV("chaining to next output and recycling track");
1840             close_l();
1841             mTrack = mRecycledTrack;
1842             mRecycledTrack.clear();
1843             if (mCallbackData != NULL) {
1844                 mCallbackData->setOutput(this);
1845             }
1846             delete newcbd;
1847             return OK;
1848         }
1849     }
1850 
1851     // we're not going to reuse the track, unblock and flush it
1852     // this was done earlier if both tracks are offloaded
1853     if (!bothOffloaded) {
1854         deleteRecycledTrack_l();
1855     }
1856 
1857     CHECK((t != NULL) && ((mCallback == NULL) || (newcbd != NULL)));
1858 
1859     mCallbackData = newcbd;
1860     ALOGV("setVolume");
1861     t->setVolume(mLeftVolume, mRightVolume);
1862 
1863     mSampleRateHz = sampleRate;
1864     mFlags = flags;
1865     mMsecsPerFrame = 1E3f / (mPlaybackRate.mSpeed * sampleRate);
1866     mFrameSize = t->frameSize();
1867     mTrack = t;
1868 
1869     status_t res = NO_ERROR;
1870     // Note some output devices may give us a direct track even though we don't specify it.
1871     // Example: Line application b/17459982.
1872     if ((t->getFlags() & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | AUDIO_OUTPUT_FLAG_DIRECT)) == 0) {
1873         res = t->setPlaybackRate(mPlaybackRate);
1874         if (res == NO_ERROR) {
1875             t->setAuxEffectSendLevel(mSendLevel);
1876             res = t->attachAuxEffect(mAuxEffectId);
1877         }
1878     }
1879     ALOGV("open() DONE status %d", res);
1880     return res;
1881 }
1882 
start()1883 status_t MediaPlayerService::AudioOutput::start()
1884 {
1885     ALOGV("start");
1886     Mutex::Autolock lock(mLock);
1887     if (mCallbackData != NULL) {
1888         mCallbackData->endTrackSwitch();
1889     }
1890     if (mTrack != 0) {
1891         mTrack->setVolume(mLeftVolume, mRightVolume);
1892         mTrack->setAuxEffectSendLevel(mSendLevel);
1893         return mTrack->start();
1894     }
1895     return NO_INIT;
1896 }
1897 
setNextOutput(const sp<AudioOutput> & nextOutput)1898 void MediaPlayerService::AudioOutput::setNextOutput(const sp<AudioOutput>& nextOutput) {
1899     Mutex::Autolock lock(mLock);
1900     mNextOutput = nextOutput;
1901 }
1902 
switchToNextOutput()1903 void MediaPlayerService::AudioOutput::switchToNextOutput() {
1904     ALOGV("switchToNextOutput");
1905 
1906     // Try to acquire the callback lock before moving track (without incurring deadlock).
1907     const unsigned kMaxSwitchTries = 100;
1908     Mutex::Autolock lock(mLock);
1909     for (unsigned tries = 0;;) {
1910         if (mTrack == 0) {
1911             return;
1912         }
1913         if (mNextOutput != NULL && mNextOutput != this) {
1914             if (mCallbackData != NULL) {
1915                 // two alternative approaches
1916 #if 1
1917                 CallbackData *callbackData = mCallbackData;
1918                 mLock.unlock();
1919                 // proper acquisition sequence
1920                 callbackData->lock();
1921                 mLock.lock();
1922                 // Caution: it is unlikely that someone deleted our callback or changed our target
1923                 if (callbackData != mCallbackData || mNextOutput == NULL || mNextOutput == this) {
1924                     // fatal if we are starved out.
1925                     LOG_ALWAYS_FATAL_IF(++tries > kMaxSwitchTries,
1926                             "switchToNextOutput() cannot obtain correct lock sequence");
1927                     callbackData->unlock();
1928                     continue;
1929                 }
1930                 callbackData->mSwitching = true; // begin track switch
1931 #else
1932                 // tryBeginTrackSwitch() returns false if the callback has the lock.
1933                 if (!mCallbackData->tryBeginTrackSwitch()) {
1934                     // fatal if we are starved out.
1935                     LOG_ALWAYS_FATAL_IF(++tries > kMaxSwitchTries,
1936                             "switchToNextOutput() cannot obtain callback lock");
1937                     mLock.unlock();
1938                     usleep(5 * 1000 /* usec */); // allow callback to use AudioOutput
1939                     mLock.lock();
1940                     continue;
1941                 }
1942 #endif
1943             }
1944 
1945             Mutex::Autolock nextLock(mNextOutput->mLock);
1946 
1947             // If the next output track is not NULL, then it has been
1948             // opened already for playback.
1949             // This is possible even without the next player being started,
1950             // for example, the next player could be prepared and seeked.
1951             //
1952             // Presuming it isn't advisable to force the track over.
1953              if (mNextOutput->mTrack == NULL) {
1954                 ALOGD("Recycling track for gapless playback");
1955                 delete mNextOutput->mCallbackData;
1956                 mNextOutput->mCallbackData = mCallbackData;
1957                 mNextOutput->mRecycledTrack = mTrack;
1958                 mNextOutput->mSampleRateHz = mSampleRateHz;
1959                 mNextOutput->mMsecsPerFrame = mMsecsPerFrame;
1960                 mNextOutput->mFlags = mFlags;
1961                 mNextOutput->mFrameSize = mFrameSize;
1962                 close_l();
1963                 mCallbackData = NULL;  // destruction handled by mNextOutput
1964             } else {
1965                 ALOGW("Ignoring gapless playback because next player has already started");
1966                 // remove track in case resource needed for future players.
1967                 if (mCallbackData != NULL) {
1968                     mCallbackData->endTrackSwitch();  // release lock for callbacks before close.
1969                 }
1970                 close_l();
1971             }
1972         }
1973         break;
1974     }
1975 }
1976 
write(const void * buffer,size_t size,bool blocking)1977 ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size, bool blocking)
1978 {
1979     Mutex::Autolock lock(mLock);
1980     LOG_ALWAYS_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback.");
1981 
1982     //ALOGV("write(%p, %u)", buffer, size);
1983     if (mTrack != 0) {
1984         return mTrack->write(buffer, size, blocking);
1985     }
1986     return NO_INIT;
1987 }
1988 
stop()1989 void MediaPlayerService::AudioOutput::stop()
1990 {
1991     ALOGV("stop");
1992     Mutex::Autolock lock(mLock);
1993     if (mTrack != 0) mTrack->stop();
1994 }
1995 
flush()1996 void MediaPlayerService::AudioOutput::flush()
1997 {
1998     ALOGV("flush");
1999     Mutex::Autolock lock(mLock);
2000     if (mTrack != 0) mTrack->flush();
2001 }
2002 
pause()2003 void MediaPlayerService::AudioOutput::pause()
2004 {
2005     ALOGV("pause");
2006     Mutex::Autolock lock(mLock);
2007     if (mTrack != 0) mTrack->pause();
2008 }
2009 
close()2010 void MediaPlayerService::AudioOutput::close()
2011 {
2012     ALOGV("close");
2013     sp<AudioTrack> track;
2014     {
2015         Mutex::Autolock lock(mLock);
2016         track = mTrack;
2017         close_l(); // clears mTrack
2018     }
2019     // destruction of the track occurs outside of mutex.
2020 }
2021 
setVolume(float left,float right)2022 void MediaPlayerService::AudioOutput::setVolume(float left, float right)
2023 {
2024     ALOGV("setVolume(%f, %f)", left, right);
2025     Mutex::Autolock lock(mLock);
2026     mLeftVolume = left;
2027     mRightVolume = right;
2028     if (mTrack != 0) {
2029         mTrack->setVolume(left, right);
2030     }
2031 }
2032 
setPlaybackRate(const AudioPlaybackRate & rate)2033 status_t MediaPlayerService::AudioOutput::setPlaybackRate(const AudioPlaybackRate &rate)
2034 {
2035     ALOGV("setPlaybackRate(%f %f %d %d)",
2036                 rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode);
2037     Mutex::Autolock lock(mLock);
2038     if (mTrack == 0) {
2039         // remember rate so that we can set it when the track is opened
2040         mPlaybackRate = rate;
2041         return OK;
2042     }
2043     status_t res = mTrack->setPlaybackRate(rate);
2044     if (res != NO_ERROR) {
2045         return res;
2046     }
2047     // rate.mSpeed is always greater than 0 if setPlaybackRate succeeded
2048     CHECK_GT(rate.mSpeed, 0.f);
2049     mPlaybackRate = rate;
2050     if (mSampleRateHz != 0) {
2051         mMsecsPerFrame = 1E3f / (rate.mSpeed * mSampleRateHz);
2052     }
2053     return res;
2054 }
2055 
getPlaybackRate(AudioPlaybackRate * rate)2056 status_t MediaPlayerService::AudioOutput::getPlaybackRate(AudioPlaybackRate *rate)
2057 {
2058     ALOGV("setPlaybackRate");
2059     Mutex::Autolock lock(mLock);
2060     if (mTrack == 0) {
2061         return NO_INIT;
2062     }
2063     *rate = mTrack->getPlaybackRate();
2064     return NO_ERROR;
2065 }
2066 
setAuxEffectSendLevel(float level)2067 status_t MediaPlayerService::AudioOutput::setAuxEffectSendLevel(float level)
2068 {
2069     ALOGV("setAuxEffectSendLevel(%f)", level);
2070     Mutex::Autolock lock(mLock);
2071     mSendLevel = level;
2072     if (mTrack != 0) {
2073         return mTrack->setAuxEffectSendLevel(level);
2074     }
2075     return NO_ERROR;
2076 }
2077 
attachAuxEffect(int effectId)2078 status_t MediaPlayerService::AudioOutput::attachAuxEffect(int effectId)
2079 {
2080     ALOGV("attachAuxEffect(%d)", effectId);
2081     Mutex::Autolock lock(mLock);
2082     mAuxEffectId = effectId;
2083     if (mTrack != 0) {
2084         return mTrack->attachAuxEffect(effectId);
2085     }
2086     return NO_ERROR;
2087 }
2088 
2089 // static
CallbackWrapper(int event,void * cookie,void * info)2090 void MediaPlayerService::AudioOutput::CallbackWrapper(
2091         int event, void *cookie, void *info) {
2092     //ALOGV("callbackwrapper");
2093     CallbackData *data = (CallbackData*)cookie;
2094     // lock to ensure we aren't caught in the middle of a track switch.
2095     data->lock();
2096     AudioOutput *me = data->getOutput();
2097     AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
2098     if (me == NULL) {
2099         // no output set, likely because the track was scheduled to be reused
2100         // by another player, but the format turned out to be incompatible.
2101         data->unlock();
2102         if (buffer != NULL) {
2103             buffer->size = 0;
2104         }
2105         return;
2106     }
2107 
2108     switch(event) {
2109     case AudioTrack::EVENT_MORE_DATA: {
2110         size_t actualSize = (*me->mCallback)(
2111                 me, buffer->raw, buffer->size, me->mCallbackCookie,
2112                 CB_EVENT_FILL_BUFFER);
2113 
2114         // Log when no data is returned from the callback.
2115         // (1) We may have no data (especially with network streaming sources).
2116         // (2) We may have reached the EOS and the audio track is not stopped yet.
2117         // Note that AwesomePlayer/AudioPlayer will only return zero size when it reaches the EOS.
2118         // NuPlayerRenderer will return zero when it doesn't have data (it doesn't block to fill).
2119         //
2120         // This is a benign busy-wait, with the next data request generated 10 ms or more later;
2121         // nevertheless for power reasons, we don't want to see too many of these.
2122 
2123         ALOGV_IF(actualSize == 0 && buffer->size > 0, "callbackwrapper: empty buffer returned");
2124 
2125         buffer->size = actualSize;
2126         } break;
2127 
2128     case AudioTrack::EVENT_STREAM_END:
2129         // currently only occurs for offloaded callbacks
2130         ALOGV("callbackwrapper: deliver EVENT_STREAM_END");
2131         (*me->mCallback)(me, NULL /* buffer */, 0 /* size */,
2132                 me->mCallbackCookie, CB_EVENT_STREAM_END);
2133         break;
2134 
2135     case AudioTrack::EVENT_NEW_IAUDIOTRACK :
2136         ALOGV("callbackwrapper: deliver EVENT_TEAR_DOWN");
2137         (*me->mCallback)(me,  NULL /* buffer */, 0 /* size */,
2138                 me->mCallbackCookie, CB_EVENT_TEAR_DOWN);
2139         break;
2140 
2141     case AudioTrack::EVENT_UNDERRUN:
2142         // This occurs when there is no data available, typically
2143         // when there is a failure to supply data to the AudioTrack.  It can also
2144         // occur in non-offloaded mode when the audio device comes out of standby.
2145         //
2146         // If an AudioTrack underruns it outputs silence. Since this happens suddenly
2147         // it may sound like an audible pop or glitch.
2148         //
2149         // The underrun event is sent once per track underrun; the condition is reset
2150         // when more data is sent to the AudioTrack.
2151         ALOGD("callbackwrapper: EVENT_UNDERRUN (discarded)");
2152         break;
2153 
2154     default:
2155         ALOGE("received unknown event type: %d inside CallbackWrapper !", event);
2156     }
2157 
2158     data->unlock();
2159 }
2160 
getSessionId() const2161 audio_session_t MediaPlayerService::AudioOutput::getSessionId() const
2162 {
2163     Mutex::Autolock lock(mLock);
2164     return mSessionId;
2165 }
2166 
getSampleRate() const2167 uint32_t MediaPlayerService::AudioOutput::getSampleRate() const
2168 {
2169     Mutex::Autolock lock(mLock);
2170     if (mTrack == 0) return 0;
2171     return mTrack->getSampleRate();
2172 }
2173 
getBufferDurationInUs() const2174 int64_t MediaPlayerService::AudioOutput::getBufferDurationInUs() const
2175 {
2176     Mutex::Autolock lock(mLock);
2177     if (mTrack == 0) {
2178         return 0;
2179     }
2180     int64_t duration;
2181     if (mTrack->getBufferDurationInUs(&duration) != OK) {
2182         return 0;
2183     }
2184     return duration;
2185 }
2186 
2187 ////////////////////////////////////////////////////////////////////////////////
2188 
2189 struct CallbackThread : public Thread {
2190     CallbackThread(const wp<MediaPlayerBase::AudioSink> &sink,
2191                    MediaPlayerBase::AudioSink::AudioCallback cb,
2192                    void *cookie);
2193 
2194 protected:
2195     virtual ~CallbackThread();
2196 
2197     virtual bool threadLoop();
2198 
2199 private:
2200     wp<MediaPlayerBase::AudioSink> mSink;
2201     MediaPlayerBase::AudioSink::AudioCallback mCallback;
2202     void *mCookie;
2203     void *mBuffer;
2204     size_t mBufferSize;
2205 
2206     CallbackThread(const CallbackThread &);
2207     CallbackThread &operator=(const CallbackThread &);
2208 };
2209 
CallbackThread(const wp<MediaPlayerBase::AudioSink> & sink,MediaPlayerBase::AudioSink::AudioCallback cb,void * cookie)2210 CallbackThread::CallbackThread(
2211         const wp<MediaPlayerBase::AudioSink> &sink,
2212         MediaPlayerBase::AudioSink::AudioCallback cb,
2213         void *cookie)
2214     : mSink(sink),
2215       mCallback(cb),
2216       mCookie(cookie),
2217       mBuffer(NULL),
2218       mBufferSize(0) {
2219 }
2220 
~CallbackThread()2221 CallbackThread::~CallbackThread() {
2222     if (mBuffer) {
2223         free(mBuffer);
2224         mBuffer = NULL;
2225     }
2226 }
2227 
threadLoop()2228 bool CallbackThread::threadLoop() {
2229     sp<MediaPlayerBase::AudioSink> sink = mSink.promote();
2230     if (sink == NULL) {
2231         return false;
2232     }
2233 
2234     if (mBuffer == NULL) {
2235         mBufferSize = sink->bufferSize();
2236         mBuffer = malloc(mBufferSize);
2237     }
2238 
2239     size_t actualSize =
2240         (*mCallback)(sink.get(), mBuffer, mBufferSize, mCookie,
2241                 MediaPlayerBase::AudioSink::CB_EVENT_FILL_BUFFER);
2242 
2243     if (actualSize > 0) {
2244         sink->write(mBuffer, actualSize);
2245         // Could return false on sink->write() error or short count.
2246         // Not necessarily appropriate but would work for AudioCache behavior.
2247     }
2248 
2249     return true;
2250 }
2251 
2252 ////////////////////////////////////////////////////////////////////////////////
2253 
addBatteryData(uint32_t params)2254 void MediaPlayerService::addBatteryData(uint32_t params)
2255 {
2256     Mutex::Autolock lock(mLock);
2257 
2258     int32_t time = systemTime() / 1000000L;
2259 
2260     // change audio output devices. This notification comes from AudioFlinger
2261     if ((params & kBatteryDataSpeakerOn)
2262             || (params & kBatteryDataOtherAudioDeviceOn)) {
2263 
2264         int deviceOn[NUM_AUDIO_DEVICES];
2265         for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
2266             deviceOn[i] = 0;
2267         }
2268 
2269         if ((params & kBatteryDataSpeakerOn)
2270                 && (params & kBatteryDataOtherAudioDeviceOn)) {
2271             deviceOn[SPEAKER_AND_OTHER] = 1;
2272         } else if (params & kBatteryDataSpeakerOn) {
2273             deviceOn[SPEAKER] = 1;
2274         } else {
2275             deviceOn[OTHER_AUDIO_DEVICE] = 1;
2276         }
2277 
2278         for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
2279             if (mBatteryAudio.deviceOn[i] != deviceOn[i]){
2280 
2281                 if (mBatteryAudio.refCount > 0) { // if playing audio
2282                     if (!deviceOn[i]) {
2283                         mBatteryAudio.lastTime[i] += time;
2284                         mBatteryAudio.totalTime[i] += mBatteryAudio.lastTime[i];
2285                         mBatteryAudio.lastTime[i] = 0;
2286                     } else {
2287                         mBatteryAudio.lastTime[i] = 0 - time;
2288                     }
2289                 }
2290 
2291                 mBatteryAudio.deviceOn[i] = deviceOn[i];
2292             }
2293         }
2294         return;
2295     }
2296 
2297     // an audio stream is started
2298     if (params & kBatteryDataAudioFlingerStart) {
2299         // record the start time only if currently no other audio
2300         // is being played
2301         if (mBatteryAudio.refCount == 0) {
2302             for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
2303                 if (mBatteryAudio.deviceOn[i]) {
2304                     mBatteryAudio.lastTime[i] -= time;
2305                 }
2306             }
2307         }
2308 
2309         mBatteryAudio.refCount ++;
2310         return;
2311 
2312     } else if (params & kBatteryDataAudioFlingerStop) {
2313         if (mBatteryAudio.refCount <= 0) {
2314             ALOGW("Battery track warning: refCount is <= 0");
2315             return;
2316         }
2317 
2318         // record the stop time only if currently this is the only
2319         // audio being played
2320         if (mBatteryAudio.refCount == 1) {
2321             for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
2322                 if (mBatteryAudio.deviceOn[i]) {
2323                     mBatteryAudio.lastTime[i] += time;
2324                     mBatteryAudio.totalTime[i] += mBatteryAudio.lastTime[i];
2325                     mBatteryAudio.lastTime[i] = 0;
2326                 }
2327             }
2328         }
2329 
2330         mBatteryAudio.refCount --;
2331         return;
2332     }
2333 
2334     int uid = IPCThreadState::self()->getCallingUid();
2335     if (uid == AID_MEDIA) {
2336         return;
2337     }
2338     int index = mBatteryData.indexOfKey(uid);
2339 
2340     if (index < 0) { // create a new entry for this UID
2341         BatteryUsageInfo info;
2342         info.audioTotalTime = 0;
2343         info.videoTotalTime = 0;
2344         info.audioLastTime = 0;
2345         info.videoLastTime = 0;
2346         info.refCount = 0;
2347 
2348         if (mBatteryData.add(uid, info) == NO_MEMORY) {
2349             ALOGE("Battery track error: no memory for new app");
2350             return;
2351         }
2352     }
2353 
2354     BatteryUsageInfo &info = mBatteryData.editValueFor(uid);
2355 
2356     if (params & kBatteryDataCodecStarted) {
2357         if (params & kBatteryDataTrackAudio) {
2358             info.audioLastTime -= time;
2359             info.refCount ++;
2360         }
2361         if (params & kBatteryDataTrackVideo) {
2362             info.videoLastTime -= time;
2363             info.refCount ++;
2364         }
2365     } else {
2366         if (info.refCount == 0) {
2367             ALOGW("Battery track warning: refCount is already 0");
2368             return;
2369         } else if (info.refCount < 0) {
2370             ALOGE("Battery track error: refCount < 0");
2371             mBatteryData.removeItem(uid);
2372             return;
2373         }
2374 
2375         if (params & kBatteryDataTrackAudio) {
2376             info.audioLastTime += time;
2377             info.refCount --;
2378         }
2379         if (params & kBatteryDataTrackVideo) {
2380             info.videoLastTime += time;
2381             info.refCount --;
2382         }
2383 
2384         // no stream is being played by this UID
2385         if (info.refCount == 0) {
2386             info.audioTotalTime += info.audioLastTime;
2387             info.audioLastTime = 0;
2388             info.videoTotalTime += info.videoLastTime;
2389             info.videoLastTime = 0;
2390         }
2391     }
2392 }
2393 
pullBatteryData(Parcel * reply)2394 status_t MediaPlayerService::pullBatteryData(Parcel* reply) {
2395     Mutex::Autolock lock(mLock);
2396 
2397     // audio output devices usage
2398     int32_t time = systemTime() / 1000000L; //in ms
2399     int32_t totalTime;
2400 
2401     for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
2402         totalTime = mBatteryAudio.totalTime[i];
2403 
2404         if (mBatteryAudio.deviceOn[i]
2405             && (mBatteryAudio.lastTime[i] != 0)) {
2406                 int32_t tmpTime = mBatteryAudio.lastTime[i] + time;
2407                 totalTime += tmpTime;
2408         }
2409 
2410         reply->writeInt32(totalTime);
2411         // reset the total time
2412         mBatteryAudio.totalTime[i] = 0;
2413    }
2414 
2415     // codec usage
2416     BatteryUsageInfo info;
2417     int size = mBatteryData.size();
2418 
2419     reply->writeInt32(size);
2420     int i = 0;
2421 
2422     while (i < size) {
2423         info = mBatteryData.valueAt(i);
2424 
2425         reply->writeInt32(mBatteryData.keyAt(i)); //UID
2426         reply->writeInt32(info.audioTotalTime);
2427         reply->writeInt32(info.videoTotalTime);
2428 
2429         info.audioTotalTime = 0;
2430         info.videoTotalTime = 0;
2431 
2432         // remove the UID entry where no stream is being played
2433         if (info.refCount <= 0) {
2434             mBatteryData.removeItemsAt(i);
2435             size --;
2436             i --;
2437         }
2438         i++;
2439     }
2440     return NO_ERROR;
2441 }
2442 } // namespace android
2443