• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 **
3 ** Copyright 2017, 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 //#define LOG_NDEBUG 0
19 #define LOG_TAG "MediaPlayer2Native"
20 
21 #include <binder/IServiceManager.h>
22 #include <binder/IPCThreadState.h>
23 
24 #include <media/AudioSystem.h>
25 #include <media/DataSourceDesc.h>
26 #include <media/MediaAnalyticsItem.h>
27 #include <media/MemoryLeakTrackUtil.h>
28 #include <media/Metadata.h>
29 #include <media/NdkWrapper.h>
30 #include <media/stagefright/foundation/ADebug.h>
31 #include <media/stagefright/foundation/ALooperRoster.h>
32 #include <mediaplayer2/MediaPlayer2AudioOutput.h>
33 #include <mediaplayer2/mediaplayer2.h>
34 
35 #include <utils/Log.h>
36 #include <utils/SortedVector.h>
37 #include <utils/String8.h>
38 
39 #include <system/audio.h>
40 #include <system/window.h>
41 
42 #include <nuplayer2/NuPlayer2Driver.h>
43 
44 #include <dirent.h>
45 #include <sys/stat.h>
46 
47 namespace android {
48 
49 extern ALooperRoster gLooperRoster;
50 
51 namespace {
52 
53 const int kDumpLockRetries = 50;
54 const int kDumpLockSleepUs = 20000;
55 
56 // Max number of entries in the filter.
57 const int kMaxFilterSize = 64;  // I pulled that out of thin air.
58 
59 // FIXME: Move all the metadata related function in the Metadata.cpp
60 
61 // Unmarshall a filter from a Parcel.
62 // Filter format in a parcel:
63 //
64 //  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
65 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
66 // |                       number of entries (n)                   |
67 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
68 // |                       metadata type 1                         |
69 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
70 // |                       metadata type 2                         |
71 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
72 //  ....
73 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
74 // |                       metadata type n                         |
75 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
76 //
77 // @param p Parcel that should start with a filter.
78 // @param[out] filter On exit contains the list of metadata type to be
79 //                    filtered.
80 // @param[out] status On exit contains the status code to be returned.
81 // @return true if the parcel starts with a valid filter.
unmarshallFilter(const Parcel & p,media::Metadata::Filter * filter,status_t * status)82 bool unmarshallFilter(const Parcel& p,
83                       media::Metadata::Filter *filter,
84                       status_t *status) {
85     int32_t val;
86     if (p.readInt32(&val) != OK) {
87         ALOGE("Failed to read filter's length");
88         *status = NOT_ENOUGH_DATA;
89         return false;
90     }
91 
92     if (val > kMaxFilterSize || val < 0) {
93         ALOGE("Invalid filter len %d", val);
94         *status = BAD_VALUE;
95         return false;
96     }
97 
98     const size_t num = val;
99 
100     filter->clear();
101     filter->setCapacity(num);
102 
103     size_t size = num * sizeof(media::Metadata::Type);
104 
105 
106     if (p.dataAvail() < size) {
107         ALOGE("Filter too short expected %zu but got %zu", size, p.dataAvail());
108         *status = NOT_ENOUGH_DATA;
109         return false;
110     }
111 
112     const media::Metadata::Type *data =
113         static_cast<const media::Metadata::Type*>(p.readInplace(size));
114 
115     if (NULL == data) {
116         ALOGE("Filter had no data");
117         *status = BAD_VALUE;
118         return false;
119     }
120 
121     // TODO: The stl impl of vector would be more efficient here
122     // because it degenerates into a memcpy on pod types. Try to
123     // replace later or use stl::set.
124     for (size_t i = 0; i < num; ++i) {
125         filter->add(*data);
126         ++data;
127     }
128     *status = OK;
129     return true;
130 }
131 
132 // @param filter Of metadata type.
133 // @param val To be searched.
134 // @return true if a match was found.
findMetadata(const media::Metadata::Filter & filter,const int32_t val)135 bool findMetadata(const media::Metadata::Filter& filter, const int32_t val) {
136     // Deal with empty and ANY right away
137     if (filter.isEmpty()) {
138         return false;
139     }
140     if (filter[0] == media::Metadata::kAny) {
141         return true;
142     }
143 
144     return filter.indexOf(val) >= 0;
145 }
146 
147 // marshalling tag indicating flattened utf16 tags
148 // keep in sync with frameworks/base/media/java/android/media/AudioAttributes.java
149 const int32_t kAudioAttributesMarshallTagFlattenTags = 1;
150 
151 // Audio attributes format in a parcel:
152 //
153 //  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
154 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
155 // |                       usage                                   |
156 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
157 // |                       content_type                            |
158 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
159 // |                       source                                  |
160 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
161 // |                       flags                                   |
162 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
163 // |                       kAudioAttributesMarshallTagFlattenTags  | // ignore tags if not found
164 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
165 // |                       flattened tags in UTF16                 |
166 // |                         ...                                   |
167 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
168 //
169 // @param p Parcel that contains audio attributes.
170 // @param[out] attributes On exit points to an initialized audio_attributes_t structure
171 // @param[out] status On exit contains the status code to be returned.
unmarshallAudioAttributes(const Parcel & parcel,audio_attributes_t * attributes)172 void unmarshallAudioAttributes(const Parcel& parcel, audio_attributes_t *attributes) {
173     attributes->usage = (audio_usage_t) parcel.readInt32();
174     attributes->content_type = (audio_content_type_t) parcel.readInt32();
175     attributes->source = (audio_source_t) parcel.readInt32();
176     attributes->flags = (audio_flags_mask_t) parcel.readInt32();
177     const bool hasFlattenedTag = (parcel.readInt32() == kAudioAttributesMarshallTagFlattenTags);
178     if (hasFlattenedTag) {
179         // the tags are UTF16, convert to UTF8
180         String16 tags = parcel.readString16();
181         ssize_t realTagSize = utf16_to_utf8_length(tags.string(), tags.size());
182         if (realTagSize <= 0) {
183             strcpy(attributes->tags, "");
184         } else {
185             // copy the flattened string into the attributes as the destination for the conversion:
186             // copying array size -1, array for tags was calloc'd, no need to NULL-terminate it
187             size_t tagSize = realTagSize > AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 ?
188                     AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 : realTagSize;
189             utf16_to_utf8(tags.string(), tagSize, attributes->tags,
190                     sizeof(attributes->tags) / sizeof(attributes->tags[0]));
191         }
192     } else {
193         ALOGE("unmarshallAudioAttributes() received unflattened tags, ignoring tag values");
194         strcpy(attributes->tags, "");
195     }
196 }
197 
198 class AudioDeviceUpdatedNotifier: public AudioSystem::AudioDeviceCallback {
199 public:
AudioDeviceUpdatedNotifier(const sp<MediaPlayer2Interface> & listener)200     AudioDeviceUpdatedNotifier(const sp<MediaPlayer2Interface>& listener)
201         : mListener(listener) { }
202 
~AudioDeviceUpdatedNotifier()203     ~AudioDeviceUpdatedNotifier() { }
204 
onAudioDeviceUpdate(audio_io_handle_t audioIo,audio_port_handle_t deviceId)205     virtual void onAudioDeviceUpdate(audio_io_handle_t audioIo,
206                                      audio_port_handle_t deviceId) override {
207         sp<MediaPlayer2Interface> listener = mListener.promote();
208         if (listener != NULL) {
209             listener->sendEvent(0, MEDIA2_AUDIO_ROUTING_CHANGED, audioIo, deviceId);
210         } else {
211             ALOGW("listener for process %d death is gone", MEDIA2_AUDIO_ROUTING_CHANGED);
212         }
213     }
214 
215 private:
216     wp<MediaPlayer2Interface> mListener;
217 };
218 
219 class proxyListener : public MediaPlayer2InterfaceListener {
220 public:
proxyListener(const wp<MediaPlayer2> & player)221     proxyListener(const wp<MediaPlayer2> &player)
222         : mPlayer(player) { }
223 
~proxyListener()224     ~proxyListener() { };
225 
notify(int64_t srcId,int msg,int ext1,int ext2,const Parcel * obj)226     virtual void notify(int64_t srcId, int msg, int ext1, int ext2, const Parcel *obj) override {
227         sp<MediaPlayer2> player = mPlayer.promote();
228         if (player != NULL) {
229             player->notify(srcId, msg, ext1, ext2, obj);
230         }
231     }
232 
233 private:
234     wp<MediaPlayer2> mPlayer;
235 };
236 
237 Mutex sRecordLock;
238 SortedVector<wp<MediaPlayer2> > *sPlayers;
239 
ensureInit_l()240 void ensureInit_l() {
241     if (sPlayers == NULL) {
242         sPlayers = new SortedVector<wp<MediaPlayer2> >();
243     }
244 }
245 
addPlayer(const wp<MediaPlayer2> & player)246 void addPlayer(const wp<MediaPlayer2>& player) {
247     Mutex::Autolock lock(sRecordLock);
248     ensureInit_l();
249     sPlayers->add(player);
250 }
251 
removePlayer(const wp<MediaPlayer2> & player)252 void removePlayer(const wp<MediaPlayer2>& player) {
253     Mutex::Autolock lock(sRecordLock);
254     ensureInit_l();
255     sPlayers->remove(player);
256 }
257 
258 /**
259  * The only arguments this understands right now are -c, -von and -voff,
260  * which are parsed by ALooperRoster::dump()
261  */
dumpPlayers(int fd,const Vector<String16> & args)262 status_t dumpPlayers(int fd, const Vector<String16>& args) {
263     const size_t SIZE = 256;
264     char buffer[SIZE];
265     String8 result;
266     SortedVector< sp<MediaPlayer2> > players; //to serialise the mutex unlock & client destruction.
267 
268     if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
269         snprintf(buffer, SIZE, "Permission Denial: can't dump MediaPlayer2\n");
270         result.append(buffer);
271     } else {
272         {
273             Mutex::Autolock lock(sRecordLock);
274             ensureInit_l();
275             for (int i = 0, n = sPlayers->size(); i < n; ++i) {
276                 sp<MediaPlayer2> p = (*sPlayers)[i].promote();
277                 if (p != 0) {
278                     p->dump(fd, args);
279                 }
280                 players.add(p);
281             }
282         }
283 
284         result.append(" Files opened and/or mapped:\n");
285         snprintf(buffer, SIZE, "/proc/%d/maps", getpid());
286         FILE *f = fopen(buffer, "r");
287         if (f) {
288             while (!feof(f)) {
289                 fgets(buffer, SIZE, f);
290                 if (strstr(buffer, " /storage/") ||
291                     strstr(buffer, " /system/sounds/") ||
292                     strstr(buffer, " /data/") ||
293                     strstr(buffer, " /system/media/")) {
294                     result.append("  ");
295                     result.append(buffer);
296                 }
297             }
298             fclose(f);
299         } else {
300             result.append("couldn't open ");
301             result.append(buffer);
302             result.append("\n");
303         }
304 
305         snprintf(buffer, SIZE, "/proc/%d/fd", getpid());
306         DIR *d = opendir(buffer);
307         if (d) {
308             struct dirent *ent;
309             while((ent = readdir(d)) != NULL) {
310                 if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) {
311                     snprintf(buffer, SIZE, "/proc/%d/fd/%s", getpid(), ent->d_name);
312                     struct stat s;
313                     if (lstat(buffer, &s) == 0) {
314                         if ((s.st_mode & S_IFMT) == S_IFLNK) {
315                             char linkto[256];
316                             int len = readlink(buffer, linkto, sizeof(linkto));
317                             if(len > 0) {
318                                 if(len > 255) {
319                                     linkto[252] = '.';
320                                     linkto[253] = '.';
321                                     linkto[254] = '.';
322                                     linkto[255] = 0;
323                                 } else {
324                                     linkto[len] = 0;
325                                 }
326                                 if (strstr(linkto, "/storage/") == linkto ||
327                                     strstr(linkto, "/system/sounds/") == linkto ||
328                                     strstr(linkto, "/data/") == linkto ||
329                                     strstr(linkto, "/system/media/") == linkto) {
330                                     result.append("  ");
331                                     result.append(buffer);
332                                     result.append(" -> ");
333                                     result.append(linkto);
334                                     result.append("\n");
335                                 }
336                             }
337                         } else {
338                             result.append("  unexpected type for ");
339                             result.append(buffer);
340                             result.append("\n");
341                         }
342                     }
343                 }
344             }
345             closedir(d);
346         } else {
347             result.append("couldn't open ");
348             result.append(buffer);
349             result.append("\n");
350         }
351 
352         gLooperRoster.dump(fd, args);
353 
354         bool dumpMem = false;
355         bool unreachableMemory = false;
356         for (size_t i = 0; i < args.size(); i++) {
357             if (args[i] == String16("-m")) {
358                 dumpMem = true;
359             } else if (args[i] == String16("--unreachable")) {
360                 unreachableMemory = true;
361             }
362         }
363         if (dumpMem) {
364             result.append("\nDumping memory:\n");
365             std::string s = dumpMemoryAddresses(100 /* limit */);
366             result.append(s.c_str(), s.size());
367         }
368         if (unreachableMemory) {
369             result.append("\nDumping unreachable memory:\n");
370             // TODO - should limit be an argument parameter?
371             // TODO: enable GetUnreachableMemoryString if it's part of stable API
372             //std::string s = GetUnreachableMemoryString(true /* contents */, 10000 /* limit */);
373             //result.append(s.c_str(), s.size());
374         }
375     }
376     write(fd, result.string(), result.size());
377     return NO_ERROR;
378 }
379 
380 }  // anonymous namespace
381 
382 //static
Create()383 sp<MediaPlayer2> MediaPlayer2::Create() {
384     sp<MediaPlayer2> player = new MediaPlayer2();
385 
386     if (!player->init()) {
387         return NULL;
388     }
389 
390     ALOGV("Create new player(%p)", player.get());
391 
392     addPlayer(player);
393     return player;
394 }
395 
396 // static
DumpAll(int fd,const Vector<String16> & args)397 status_t MediaPlayer2::DumpAll(int fd, const Vector<String16>& args) {
398     return dumpPlayers(fd, args);
399 }
400 
MediaPlayer2()401 MediaPlayer2::MediaPlayer2() {
402     ALOGV("constructor");
403     mSrcId = 0;
404     mLockThreadId = 0;
405     mListener = NULL;
406     mStreamType = AUDIO_STREAM_MUSIC;
407     mAudioAttributesParcel = NULL;
408     mCurrentPosition = -1;
409     mCurrentSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
410     mSeekPosition = -1;
411     mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
412     mCurrentState = MEDIA_PLAYER2_IDLE;
413     mLoop = false;
414     mLeftVolume = mRightVolume = 1.0;
415     mVideoWidth = mVideoHeight = 0;
416     mAudioSessionId = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
417     AudioSystem::acquireAudioSessionId(mAudioSessionId, -1);
418     mSendLevel = 0;
419 
420     // TODO: get pid and uid from JAVA
421     mPid = IPCThreadState::self()->getCallingPid();
422     mUid = IPCThreadState::self()->getCallingUid();
423 
424     mAudioAttributes = NULL;
425 }
426 
~MediaPlayer2()427 MediaPlayer2::~MediaPlayer2() {
428     ALOGV("destructor");
429     if (mAudioAttributesParcel != NULL) {
430         delete mAudioAttributesParcel;
431         mAudioAttributesParcel = NULL;
432     }
433     AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
434     disconnect();
435     removePlayer(this);
436     if (mAudioAttributes != NULL) {
437         free(mAudioAttributes);
438     }
439 }
440 
init()441 bool MediaPlayer2::init() {
442     // TODO: after merge with NuPlayer2Driver, MediaPlayer2 will have its own
443     // looper for notification.
444     return true;
445 }
446 
disconnect()447 void MediaPlayer2::disconnect() {
448     ALOGV("disconnect");
449     sp<MediaPlayer2Interface> p;
450     {
451         Mutex::Autolock _l(mLock);
452         p = mPlayer;
453         mPlayer.clear();
454     }
455 
456     if (p != 0) {
457         p->setListener(NULL);
458         p->reset();
459     }
460 
461     {
462         Mutex::Autolock _l(mLock);
463         disconnectNativeWindow_l();
464     }
465 }
466 
clear_l()467 void MediaPlayer2::clear_l() {
468     mCurrentPosition = -1;
469     mCurrentSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
470     mSeekPosition = -1;
471     mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
472     mVideoWidth = mVideoHeight = 0;
473 }
474 
setListener(const sp<MediaPlayer2Listener> & listener)475 status_t MediaPlayer2::setListener(const sp<MediaPlayer2Listener>& listener) {
476     ALOGV("setListener");
477     Mutex::Autolock _l(mLock);
478     mListener = listener;
479     return NO_ERROR;
480 }
481 
getSrcId(int64_t * srcId)482 status_t MediaPlayer2::getSrcId(int64_t *srcId) {
483     if (srcId == NULL) {
484         return BAD_VALUE;
485     }
486 
487     Mutex::Autolock _l(mLock);
488     *srcId = mSrcId;
489     return OK;
490 }
491 
setDataSource(const sp<DataSourceDesc> & dsd)492 status_t MediaPlayer2::setDataSource(const sp<DataSourceDesc> &dsd) {
493     if (dsd == NULL) {
494         return BAD_VALUE;
495     }
496     ALOGV("setDataSource type(%d), srcId(%lld)", dsd->mType, (long long)dsd->mId);
497 
498     sp<MediaPlayer2Interface> oldPlayer;
499 
500     Mutex::Autolock _l(mLock);
501     {
502         if (!((mCurrentState & MEDIA_PLAYER2_IDLE)
503               || mCurrentState == MEDIA_PLAYER2_STATE_ERROR)) {
504             ALOGE("setDataSource called in wrong state %d", mCurrentState);
505             return INVALID_OPERATION;
506         }
507 
508         sp<MediaPlayer2Interface> player = new NuPlayer2Driver(mPid, mUid);
509         status_t err = player->initCheck();
510         if (err != NO_ERROR) {
511             ALOGE("Failed to create player object, initCheck failed(%d)", err);
512             return err;
513         }
514 
515         clear_l();
516 
517         player->setListener(new proxyListener(this));
518         mAudioOutput = new MediaPlayer2AudioOutput(mAudioSessionId, mUid,
519                 mPid, mAudioAttributes, new AudioDeviceUpdatedNotifier(player));
520         player->setAudioSink(mAudioOutput);
521 
522         err = player->setDataSource(dsd);
523         if (err != OK) {
524             ALOGE("setDataSource error: %d", err);
525             return err;
526         }
527 
528         sp<MediaPlayer2Interface> oldPlayer = mPlayer;
529         mPlayer = player;
530         mSrcId = dsd->mId;
531         mCurrentState = MEDIA_PLAYER2_INITIALIZED;
532     }
533 
534     if (oldPlayer != NULL) {
535         oldPlayer->setListener(NULL);
536         oldPlayer->reset();
537     }
538 
539     return OK;
540 }
541 
prepareNextDataSource(const sp<DataSourceDesc> & dsd)542 status_t MediaPlayer2::prepareNextDataSource(const sp<DataSourceDesc> &dsd) {
543     if (dsd == NULL) {
544         return BAD_VALUE;
545     }
546     ALOGV("prepareNextDataSource type(%d), srcId(%lld)", dsd->mType, (long long)dsd->mId);
547 
548     Mutex::Autolock _l(mLock);
549     if (mPlayer == NULL) {
550         ALOGE("prepareNextDataSource failed: state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
551         return INVALID_OPERATION;
552     }
553     return mPlayer->prepareNextDataSource(dsd);
554 }
555 
playNextDataSource(int64_t srcId)556 status_t MediaPlayer2::playNextDataSource(int64_t srcId) {
557     ALOGV("playNextDataSource srcId(%lld)", (long long)srcId);
558 
559     Mutex::Autolock _l(mLock);
560     if (mPlayer == NULL) {
561         ALOGE("playNextDataSource failed: state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
562         return INVALID_OPERATION;
563     }
564     mSrcId = srcId;
565     return mPlayer->playNextDataSource(srcId);
566 }
567 
invoke(const Parcel & request,Parcel * reply)568 status_t MediaPlayer2::invoke(const Parcel& request, Parcel *reply) {
569     Mutex::Autolock _l(mLock);
570     const bool hasBeenInitialized =
571             (mCurrentState != MEDIA_PLAYER2_STATE_ERROR) &&
572             ((mCurrentState & MEDIA_PLAYER2_IDLE) != MEDIA_PLAYER2_IDLE);
573     if ((mPlayer == NULL) || !hasBeenInitialized) {
574         ALOGE("invoke failed: wrong state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
575         return INVALID_OPERATION;
576     }
577     ALOGV("invoke %zu", request.dataSize());
578     return mPlayer->invoke(request, reply);
579 }
580 
581 // This call doesn't need to access the native player.
setMetadataFilter(const Parcel & filter)582 status_t MediaPlayer2::setMetadataFilter(const Parcel& filter) {
583     ALOGD("setMetadataFilter");
584 
585     status_t status;
586     media::Metadata::Filter allow, drop;
587 
588     if (unmarshallFilter(filter, &allow, &status) &&
589         unmarshallFilter(filter, &drop, &status)) {
590         Mutex::Autolock lock(mLock);
591 
592         mMetadataAllow = allow;
593         mMetadataDrop = drop;
594     }
595     return status;
596 }
597 
getMetadata(bool update_only,bool,Parcel * reply)598 status_t MediaPlayer2::getMetadata(bool update_only, bool /* apply_filter */, Parcel *reply) {
599     ALOGD("getMetadata");
600     sp<MediaPlayer2Interface> player;
601     media::Metadata::Filter ids;
602     Mutex::Autolock lock(mLock);
603     {
604         if (mPlayer == NULL) {
605             return NO_INIT;
606         }
607 
608         player = mPlayer;
609         // Placeholder for the return code, updated by the caller.
610         reply->writeInt32(-1);
611 
612         // We don't block notifications while we fetch the data. We clear
613         // mMetadataUpdated first so we don't lose notifications happening
614         // during the rest of this call.
615         if (update_only) {
616             ids = mMetadataUpdated;
617         }
618         mMetadataUpdated.clear();
619     }
620 
621     media::Metadata metadata(reply);
622 
623     metadata.appendHeader();
624     status_t status = player->getMetadata(ids, reply);
625 
626     if (status != OK) {
627         metadata.resetParcel();
628         ALOGE("getMetadata failed %d", status);
629         return status;
630     }
631 
632     // FIXME: ement filtering on the result. Not critical since
633     // filtering takes place on the update notifications already. This
634     // would be when all the metadata are fetch and a filter is set.
635 
636     // Everything is fine, update the metadata length.
637     metadata.updateLength();
638     return OK;
639 }
640 
disconnectNativeWindow_l()641 void MediaPlayer2::disconnectNativeWindow_l() {
642     if (mConnectedWindow != NULL && mConnectedWindow->getANativeWindow() != NULL) {
643         status_t err = native_window_api_disconnect(
644                 mConnectedWindow->getANativeWindow(), NATIVE_WINDOW_API_MEDIA);
645 
646         if (err != OK) {
647             ALOGW("nativeWindowDisconnect returned an error: %s (%d)",
648                   strerror(-err), err);
649         }
650     }
651     mConnectedWindow.clear();
652 }
653 
setVideoSurfaceTexture(const sp<ANativeWindowWrapper> & nww)654 status_t MediaPlayer2::setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww) {
655     ANativeWindow *anw = (nww == NULL ? NULL : nww->getANativeWindow());
656     ALOGV("setVideoSurfaceTexture(%p)", anw);
657     Mutex::Autolock _l(mLock);
658     if (mPlayer == 0) {
659         return NO_INIT;
660     }
661 
662     if (anw != NULL) {
663         if (mConnectedWindow != NULL
664             && mConnectedWindow->getANativeWindow() == anw) {
665             return OK;
666         }
667         status_t err = native_window_api_connect(anw, NATIVE_WINDOW_API_MEDIA);
668 
669         if (err != OK) {
670             ALOGE("setVideoSurfaceTexture failed: %d", err);
671             // Note that we must do the reset before disconnecting from the ANW.
672             // Otherwise queue/dequeue calls could be made on the disconnected
673             // ANW, which may result in errors.
674             mPlayer->reset();
675             disconnectNativeWindow_l();
676             return err;
677         }
678     }
679 
680     // Note that we must set the player's new GraphicBufferProducer before
681     // disconnecting the old one.  Otherwise queue/dequeue calls could be made
682     // on the disconnected ANW, which may result in errors.
683     status_t err = mPlayer->setVideoSurfaceTexture(nww);
684 
685     disconnectNativeWindow_l();
686 
687     if (err == OK) {
688         mConnectedWindow = nww;
689         mLock.unlock();
690     } else if (anw != NULL) {
691         mLock.unlock();
692         status_t err = native_window_api_disconnect(anw, NATIVE_WINDOW_API_MEDIA);
693 
694         if (err != OK) {
695             ALOGW("nativeWindowDisconnect returned an error: %s (%d)",
696                   strerror(-err), err);
697         }
698     }
699 
700     return err;
701 }
702 
getBufferingSettings(BufferingSettings * buffering)703 status_t MediaPlayer2::getBufferingSettings(BufferingSettings* buffering /* nonnull */) {
704     ALOGV("getBufferingSettings");
705 
706     Mutex::Autolock _l(mLock);
707     if (mPlayer == 0) {
708         return NO_INIT;
709     }
710 
711     status_t ret = mPlayer->getBufferingSettings(buffering);
712     if (ret == NO_ERROR) {
713         ALOGV("getBufferingSettings{%s}", buffering->toString().string());
714     } else {
715         ALOGE("getBufferingSettings returned %d", ret);
716     }
717     return ret;
718 }
719 
setBufferingSettings(const BufferingSettings & buffering)720 status_t MediaPlayer2::setBufferingSettings(const BufferingSettings& buffering) {
721     ALOGV("setBufferingSettings{%s}", buffering.toString().string());
722 
723     Mutex::Autolock _l(mLock);
724     if (mPlayer == 0) {
725         return NO_INIT;
726     }
727     return mPlayer->setBufferingSettings(buffering);
728 }
729 
setAudioAttributes_l(const Parcel & parcel)730 status_t MediaPlayer2::setAudioAttributes_l(const Parcel &parcel) {
731     if (mAudioAttributes != NULL) {
732         free(mAudioAttributes);
733     }
734     mAudioAttributes = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t));
735     if (mAudioAttributes == NULL) {
736         return NO_MEMORY;
737     }
738     unmarshallAudioAttributes(parcel, mAudioAttributes);
739 
740     ALOGV("setAudioAttributes_l() usage=%d content=%d flags=0x%x tags=%s",
741             mAudioAttributes->usage, mAudioAttributes->content_type, mAudioAttributes->flags,
742             mAudioAttributes->tags);
743 
744     if (mAudioOutput != 0) {
745         mAudioOutput->setAudioAttributes(mAudioAttributes);
746     }
747     return NO_ERROR;
748 }
749 
prepareAsync()750 status_t MediaPlayer2::prepareAsync() {
751     ALOGV("prepareAsync");
752     Mutex::Autolock _l(mLock);
753     if ((mPlayer != 0) && (mCurrentState & (MEDIA_PLAYER2_INITIALIZED | MEDIA_PLAYER2_STOPPED))) {
754         if (mAudioAttributesParcel != NULL) {
755             status_t err = setAudioAttributes_l(*mAudioAttributesParcel);
756             if (err != OK) {
757                 return err;
758             }
759         } else if (mAudioOutput != 0) {
760             mAudioOutput->setAudioStreamType(mStreamType);
761         }
762         mCurrentState = MEDIA_PLAYER2_PREPARING;
763         return mPlayer->prepareAsync();
764     }
765     ALOGE("prepareAsync called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
766     return INVALID_OPERATION;
767 }
768 
start()769 status_t MediaPlayer2::start() {
770     ALOGV("start");
771 
772     status_t ret = NO_ERROR;
773     Mutex::Autolock _l(mLock);
774 
775     mLockThreadId = getThreadId();
776 
777     if (mCurrentState & MEDIA_PLAYER2_STARTED) {
778         ret = NO_ERROR;
779     } else if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER2_PREPARED |
780                     MEDIA_PLAYER2_PLAYBACK_COMPLETE | MEDIA_PLAYER2_PAUSED ) ) ) {
781         mPlayer->setLooping(mLoop);
782 
783         if (mAudioOutput != 0) {
784             mAudioOutput->setVolume(mLeftVolume, mRightVolume);
785         }
786 
787         if (mAudioOutput != 0) {
788             mAudioOutput->setAuxEffectSendLevel(mSendLevel);
789         }
790         mCurrentState = MEDIA_PLAYER2_STARTED;
791         ret = mPlayer->start();
792         if (ret != NO_ERROR) {
793             mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
794         } else {
795             if (mCurrentState == MEDIA_PLAYER2_PLAYBACK_COMPLETE) {
796                 ALOGV("playback completed immediately following start()");
797             }
798         }
799     } else {
800         ALOGE("start called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
801         ret = INVALID_OPERATION;
802     }
803 
804     mLockThreadId = 0;
805 
806     return ret;
807 }
808 
stop()809 status_t MediaPlayer2::stop() {
810     ALOGV("stop");
811     Mutex::Autolock _l(mLock);
812     if (mCurrentState & MEDIA_PLAYER2_STOPPED) return NO_ERROR;
813     if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER2_STARTED | MEDIA_PLAYER2_PREPARED |
814                     MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE ) ) ) {
815         status_t ret = mPlayer->stop();
816         if (ret != NO_ERROR) {
817             mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
818         } else {
819             mCurrentState = MEDIA_PLAYER2_STOPPED;
820         }
821         return ret;
822     }
823     ALOGE("stop called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
824     return INVALID_OPERATION;
825 }
826 
pause()827 status_t MediaPlayer2::pause() {
828     ALOGV("pause");
829     Mutex::Autolock _l(mLock);
830     if (mCurrentState & (MEDIA_PLAYER2_PAUSED|MEDIA_PLAYER2_PLAYBACK_COMPLETE))
831         return NO_ERROR;
832     if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER2_STARTED)) {
833         status_t ret = mPlayer->pause();
834         if (ret != NO_ERROR) {
835             mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
836         } else {
837             mCurrentState = MEDIA_PLAYER2_PAUSED;
838         }
839         return ret;
840     }
841     ALOGE("pause called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
842     return INVALID_OPERATION;
843 }
844 
isPlaying()845 bool MediaPlayer2::isPlaying() {
846     Mutex::Autolock _l(mLock);
847     if (mPlayer != 0) {
848         bool temp = mPlayer->isPlaying();
849         ALOGV("isPlaying: %d", temp);
850         if ((mCurrentState & MEDIA_PLAYER2_STARTED) && ! temp) {
851             ALOGE("internal/external state mismatch corrected");
852             mCurrentState = MEDIA_PLAYER2_PAUSED;
853         } else if ((mCurrentState & MEDIA_PLAYER2_PAUSED) && temp) {
854             ALOGE("internal/external state mismatch corrected");
855             mCurrentState = MEDIA_PLAYER2_STARTED;
856         }
857         return temp;
858     }
859     ALOGV("isPlaying: no active player");
860     return false;
861 }
862 
getMediaPlayer2State()863 mediaplayer2_states MediaPlayer2::getMediaPlayer2State() {
864     Mutex::Autolock _l(mLock);
865     if (mCurrentState & MEDIA_PLAYER2_STATE_ERROR) {
866         return MEDIAPLAYER2_STATE_ERROR;
867     }
868     if (mPlayer == 0
869         || (mCurrentState &
870             (MEDIA_PLAYER2_IDLE | MEDIA_PLAYER2_INITIALIZED | MEDIA_PLAYER2_PREPARING))) {
871         return MEDIAPLAYER2_STATE_IDLE;
872     }
873     if (mCurrentState & MEDIA_PLAYER2_STARTED) {
874         return MEDIAPLAYER2_STATE_PLAYING;
875     }
876     if (mCurrentState
877         & (MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_STOPPED | MEDIA_PLAYER2_PLAYBACK_COMPLETE)) {
878         return MEDIAPLAYER2_STATE_PAUSED;
879     }
880     // now only mCurrentState & MEDIA_PLAYER2_PREPARED is true
881     return MEDIAPLAYER2_STATE_PREPARED;
882 }
883 
setPlaybackSettings(const AudioPlaybackRate & rate)884 status_t MediaPlayer2::setPlaybackSettings(const AudioPlaybackRate& rate) {
885     ALOGV("setPlaybackSettings: %f %f %d %d",
886             rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode);
887     // Negative speed and pitch does not make sense. Further validation will
888     // be done by the respective mediaplayers.
889     if (rate.mSpeed <= 0.f || rate.mPitch < 0.f) {
890         return BAD_VALUE;
891     }
892     Mutex::Autolock _l(mLock);
893     if (mPlayer == 0 || (mCurrentState & MEDIA_PLAYER2_STOPPED)) {
894         return INVALID_OPERATION;
895     }
896 
897     status_t err = mPlayer->setPlaybackSettings(rate);
898     return err;
899 }
900 
getPlaybackSettings(AudioPlaybackRate * rate)901 status_t MediaPlayer2::getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) {
902     Mutex::Autolock _l(mLock);
903     if (mPlayer == 0) {
904         return INVALID_OPERATION;
905     }
906     status_t ret = mPlayer->getPlaybackSettings(rate);
907     if (ret == NO_ERROR) {
908         ALOGV("getPlaybackSettings(%f, %f, %d, %d)",
909                 rate->mSpeed, rate->mPitch, rate->mFallbackMode, rate->mStretchMode);
910     } else {
911         ALOGV("getPlaybackSettings returned %d", ret);
912     }
913     return ret;
914 }
915 
setSyncSettings(const AVSyncSettings & sync,float videoFpsHint)916 status_t MediaPlayer2::setSyncSettings(const AVSyncSettings& sync, float videoFpsHint) {
917     ALOGV("setSyncSettings: %u %u %f %f",
918             sync.mSource, sync.mAudioAdjustMode, sync.mTolerance, videoFpsHint);
919     Mutex::Autolock _l(mLock);
920     if (mPlayer == 0) return INVALID_OPERATION;
921     return mPlayer->setSyncSettings(sync, videoFpsHint);
922 }
923 
getSyncSettings(AVSyncSettings * sync,float * videoFps)924 status_t MediaPlayer2::getSyncSettings(
925         AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) {
926     Mutex::Autolock _l(mLock);
927     if (mPlayer == 0) {
928         return INVALID_OPERATION;
929     }
930     status_t ret = mPlayer->getSyncSettings(sync, videoFps);
931     if (ret == NO_ERROR) {
932         ALOGV("getSyncSettings(%u, %u, %f, %f)",
933                 sync->mSource, sync->mAudioAdjustMode, sync->mTolerance, *videoFps);
934     } else {
935         ALOGV("getSyncSettings returned %d", ret);
936     }
937     return ret;
938 
939 }
940 
getVideoWidth(int * w)941 status_t MediaPlayer2::getVideoWidth(int *w) {
942     ALOGV("getVideoWidth");
943     Mutex::Autolock _l(mLock);
944     if (mPlayer == 0) {
945         return INVALID_OPERATION;
946     }
947     *w = mVideoWidth;
948     return NO_ERROR;
949 }
950 
getVideoHeight(int * h)951 status_t MediaPlayer2::getVideoHeight(int *h) {
952     ALOGV("getVideoHeight");
953     Mutex::Autolock _l(mLock);
954     if (mPlayer == 0) {
955         return INVALID_OPERATION;
956     }
957     *h = mVideoHeight;
958     return NO_ERROR;
959 }
960 
getCurrentPosition(int64_t * msec)961 status_t MediaPlayer2::getCurrentPosition(int64_t *msec) {
962     ALOGV("getCurrentPosition");
963     Mutex::Autolock _l(mLock);
964     if (mPlayer == 0) {
965         return INVALID_OPERATION;
966     }
967     if (mCurrentPosition >= 0) {
968         ALOGV("Using cached seek position: %lld", (long long)mCurrentPosition);
969         *msec = mCurrentPosition;
970         return NO_ERROR;
971     }
972     status_t ret = mPlayer->getCurrentPosition(msec);
973     if (ret == NO_ERROR) {
974         ALOGV("getCurrentPosition = %lld", (long long)*msec);
975     } else {
976         ALOGE("getCurrentPosition returned %d", ret);
977     }
978     return ret;
979 }
980 
getDuration(int64_t * msec)981 status_t MediaPlayer2::getDuration(int64_t *msec) {
982     Mutex::Autolock _l(mLock);
983     ALOGV("getDuration_l");
984     bool isValidState = (mCurrentState & (MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
985             MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_STOPPED | MEDIA_PLAYER2_PLAYBACK_COMPLETE));
986     if (mPlayer == 0 || !isValidState) {
987         ALOGE("Attempt to call getDuration in wrong state: mPlayer=%p, mCurrentState=%u",
988                 mPlayer.get(), mCurrentState);
989         return INVALID_OPERATION;
990     }
991     int64_t durationMs;
992     status_t ret = mPlayer->getDuration(&durationMs);
993 
994     if (ret == NO_ERROR) {
995         ALOGV("getDuration = %lld", (long long)durationMs);
996     } else {
997         ALOGE("getDuration returned %d", ret);
998         // Do not enter error state just because no duration was available.
999         durationMs = -1;
1000     }
1001 
1002     if (msec) {
1003         *msec = durationMs;
1004     }
1005     return OK;
1006 }
1007 
seekTo_l(int64_t msec,MediaPlayer2SeekMode mode)1008 status_t MediaPlayer2::seekTo_l(int64_t msec, MediaPlayer2SeekMode mode) {
1009     ALOGV("seekTo (%lld, %d)", (long long)msec, mode);
1010     if ((mPlayer == 0) || !(mCurrentState & (MEDIA_PLAYER2_STARTED | MEDIA_PLAYER2_PREPARED |
1011             MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE))) {
1012         ALOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u",
1013               mPlayer.get(), mCurrentState);
1014         return INVALID_OPERATION;
1015     }
1016     if (msec < 0) {
1017         ALOGW("Attempt to seek to invalid position: %lld", (long long)msec);
1018         msec = 0;
1019     }
1020 
1021     int64_t durationMs;
1022     status_t err = mPlayer->getDuration(&durationMs);
1023 
1024     if (err != OK) {
1025         ALOGW("Stream has no duration and is therefore not seekable.");
1026         return err;
1027     }
1028 
1029     if (msec > durationMs) {
1030         ALOGW("Attempt to seek to past end of file: request = %lld, durationMs = %lld",
1031               (long long)msec, (long long)durationMs);
1032 
1033         msec = durationMs;
1034     }
1035 
1036     // cache duration
1037     mCurrentPosition = msec;
1038     mCurrentSeekMode = mode;
1039     if (mSeekPosition < 0) {
1040         mSeekPosition = msec;
1041         mSeekMode = mode;
1042         return mPlayer->seekTo(msec, mode);
1043     }
1044     ALOGV("Seek in progress - queue up seekTo[%lld, %d]", (long long)msec, mode);
1045     return NO_ERROR;
1046 }
1047 
seekTo(int64_t msec,MediaPlayer2SeekMode mode)1048 status_t MediaPlayer2::seekTo(int64_t msec, MediaPlayer2SeekMode mode) {
1049     mLockThreadId = getThreadId();
1050     Mutex::Autolock _l(mLock);
1051     status_t result = seekTo_l(msec, mode);
1052     mLockThreadId = 0;
1053 
1054     return result;
1055 }
1056 
notifyAt(int64_t mediaTimeUs)1057 status_t MediaPlayer2::notifyAt(int64_t mediaTimeUs) {
1058     Mutex::Autolock _l(mLock);
1059     if (mPlayer != 0) {
1060         return INVALID_OPERATION;
1061     }
1062 
1063     return mPlayer->notifyAt(mediaTimeUs);
1064 }
1065 
reset_l()1066 status_t MediaPlayer2::reset_l() {
1067     mLoop = false;
1068     if (mCurrentState == MEDIA_PLAYER2_IDLE) {
1069         return NO_ERROR;
1070     }
1071     if (mPlayer != 0) {
1072         status_t ret = mPlayer->reset();
1073         if (ret != NO_ERROR) {
1074             ALOGE("reset() failed with return code (%d)", ret);
1075             mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
1076         } else {
1077             mPlayer->setListener(NULL);
1078             mCurrentState = MEDIA_PLAYER2_IDLE;
1079         }
1080         // setDataSource has to be called again to create a
1081         // new mediaplayer.
1082         mPlayer = 0;
1083         return ret;
1084     }
1085     clear_l();
1086     return NO_ERROR;
1087 }
1088 
reset()1089 status_t MediaPlayer2::reset() {
1090     ALOGV("reset");
1091     mLockThreadId = getThreadId();
1092     Mutex::Autolock _l(mLock);
1093     status_t result = reset_l();
1094     mLockThreadId = 0;
1095 
1096     return result;
1097 }
1098 
setAudioStreamType(audio_stream_type_t type)1099 status_t MediaPlayer2::setAudioStreamType(audio_stream_type_t type) {
1100     ALOGV("MediaPlayer2::setAudioStreamType");
1101     Mutex::Autolock _l(mLock);
1102     if (mStreamType == type) return NO_ERROR;
1103     if (mCurrentState & ( MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
1104                 MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE ) ) {
1105         // Can't change the stream type after prepare
1106         ALOGE("setAudioStream called in state %d", mCurrentState);
1107         return INVALID_OPERATION;
1108     }
1109     // cache
1110     mStreamType = type;
1111     return OK;
1112 }
1113 
getAudioStreamType(audio_stream_type_t * type)1114 status_t MediaPlayer2::getAudioStreamType(audio_stream_type_t *type) {
1115     ALOGV("getAudioStreamType");
1116     Mutex::Autolock _l(mLock);
1117     *type = mStreamType;
1118     return OK;
1119 }
1120 
setLooping(int loop)1121 status_t MediaPlayer2::setLooping(int loop) {
1122     ALOGV("MediaPlayer2::setLooping");
1123     Mutex::Autolock _l(mLock);
1124     mLoop = (loop != 0);
1125     if (mPlayer != 0) {
1126         return mPlayer->setLooping(loop);
1127     }
1128     return OK;
1129 }
1130 
isLooping()1131 bool MediaPlayer2::isLooping() {
1132     ALOGV("isLooping");
1133     Mutex::Autolock _l(mLock);
1134     if (mPlayer != 0) {
1135         return mLoop;
1136     }
1137     ALOGV("isLooping: no active player");
1138     return false;
1139 }
1140 
setVolume(float leftVolume,float rightVolume)1141 status_t MediaPlayer2::setVolume(float leftVolume, float rightVolume) {
1142     ALOGV("MediaPlayer2::setVolume(%f, %f)", leftVolume, rightVolume);
1143     Mutex::Autolock _l(mLock);
1144     mLeftVolume = leftVolume;
1145     mRightVolume = rightVolume;
1146     if (mAudioOutput != 0) {
1147         mAudioOutput->setVolume(leftVolume, rightVolume);
1148     }
1149     return OK;
1150 }
1151 
setAudioSessionId(audio_session_t sessionId)1152 status_t MediaPlayer2::setAudioSessionId(audio_session_t sessionId) {
1153     ALOGV("MediaPlayer2::setAudioSessionId(%d)", sessionId);
1154     Mutex::Autolock _l(mLock);
1155     if (!(mCurrentState & MEDIA_PLAYER2_IDLE)) {
1156         ALOGE("setAudioSessionId called in state %d", mCurrentState);
1157         return INVALID_OPERATION;
1158     }
1159     if (sessionId < 0) {
1160         return BAD_VALUE;
1161     }
1162     if (sessionId != mAudioSessionId) {
1163         AudioSystem::acquireAudioSessionId(sessionId, -1);
1164         AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
1165         mAudioSessionId = sessionId;
1166     }
1167     return NO_ERROR;
1168 }
1169 
getAudioSessionId()1170 audio_session_t MediaPlayer2::getAudioSessionId() {
1171     Mutex::Autolock _l(mLock);
1172     return mAudioSessionId;
1173 }
1174 
setAuxEffectSendLevel(float level)1175 status_t MediaPlayer2::setAuxEffectSendLevel(float level) {
1176     ALOGV("MediaPlayer2::setAuxEffectSendLevel(%f)", level);
1177     Mutex::Autolock _l(mLock);
1178     mSendLevel = level;
1179     if (mAudioOutput != 0) {
1180         return mAudioOutput->setAuxEffectSendLevel(level);
1181     }
1182     return OK;
1183 }
1184 
attachAuxEffect(int effectId)1185 status_t MediaPlayer2::attachAuxEffect(int effectId) {
1186     ALOGV("MediaPlayer2::attachAuxEffect(%d)", effectId);
1187     Mutex::Autolock _l(mLock);
1188     if (mAudioOutput == 0 ||
1189         (mCurrentState & MEDIA_PLAYER2_IDLE) ||
1190         (mCurrentState == MEDIA_PLAYER2_STATE_ERROR )) {
1191         ALOGE("attachAuxEffect called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
1192         return INVALID_OPERATION;
1193     }
1194 
1195     return mAudioOutput->attachAuxEffect(effectId);
1196 }
1197 
1198 // always call with lock held
checkStateForKeySet_l(int key)1199 status_t MediaPlayer2::checkStateForKeySet_l(int key) {
1200     switch(key) {
1201     case MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES:
1202         if (mCurrentState & ( MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
1203                 MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE) ) {
1204             // Can't change the audio attributes after prepare
1205             ALOGE("trying to set audio attributes called in state %d", mCurrentState);
1206             return INVALID_OPERATION;
1207         }
1208         break;
1209     default:
1210         // parameter doesn't require player state check
1211         break;
1212     }
1213     return OK;
1214 }
1215 
setParameter(int key,const Parcel & request)1216 status_t MediaPlayer2::setParameter(int key, const Parcel& request) {
1217     ALOGV("MediaPlayer2::setParameter(%d)", key);
1218     status_t status = INVALID_OPERATION;
1219     Mutex::Autolock _l(mLock);
1220     if (checkStateForKeySet_l(key) != OK) {
1221         return status;
1222     }
1223     switch (key) {
1224     case MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES:
1225         // save the marshalled audio attributes
1226         if (mAudioAttributesParcel != NULL) {
1227             delete mAudioAttributesParcel;
1228         }
1229         mAudioAttributesParcel = new Parcel();
1230         mAudioAttributesParcel->appendFrom(&request, 0, request.dataSize());
1231         status = setAudioAttributes_l(request);
1232         if (status != OK) {
1233             return status;
1234         }
1235         break;
1236     default:
1237         ALOGV_IF(mPlayer == NULL, "setParameter: no active player");
1238         break;
1239     }
1240 
1241     if (mPlayer != NULL) {
1242         status = mPlayer->setParameter(key, request);
1243     }
1244     return status;
1245 }
1246 
getParameter(int key,Parcel * reply)1247 status_t MediaPlayer2::getParameter(int key, Parcel *reply) {
1248     ALOGV("MediaPlayer2::getParameter(%d)", key);
1249     Mutex::Autolock _l(mLock);
1250     if (key == MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES) {
1251         if (reply == NULL) {
1252             return BAD_VALUE;
1253         }
1254         if (mAudioAttributesParcel != NULL) {
1255             reply->appendFrom(mAudioAttributesParcel, 0, mAudioAttributesParcel->dataSize());
1256         }
1257         return OK;
1258     }
1259 
1260     if (mPlayer == NULL) {
1261         ALOGV("getParameter: no active player");
1262         return INVALID_OPERATION;
1263     }
1264 
1265     status_t status =  mPlayer->getParameter(key, reply);
1266     if (status != OK) {
1267         ALOGD("getParameter returns %d", status);
1268     }
1269     return status;
1270 }
1271 
shouldDropMetadata(media::Metadata::Type code) const1272 bool MediaPlayer2::shouldDropMetadata(media::Metadata::Type code) const {
1273     Mutex::Autolock lock(mLock);
1274 
1275     if (findMetadata(mMetadataDrop, code)) {
1276         return true;
1277     }
1278 
1279     if (mMetadataAllow.isEmpty() || findMetadata(mMetadataAllow, code)) {
1280         return false;
1281     } else {
1282         return true;
1283     }
1284 }
1285 
1286 
addNewMetadataUpdate(media::Metadata::Type metadata_type)1287 void MediaPlayer2::addNewMetadataUpdate(media::Metadata::Type metadata_type) {
1288     Mutex::Autolock lock(mLock);
1289     if (mMetadataUpdated.indexOf(metadata_type) < 0) {
1290         mMetadataUpdated.add(metadata_type);
1291     }
1292 }
1293 
notify(int64_t srcId,int msg,int ext1,int ext2,const Parcel * obj)1294 void MediaPlayer2::notify(int64_t srcId, int msg, int ext1, int ext2, const Parcel *obj) {
1295     ALOGV("message received srcId=%lld, msg=%d, ext1=%d, ext2=%d",
1296           (long long)srcId, msg, ext1, ext2);
1297 
1298     if (MEDIA2_INFO == msg && MEDIA2_INFO_METADATA_UPDATE == ext1) {
1299         const media::Metadata::Type metadata_type = ext2;
1300 
1301         if(shouldDropMetadata(metadata_type)) {
1302             return;
1303         }
1304 
1305         // Update the list of metadata that have changed. getMetadata
1306         // also access mMetadataUpdated and clears it.
1307         addNewMetadataUpdate(metadata_type);
1308     }
1309 
1310     bool send = true;
1311     bool locked = false;
1312 
1313     // TODO: In the future, we might be on the same thread if the app is
1314     // running in the same process as the media server. In that case,
1315     // this will deadlock.
1316     //
1317     // The threadId hack below works around this for the care of prepare,
1318     // seekTo, start, and reset within the same process.
1319     // FIXME: Remember, this is a hack, it's not even a hack that is applied
1320     // consistently for all use-cases, this needs to be revisited.
1321     if (mLockThreadId != getThreadId()) {
1322         mLock.lock();
1323         locked = true;
1324     }
1325 
1326     // Allows calls from JNI in idle state to notify errors
1327     if (!(msg == MEDIA2_ERROR && mCurrentState == MEDIA_PLAYER2_IDLE) && mPlayer == 0) {
1328         ALOGV("notify(%lld, %d, %d, %d) callback on disconnected mediaplayer",
1329               (long long)srcId, msg, ext1, ext2);
1330         if (locked) mLock.unlock();   // release the lock when done.
1331         return;
1332     }
1333 
1334     switch (msg) {
1335     case MEDIA2_NOP: // interface test message
1336         break;
1337     case MEDIA2_PREPARED:
1338         ALOGV("MediaPlayer2::notify() prepared");
1339         mCurrentState = MEDIA_PLAYER2_PREPARED;
1340         break;
1341     case MEDIA2_DRM_INFO:
1342         ALOGV("MediaPlayer2::notify() MEDIA2_DRM_INFO(%lld, %d, %d, %d, %p)",
1343               (long long)srcId, msg, ext1, ext2, obj);
1344         break;
1345     case MEDIA2_PLAYBACK_COMPLETE:
1346         ALOGV("playback complete");
1347         if (mCurrentState == MEDIA_PLAYER2_IDLE) {
1348             ALOGE("playback complete in idle state");
1349         }
1350         if (!mLoop) {
1351             mCurrentState = MEDIA_PLAYER2_PLAYBACK_COMPLETE;
1352         }
1353         break;
1354     case MEDIA2_ERROR:
1355         // Always log errors.
1356         // ext1: Media framework error code.
1357         // ext2: Implementation dependant error code.
1358         ALOGE("error (%d, %d)", ext1, ext2);
1359         mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
1360         break;
1361     case MEDIA2_INFO:
1362         // ext1: Media framework error code.
1363         // ext2: Implementation dependant error code.
1364         if (ext1 != MEDIA2_INFO_VIDEO_TRACK_LAGGING) {
1365             ALOGW("info/warning (%d, %d)", ext1, ext2);
1366         }
1367         break;
1368     case MEDIA2_SEEK_COMPLETE:
1369         ALOGV("Received seek complete");
1370         if (mSeekPosition != mCurrentPosition || (mSeekMode != mCurrentSeekMode)) {
1371             ALOGV("Executing queued seekTo(%lld, %d)",
1372                   (long long)mCurrentPosition, mCurrentSeekMode);
1373             mSeekPosition = -1;
1374             mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
1375             seekTo_l(mCurrentPosition, mCurrentSeekMode);
1376         }
1377         else {
1378             ALOGV("All seeks complete - return to regularly scheduled program");
1379             mCurrentPosition = mSeekPosition = -1;
1380             mCurrentSeekMode = mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
1381         }
1382         break;
1383     case MEDIA2_BUFFERING_UPDATE:
1384         ALOGV("buffering %d", ext1);
1385         break;
1386     case MEDIA2_SET_VIDEO_SIZE:
1387         ALOGV("New video size %d x %d", ext1, ext2);
1388         mVideoWidth = ext1;
1389         mVideoHeight = ext2;
1390         break;
1391     case MEDIA2_NOTIFY_TIME:
1392         ALOGV("Received notify time message");
1393         break;
1394     case MEDIA2_TIMED_TEXT:
1395         ALOGV("Received timed text message");
1396         break;
1397     case MEDIA2_SUBTITLE_DATA:
1398         ALOGV("Received subtitle data message");
1399         break;
1400     case MEDIA2_META_DATA:
1401         ALOGV("Received timed metadata message");
1402         break;
1403     default:
1404         ALOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2);
1405         break;
1406     }
1407 
1408     sp<MediaPlayer2Listener> listener = mListener;
1409     if (locked) mLock.unlock();
1410 
1411     // this prevents re-entrant calls into client code
1412     if ((listener != 0) && send) {
1413         Mutex::Autolock _l(mNotifyLock);
1414         ALOGV("callback application");
1415         listener->notify(srcId, msg, ext1, ext2, obj);
1416         ALOGV("back from callback");
1417     }
1418 }
1419 
1420 // Modular DRM
prepareDrm(const uint8_t uuid[16],const Vector<uint8_t> & drmSessionId)1421 status_t MediaPlayer2::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId) {
1422     // TODO change to ALOGV
1423     ALOGD("prepareDrm: uuid: %p  drmSessionId: %p(%zu)", uuid,
1424             drmSessionId.array(), drmSessionId.size());
1425     Mutex::Autolock _l(mLock);
1426     if (mPlayer == NULL) {
1427         return NO_INIT;
1428     }
1429 
1430     // Only allowed it in player's preparing/prepared state.
1431     // We get here only if MEDIA_DRM_INFO has already arrived (e.g., prepare is half-way through or
1432     // completed) so the state change to "prepared" might not have happened yet (e.g., buffering).
1433     // Still, we can allow prepareDrm for the use case of being called in OnDrmInfoListener.
1434     if (!(mCurrentState & (MEDIA_PLAYER2_PREPARING | MEDIA_PLAYER2_PREPARED))) {
1435         ALOGE("prepareDrm is called in the wrong state (%d).", mCurrentState);
1436         return INVALID_OPERATION;
1437     }
1438 
1439     if (drmSessionId.isEmpty()) {
1440         ALOGE("prepareDrm: Unexpected. Can't proceed with crypto. Empty drmSessionId.");
1441         return INVALID_OPERATION;
1442     }
1443 
1444     // Passing down to mediaserver mainly for creating the crypto
1445     status_t status = mPlayer->prepareDrm(uuid, drmSessionId);
1446     ALOGE_IF(status != OK, "prepareDrm: Failed at mediaserver with ret: %d", status);
1447 
1448     // TODO change to ALOGV
1449     ALOGD("prepareDrm: mediaserver::prepareDrm ret=%d", status);
1450 
1451     return status;
1452 }
1453 
releaseDrm()1454 status_t MediaPlayer2::releaseDrm() {
1455     Mutex::Autolock _l(mLock);
1456     if (mPlayer == NULL) {
1457         return NO_INIT;
1458     }
1459 
1460     // Not allowing releaseDrm in an active/resumable state
1461     if (mCurrentState & (MEDIA_PLAYER2_STARTED |
1462                          MEDIA_PLAYER2_PAUSED |
1463                          MEDIA_PLAYER2_PLAYBACK_COMPLETE |
1464                          MEDIA_PLAYER2_STATE_ERROR)) {
1465         ALOGE("releaseDrm Unexpected state %d. Can only be called in stopped/idle.", mCurrentState);
1466         return INVALID_OPERATION;
1467     }
1468 
1469     status_t status = mPlayer->releaseDrm();
1470     // TODO change to ALOGV
1471     ALOGD("releaseDrm: mediaserver::releaseDrm ret: %d", status);
1472     if (status != OK) {
1473         ALOGE("releaseDrm: Failed at mediaserver with ret: %d", status);
1474         // Overriding to OK so the client proceed with its own cleanup
1475         // Client can't do more cleanup. mediaserver release its crypto at end of session anyway.
1476         status = OK;
1477     }
1478 
1479     return status;
1480 }
1481 
setOutputDevice(audio_port_handle_t deviceId)1482 status_t MediaPlayer2::setOutputDevice(audio_port_handle_t deviceId) {
1483     Mutex::Autolock _l(mLock);
1484     if (mAudioOutput == NULL) {
1485         ALOGV("setOutputDevice: audio sink not init");
1486         return NO_INIT;
1487     }
1488     return mAudioOutput->setOutputDevice(deviceId);
1489 }
1490 
getRoutedDeviceId()1491 audio_port_handle_t MediaPlayer2::getRoutedDeviceId() {
1492     Mutex::Autolock _l(mLock);
1493     if (mAudioOutput == NULL) {
1494         ALOGV("getRoutedDeviceId: audio sink not init");
1495         return AUDIO_PORT_HANDLE_NONE;
1496     }
1497     audio_port_handle_t deviceId;
1498     status_t status = mAudioOutput->getRoutedDeviceId(&deviceId);
1499     if (status != NO_ERROR) {
1500         return AUDIO_PORT_HANDLE_NONE;
1501     }
1502     return deviceId;
1503 }
1504 
enableAudioDeviceCallback(bool enabled)1505 status_t MediaPlayer2::enableAudioDeviceCallback(bool enabled) {
1506     Mutex::Autolock _l(mLock);
1507     if (mAudioOutput == NULL) {
1508         ALOGV("addAudioDeviceCallback: player not init");
1509         return NO_INIT;
1510     }
1511     return mAudioOutput->enableAudioDeviceCallback(enabled);
1512 }
1513 
dump(int fd,const Vector<String16> & args)1514 status_t MediaPlayer2::dump(int fd, const Vector<String16>& args) {
1515     const size_t SIZE = 256;
1516     char buffer[SIZE];
1517     String8 result;
1518     result.append(" MediaPlayer2\n");
1519     snprintf(buffer, 255, "  pid(%d), looping(%s)\n", mPid, mLoop?"true": "false");
1520     result.append(buffer);
1521 
1522     sp<MediaPlayer2Interface> player;
1523     sp<MediaPlayer2AudioOutput> audioOutput;
1524     bool locked = false;
1525     for (int i = 0; i < kDumpLockRetries; ++i) {
1526         if (mLock.tryLock() == NO_ERROR) {
1527             locked = true;
1528             break;
1529         }
1530         usleep(kDumpLockSleepUs);
1531     }
1532 
1533     if (locked) {
1534         player = mPlayer;
1535         audioOutput = mAudioOutput;
1536         mLock.unlock();
1537     } else {
1538         result.append("  lock is taken, no dump from player and audio output\n");
1539     }
1540     write(fd, result.string(), result.size());
1541 
1542     if (player != NULL) {
1543         player->dump(fd, args);
1544     }
1545     if (audioOutput != 0) {
1546         audioOutput->dump(fd, args);
1547     }
1548     write(fd, "\n", 1);
1549     return NO_ERROR;
1550 }
1551 
1552 } // namespace android
1553