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