MediaPlayerService.cpp revision 9ee159b79022b2e1a050acb3890ce948e99e9ccb
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 <android_runtime/ActivityManager.h>
38
39#include <binder/IPCThreadState.h>
40#include <binder/IServiceManager.h>
41#include <binder/MemoryHeapBase.h>
42#include <binder/MemoryBase.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#include <cutils/properties.h>
48
49#include <media/MediaPlayerInterface.h>
50#include <media/mediarecorder.h>
51#include <media/MediaMetadataRetrieverInterface.h>
52#include <media/Metadata.h>
53#include <media/AudioTrack.h>
54
55#include <private/android_filesystem_config.h>
56
57#include "MediaRecorderClient.h"
58#include "MediaPlayerService.h"
59#include "MetadataRetrieverClient.h"
60
61#include "MidiFile.h"
62#include "TestPlayerStub.h"
63#include "StagefrightPlayer.h"
64#include "nuplayer/NuPlayerDriver.h"
65
66#include <OMX.h>
67
68/* desktop Linux needs a little help with gettid() */
69#if defined(HAVE_GETTID) && !defined(HAVE_ANDROID_OS)
70#define __KERNEL__
71# include <linux/unistd.h>
72#ifdef _syscall0
73_syscall0(pid_t,gettid)
74#else
75pid_t gettid() { return syscall(__NR_gettid);}
76#endif
77#undef __KERNEL__
78#endif
79
80namespace {
81using android::media::Metadata;
82using android::status_t;
83using android::OK;
84using android::BAD_VALUE;
85using android::NOT_ENOUGH_DATA;
86using android::Parcel;
87
88// Max number of entries in the filter.
89const int kMaxFilterSize = 64;  // I pulled that out of thin air.
90
91// FIXME: Move all the metadata related function in the Metadata.cpp
92
93
94// Unmarshall a filter from a Parcel.
95// Filter format in a parcel:
96//
97//  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
98// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
99// |                       number of entries (n)                   |
100// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
101// |                       metadata type 1                         |
102// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
103// |                       metadata type 2                         |
104// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
105//  ....
106// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
107// |                       metadata type n                         |
108// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
109//
110// @param p Parcel that should start with a filter.
111// @param[out] filter On exit contains the list of metadata type to be
112//                    filtered.
113// @param[out] status On exit contains the status code to be returned.
114// @return true if the parcel starts with a valid filter.
115bool unmarshallFilter(const Parcel& p,
116                      Metadata::Filter *filter,
117                      status_t *status)
118{
119    int32_t val;
120    if (p.readInt32(&val) != OK)
121    {
122        LOGE("Failed to read filter's length");
123        *status = NOT_ENOUGH_DATA;
124        return false;
125    }
126
127    if( val > kMaxFilterSize || val < 0)
128    {
129        LOGE("Invalid filter len %d", val);
130        *status = BAD_VALUE;
131        return false;
132    }
133
134    const size_t num = val;
135
136    filter->clear();
137    filter->setCapacity(num);
138
139    size_t size = num * sizeof(Metadata::Type);
140
141
142    if (p.dataAvail() < size)
143    {
144        LOGE("Filter too short expected %d but got %d", size, p.dataAvail());
145        *status = NOT_ENOUGH_DATA;
146        return false;
147    }
148
149    const Metadata::Type *data =
150            static_cast<const Metadata::Type*>(p.readInplace(size));
151
152    if (NULL == data)
153    {
154        LOGE("Filter had no data");
155        *status = BAD_VALUE;
156        return false;
157    }
158
159    // TODO: The stl impl of vector would be more efficient here
160    // because it degenerates into a memcpy on pod types. Try to
161    // replace later or use stl::set.
162    for (size_t i = 0; i < num; ++i)
163    {
164        filter->add(*data);
165        ++data;
166    }
167    *status = OK;
168    return true;
169}
170
171// @param filter Of metadata type.
172// @param val To be searched.
173// @return true if a match was found.
174bool findMetadata(const Metadata::Filter& filter, const int32_t val)
175{
176    // Deal with empty and ANY right away
177    if (filter.isEmpty()) return false;
178    if (filter[0] == Metadata::kAny) return true;
179
180    return filter.indexOf(val) >= 0;
181}
182
183}  // anonymous namespace
184
185
186namespace android {
187
188// TODO: Temp hack until we can register players
189typedef struct {
190    const char *extension;
191    const player_type playertype;
192} extmap;
193extmap FILE_EXTS [] =  {
194        {".mid", SONIVOX_PLAYER},
195        {".midi", SONIVOX_PLAYER},
196        {".smf", SONIVOX_PLAYER},
197        {".xmf", SONIVOX_PLAYER},
198        {".imy", SONIVOX_PLAYER},
199        {".rtttl", SONIVOX_PLAYER},
200        {".rtx", SONIVOX_PLAYER},
201        {".ota", SONIVOX_PLAYER},
202};
203
204// TODO: Find real cause of Audio/Video delay in PV framework and remove this workaround
205/* static */ int MediaPlayerService::AudioOutput::mMinBufferCount = 4;
206/* static */ bool MediaPlayerService::AudioOutput::mIsOnEmulator = false;
207
208void MediaPlayerService::instantiate() {
209    defaultServiceManager()->addService(
210            String16("media.player"), new MediaPlayerService());
211}
212
213MediaPlayerService::MediaPlayerService()
214{
215    LOGV("MediaPlayerService created");
216    mNextConnId = 1;
217
218    mBatteryAudio.refCount = 0;
219    for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
220        mBatteryAudio.deviceOn[i] = 0;
221        mBatteryAudio.lastTime[i] = 0;
222        mBatteryAudio.totalTime[i] = 0;
223    }
224    // speaker is on by default
225    mBatteryAudio.deviceOn[SPEAKER] = 1;
226}
227
228MediaPlayerService::~MediaPlayerService()
229{
230    LOGV("MediaPlayerService destroyed");
231}
232
233sp<IMediaRecorder> MediaPlayerService::createMediaRecorder(pid_t pid)
234{
235    sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid);
236    wp<MediaRecorderClient> w = recorder;
237    Mutex::Autolock lock(mLock);
238    mMediaRecorderClients.add(w);
239    LOGV("Create new media recorder client from pid %d", pid);
240    return recorder;
241}
242
243void MediaPlayerService::removeMediaRecorderClient(wp<MediaRecorderClient> client)
244{
245    Mutex::Autolock lock(mLock);
246    mMediaRecorderClients.remove(client);
247    LOGV("Delete media recorder client");
248}
249
250sp<IMediaMetadataRetriever> MediaPlayerService::createMetadataRetriever(pid_t pid)
251{
252    sp<MetadataRetrieverClient> retriever = new MetadataRetrieverClient(pid);
253    LOGV("Create new media retriever from pid %d", pid);
254    return retriever;
255}
256
257sp<IMediaPlayer> MediaPlayerService::create(
258        pid_t pid, const sp<IMediaPlayerClient>& client, const char* url,
259        const KeyedVector<String8, String8> *headers, int audioSessionId)
260{
261    int32_t connId = android_atomic_inc(&mNextConnId);
262    sp<Client> c = new Client(this, pid, connId, client, audioSessionId);
263    LOGV("Create new client(%d) from pid %d, url=%s, connId=%d, audioSessionId=%d",
264            connId, pid, url, connId, audioSessionId);
265    if (NO_ERROR != c->setDataSource(url, headers))
266    {
267        c.clear();
268        return c;
269    }
270    wp<Client> w = c;
271    Mutex::Autolock lock(mLock);
272    mClients.add(w);
273    return c;
274}
275
276sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client,
277        int fd, int64_t offset, int64_t length, int audioSessionId)
278{
279    int32_t connId = android_atomic_inc(&mNextConnId);
280    sp<Client> c = new Client(this, pid, connId, client, audioSessionId);
281    LOGV("Create new client(%d) from pid %d, fd=%d, offset=%lld, length=%lld, audioSessionId=%d",
282            connId, pid, fd, offset, length, audioSessionId);
283    if (NO_ERROR != c->setDataSource(fd, offset, length)) {
284        c.clear();
285    } else {
286        wp<Client> w = c;
287        Mutex::Autolock lock(mLock);
288        mClients.add(w);
289    }
290    ::close(fd);
291    return c;
292}
293
294sp<IMediaPlayer> MediaPlayerService::create(
295        pid_t pid, const sp<IMediaPlayerClient> &client,
296        const sp<IStreamSource> &source, int audioSessionId) {
297    int32_t connId = android_atomic_inc(&mNextConnId);
298    sp<Client> c = new Client(this, pid, connId, client, audioSessionId);
299
300    LOGV("Create new client(%d) from pid %d, audioSessionId=%d",
301         connId, pid, audioSessionId);
302
303    if (OK != c->setDataSource(source)) {
304        c.clear();
305    } else {
306        wp<Client> w = c;
307        Mutex::Autolock lock(mLock);
308        mClients.add(w);
309    }
310
311    return c;
312}
313
314sp<IOMX> MediaPlayerService::getOMX() {
315    Mutex::Autolock autoLock(mLock);
316
317    if (mOMX.get() == NULL) {
318        mOMX = new OMX;
319    }
320
321    return mOMX;
322}
323
324status_t MediaPlayerService::AudioCache::dump(int fd, const Vector<String16>& args) const
325{
326    const size_t SIZE = 256;
327    char buffer[SIZE];
328    String8 result;
329
330    result.append(" AudioCache\n");
331    if (mHeap != 0) {
332        snprintf(buffer, 255, "  heap base(%p), size(%d), flags(%d), device(%s)\n",
333                mHeap->getBase(), mHeap->getSize(), mHeap->getFlags(), mHeap->getDevice());
334        result.append(buffer);
335    }
336    snprintf(buffer, 255, "  msec per frame(%f), channel count(%d), format(%d), frame count(%ld)\n",
337            mMsecsPerFrame, mChannelCount, mFormat, mFrameCount);
338    result.append(buffer);
339    snprintf(buffer, 255, "  sample rate(%d), size(%d), error(%d), command complete(%s)\n",
340            mSampleRate, mSize, mError, mCommandComplete?"true":"false");
341    result.append(buffer);
342    ::write(fd, result.string(), result.size());
343    return NO_ERROR;
344}
345
346status_t MediaPlayerService::AudioOutput::dump(int fd, const Vector<String16>& args) const
347{
348    const size_t SIZE = 256;
349    char buffer[SIZE];
350    String8 result;
351
352    result.append(" AudioOutput\n");
353    snprintf(buffer, 255, "  stream type(%d), left - right volume(%f, %f)\n",
354            mStreamType, mLeftVolume, mRightVolume);
355    result.append(buffer);
356    snprintf(buffer, 255, "  msec per frame(%f), latency (%d)\n",
357            mMsecsPerFrame, mLatency);
358    result.append(buffer);
359    snprintf(buffer, 255, "  aux effect id(%d), send level (%f)\n",
360            mAuxEffectId, mSendLevel);
361    result.append(buffer);
362
363    ::write(fd, result.string(), result.size());
364    if (mTrack != 0) {
365        mTrack->dump(fd, args);
366    }
367    return NO_ERROR;
368}
369
370status_t MediaPlayerService::Client::dump(int fd, const Vector<String16>& args) const
371{
372    const size_t SIZE = 256;
373    char buffer[SIZE];
374    String8 result;
375    result.append(" Client\n");
376    snprintf(buffer, 255, "  pid(%d), connId(%d), status(%d), looping(%s)\n",
377            mPid, mConnId, mStatus, mLoop?"true": "false");
378    result.append(buffer);
379    write(fd, result.string(), result.size());
380    if (mAudioOutput != 0) {
381        mAudioOutput->dump(fd, args);
382    }
383    write(fd, "\n", 1);
384    return NO_ERROR;
385}
386
387static int myTid() {
388#ifdef HAVE_GETTID
389    return gettid();
390#else
391    return getpid();
392#endif
393}
394
395#if defined(__arm__)
396extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize,
397        size_t* infoSize, size_t* totalMemory, size_t* backtraceSize);
398extern "C" void free_malloc_leak_info(uint8_t* info);
399
400// Use the String-class below instead of String8 to allocate all memory
401// beforehand and not reenter the heap while we are examining it...
402struct MyString8 {
403    static const size_t MAX_SIZE = 256 * 1024;
404
405    MyString8()
406        : mPtr((char *)malloc(MAX_SIZE)) {
407        *mPtr = '\0';
408    }
409
410    ~MyString8() {
411        free(mPtr);
412    }
413
414    void append(const char *s) {
415        strcat(mPtr, s);
416    }
417
418    const char *string() const {
419        return mPtr;
420    }
421
422    size_t size() const {
423        return strlen(mPtr);
424    }
425
426private:
427    char *mPtr;
428
429    MyString8(const MyString8 &);
430    MyString8 &operator=(const MyString8 &);
431};
432
433void memStatus(int fd, const Vector<String16>& args)
434{
435    const size_t SIZE = 256;
436    char buffer[SIZE];
437    MyString8 result;
438
439    typedef struct {
440        size_t size;
441        size_t dups;
442        intptr_t * backtrace;
443    } AllocEntry;
444
445    uint8_t *info = NULL;
446    size_t overallSize = 0;
447    size_t infoSize = 0;
448    size_t totalMemory = 0;
449    size_t backtraceSize = 0;
450
451    get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, &backtraceSize);
452    if (info) {
453        uint8_t *ptr = info;
454        size_t count = overallSize / infoSize;
455
456        snprintf(buffer, SIZE, " Allocation count %i\n", count);
457        result.append(buffer);
458        snprintf(buffer, SIZE, " Total memory %i\n", totalMemory);
459        result.append(buffer);
460
461        AllocEntry * entries = new AllocEntry[count];
462
463        for (size_t i = 0; i < count; i++) {
464            // Each entry should be size_t, size_t, intptr_t[backtraceSize]
465            AllocEntry *e = &entries[i];
466
467            e->size = *reinterpret_cast<size_t *>(ptr);
468            ptr += sizeof(size_t);
469
470            e->dups = *reinterpret_cast<size_t *>(ptr);
471            ptr += sizeof(size_t);
472
473            e->backtrace = reinterpret_cast<intptr_t *>(ptr);
474            ptr += sizeof(intptr_t) * backtraceSize;
475        }
476
477        // Now we need to sort the entries.  They come sorted by size but
478        // not by stack trace which causes problems using diff.
479        bool moved;
480        do {
481            moved = false;
482            for (size_t i = 0; i < (count - 1); i++) {
483                AllocEntry *e1 = &entries[i];
484                AllocEntry *e2 = &entries[i+1];
485
486                bool swap = e1->size < e2->size;
487                if (e1->size == e2->size) {
488                    for(size_t j = 0; j < backtraceSize; j++) {
489                        if (e1->backtrace[j] == e2->backtrace[j]) {
490                            continue;
491                        }
492                        swap = e1->backtrace[j] < e2->backtrace[j];
493                        break;
494                    }
495                }
496                if (swap) {
497                    AllocEntry t = entries[i];
498                    entries[i] = entries[i+1];
499                    entries[i+1] = t;
500                    moved = true;
501                }
502            }
503        } while (moved);
504
505        for (size_t i = 0; i < count; i++) {
506            AllocEntry *e = &entries[i];
507
508            snprintf(buffer, SIZE, "size %8i, dup %4i, ", e->size, e->dups);
509            result.append(buffer);
510            for (size_t ct = 0; (ct < backtraceSize) && e->backtrace[ct]; ct++) {
511                if (ct) {
512                    result.append(", ");
513                }
514                snprintf(buffer, SIZE, "0x%08x", e->backtrace[ct]);
515                result.append(buffer);
516            }
517            result.append("\n");
518        }
519
520        delete[] entries;
521        free_malloc_leak_info(info);
522    }
523
524    write(fd, result.string(), result.size());
525}
526#endif
527
528status_t MediaPlayerService::dump(int fd, const Vector<String16>& args)
529{
530    const size_t SIZE = 256;
531    char buffer[SIZE];
532    String8 result;
533    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
534        snprintf(buffer, SIZE, "Permission Denial: "
535                "can't dump MediaPlayerService from pid=%d, uid=%d\n",
536                IPCThreadState::self()->getCallingPid(),
537                IPCThreadState::self()->getCallingUid());
538        result.append(buffer);
539    } else {
540        Mutex::Autolock lock(mLock);
541        for (int i = 0, n = mClients.size(); i < n; ++i) {
542            sp<Client> c = mClients[i].promote();
543            if (c != 0) c->dump(fd, args);
544        }
545        if (mMediaRecorderClients.size() == 0) {
546                result.append(" No media recorder client\n\n");
547        } else {
548            for (int i = 0, n = mMediaRecorderClients.size(); i < n; ++i) {
549                sp<MediaRecorderClient> c = mMediaRecorderClients[i].promote();
550                snprintf(buffer, 255, " MediaRecorderClient pid(%d)\n", c->mPid);
551                result.append(buffer);
552                write(fd, result.string(), result.size());
553                result = "\n";
554                c->dump(fd, args);
555            }
556        }
557
558        result.append(" Files opened and/or mapped:\n");
559        snprintf(buffer, SIZE, "/proc/%d/maps", myTid());
560        FILE *f = fopen(buffer, "r");
561        if (f) {
562            while (!feof(f)) {
563                fgets(buffer, SIZE, f);
564                if (strstr(buffer, " /mnt/sdcard/") ||
565                    strstr(buffer, " /system/sounds/") ||
566                    strstr(buffer, " /data/") ||
567                    strstr(buffer, " /system/media/")) {
568                    result.append("  ");
569                    result.append(buffer);
570                }
571            }
572            fclose(f);
573        } else {
574            result.append("couldn't open ");
575            result.append(buffer);
576            result.append("\n");
577        }
578
579        snprintf(buffer, SIZE, "/proc/%d/fd", myTid());
580        DIR *d = opendir(buffer);
581        if (d) {
582            struct dirent *ent;
583            while((ent = readdir(d)) != NULL) {
584                if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) {
585                    snprintf(buffer, SIZE, "/proc/%d/fd/%s", myTid(), ent->d_name);
586                    struct stat s;
587                    if (lstat(buffer, &s) == 0) {
588                        if ((s.st_mode & S_IFMT) == S_IFLNK) {
589                            char linkto[256];
590                            int len = readlink(buffer, linkto, sizeof(linkto));
591                            if(len > 0) {
592                                if(len > 255) {
593                                    linkto[252] = '.';
594                                    linkto[253] = '.';
595                                    linkto[254] = '.';
596                                    linkto[255] = 0;
597                                } else {
598                                    linkto[len] = 0;
599                                }
600                                if (strstr(linkto, "/mnt/sdcard/") == linkto ||
601                                    strstr(linkto, "/system/sounds/") == linkto ||
602                                    strstr(linkto, "/data/") == linkto ||
603                                    strstr(linkto, "/system/media/") == linkto) {
604                                    result.append("  ");
605                                    result.append(buffer);
606                                    result.append(" -> ");
607                                    result.append(linkto);
608                                    result.append("\n");
609                                }
610                            }
611                        } else {
612                            result.append("  unexpected type for ");
613                            result.append(buffer);
614                            result.append("\n");
615                        }
616                    }
617                }
618            }
619            closedir(d);
620        } else {
621            result.append("couldn't open ");
622            result.append(buffer);
623            result.append("\n");
624        }
625
626#if defined(__arm__)
627        bool dumpMem = false;
628        for (size_t i = 0; i < args.size(); i++) {
629            if (args[i] == String16("-m")) {
630                dumpMem = true;
631            }
632        }
633        if (dumpMem) {
634            memStatus(fd, args);
635        }
636#endif
637    }
638    write(fd, result.string(), result.size());
639    return NO_ERROR;
640}
641
642void MediaPlayerService::removeClient(wp<Client> client)
643{
644    Mutex::Autolock lock(mLock);
645    mClients.remove(client);
646}
647
648MediaPlayerService::Client::Client(const sp<MediaPlayerService>& service, pid_t pid,
649        int32_t connId, const sp<IMediaPlayerClient>& client, int audioSessionId)
650{
651    LOGV("Client(%d) constructor", connId);
652    mPid = pid;
653    mConnId = connId;
654    mService = service;
655    mClient = client;
656    mLoop = false;
657    mStatus = NO_INIT;
658    mAudioSessionId = audioSessionId;
659
660#if CALLBACK_ANTAGONIZER
661    LOGD("create Antagonizer");
662    mAntagonizer = new Antagonizer(notify, this);
663#endif
664}
665
666MediaPlayerService::Client::~Client()
667{
668    LOGV("Client(%d) destructor pid = %d", mConnId, mPid);
669    mAudioOutput.clear();
670    wp<Client> client(this);
671    disconnect();
672    mService->removeClient(client);
673}
674
675void MediaPlayerService::Client::disconnect()
676{
677    LOGV("disconnect(%d) from pid %d", mConnId, mPid);
678    // grab local reference and clear main reference to prevent future
679    // access to object
680    sp<MediaPlayerBase> p;
681    {
682        Mutex::Autolock l(mLock);
683        p = mPlayer;
684    }
685    mClient.clear();
686
687    mPlayer.clear();
688
689    // clear the notification to prevent callbacks to dead client
690    // and reset the player. We assume the player will serialize
691    // access to itself if necessary.
692    if (p != 0) {
693        p->setNotifyCallback(0, 0);
694#if CALLBACK_ANTAGONIZER
695        LOGD("kill Antagonizer");
696        mAntagonizer->kill();
697#endif
698        p->reset();
699    }
700
701    IPCThreadState::self()->flushCommands();
702}
703
704static player_type getDefaultPlayerType() {
705    return STAGEFRIGHT_PLAYER;
706}
707
708player_type getPlayerType(int fd, int64_t offset, int64_t length)
709{
710    char buf[20];
711    lseek(fd, offset, SEEK_SET);
712    read(fd, buf, sizeof(buf));
713    lseek(fd, offset, SEEK_SET);
714
715    long ident = *((long*)buf);
716
717    // Ogg vorbis?
718    if (ident == 0x5367674f) // 'OggS'
719        return STAGEFRIGHT_PLAYER;
720
721    // Some kind of MIDI?
722    EAS_DATA_HANDLE easdata;
723    if (EAS_Init(&easdata) == EAS_SUCCESS) {
724        EAS_FILE locator;
725        locator.path = NULL;
726        locator.fd = fd;
727        locator.offset = offset;
728        locator.length = length;
729        EAS_HANDLE  eashandle;
730        if (EAS_OpenFile(easdata, &locator, &eashandle) == EAS_SUCCESS) {
731            EAS_CloseFile(easdata, eashandle);
732            EAS_Shutdown(easdata);
733            return SONIVOX_PLAYER;
734        }
735        EAS_Shutdown(easdata);
736    }
737
738    return getDefaultPlayerType();
739}
740
741player_type getPlayerType(const char* url)
742{
743    if (TestPlayerStub::canBeUsed(url)) {
744        return TEST_PLAYER;
745    }
746
747    if (!strncasecmp("http://", url, 7)) {
748        size_t len = strlen(url);
749        if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
750            return NU_PLAYER;
751        }
752
753        if (strstr(url,"m3u8")) {
754            return NU_PLAYER;
755        }
756    }
757
758    // use MidiFile for MIDI extensions
759    int lenURL = strlen(url);
760    for (int i = 0; i < NELEM(FILE_EXTS); ++i) {
761        int len = strlen(FILE_EXTS[i].extension);
762        int start = lenURL - len;
763        if (start > 0) {
764            if (!strncasecmp(url + start, FILE_EXTS[i].extension, len)) {
765                return FILE_EXTS[i].playertype;
766            }
767        }
768    }
769
770    return getDefaultPlayerType();
771}
772
773static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie,
774        notify_callback_f notifyFunc)
775{
776    sp<MediaPlayerBase> p;
777    switch (playerType) {
778        case SONIVOX_PLAYER:
779            LOGV(" create MidiFile");
780            p = new MidiFile();
781            break;
782        case STAGEFRIGHT_PLAYER:
783            LOGV(" create StagefrightPlayer");
784            p = new StagefrightPlayer;
785            break;
786        case NU_PLAYER:
787            LOGV(" create NuPlayer");
788            p = new NuPlayerDriver;
789            break;
790        case TEST_PLAYER:
791            LOGV("Create Test Player stub");
792            p = new TestPlayerStub();
793            break;
794        default:
795            LOGE("Unknown player type: %d", playerType);
796            return NULL;
797    }
798    if (p != NULL) {
799        if (p->initCheck() == NO_ERROR) {
800            p->setNotifyCallback(cookie, notifyFunc);
801        } else {
802            p.clear();
803        }
804    }
805    if (p == NULL) {
806        LOGE("Failed to create player object");
807    }
808    return p;
809}
810
811sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)
812{
813    // determine if we have the right player type
814    sp<MediaPlayerBase> p = mPlayer;
815    if ((p != NULL) && (p->playerType() != playerType)) {
816        LOGV("delete player");
817        p.clear();
818    }
819    if (p == NULL) {
820        p = android::createPlayer(playerType, this, notify);
821    }
822    return p;
823}
824
825status_t MediaPlayerService::Client::setDataSource(
826        const char *url, const KeyedVector<String8, String8> *headers)
827{
828    LOGV("setDataSource(%s)", url);
829    if (url == NULL)
830        return UNKNOWN_ERROR;
831
832    if (strncmp(url, "content://", 10) == 0) {
833        // get a filedescriptor for the content Uri and
834        // pass it to the setDataSource(fd) method
835
836        String16 url16(url);
837        int fd = android::openContentProviderFile(url16);
838        if (fd < 0)
839        {
840            LOGE("Couldn't open fd for %s", url);
841            return UNKNOWN_ERROR;
842        }
843        setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus
844        close(fd);
845        return mStatus;
846    } else {
847        player_type playerType = getPlayerType(url);
848        LOGV("player type = %d", playerType);
849
850        // create the right type of player
851        sp<MediaPlayerBase> p = createPlayer(playerType);
852        if (p == NULL) return NO_INIT;
853
854        if (!p->hardwareOutput()) {
855            mAudioOutput = new AudioOutput(mAudioSessionId);
856            static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
857        }
858
859        // now set data source
860        LOGV(" setDataSource");
861        mStatus = p->setDataSource(url, headers);
862        if (mStatus == NO_ERROR) {
863            mPlayer = p;
864        } else {
865            LOGE("  error: %d", mStatus);
866        }
867        return mStatus;
868    }
869}
870
871status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)
872{
873    LOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length);
874    struct stat sb;
875    int ret = fstat(fd, &sb);
876    if (ret != 0) {
877        LOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno));
878        return UNKNOWN_ERROR;
879    }
880
881    LOGV("st_dev  = %llu", sb.st_dev);
882    LOGV("st_mode = %u", sb.st_mode);
883    LOGV("st_uid  = %lu", sb.st_uid);
884    LOGV("st_gid  = %lu", sb.st_gid);
885    LOGV("st_size = %llu", sb.st_size);
886
887    if (offset >= sb.st_size) {
888        LOGE("offset error");
889        ::close(fd);
890        return UNKNOWN_ERROR;
891    }
892    if (offset + length > sb.st_size) {
893        length = sb.st_size - offset;
894        LOGV("calculated length = %lld", length);
895    }
896
897    player_type playerType = getPlayerType(fd, offset, length);
898    LOGV("player type = %d", playerType);
899
900    // create the right type of player
901    sp<MediaPlayerBase> p = createPlayer(playerType);
902    if (p == NULL) return NO_INIT;
903
904    if (!p->hardwareOutput()) {
905        mAudioOutput = new AudioOutput(mAudioSessionId);
906        static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
907    }
908
909    // now set data source
910    mStatus = p->setDataSource(fd, offset, length);
911    if (mStatus == NO_ERROR) mPlayer = p;
912    return mStatus;
913}
914
915status_t MediaPlayerService::Client::setDataSource(
916        const sp<IStreamSource> &source) {
917    // create the right type of player
918    sp<MediaPlayerBase> p = createPlayer(NU_PLAYER);
919
920    if (p == NULL) {
921        return NO_INIT;
922    }
923
924    if (!p->hardwareOutput()) {
925        mAudioOutput = new AudioOutput(mAudioSessionId);
926        static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
927    }
928
929    // now set data source
930    mStatus = p->setDataSource(source);
931
932    if (mStatus == OK) {
933        mPlayer = p;
934    }
935
936    return mStatus;
937}
938
939status_t MediaPlayerService::Client::setVideoSurface(const sp<Surface>& surface)
940{
941    LOGV("[%d] setVideoSurface(%p)", mConnId, surface.get());
942    sp<MediaPlayerBase> p = getPlayer();
943    if (p == 0) return UNKNOWN_ERROR;
944    return p->setVideoSurface(surface);
945}
946
947status_t MediaPlayerService::Client::setVideoSurfaceTexture(
948        const sp<ISurfaceTexture>& surfaceTexture)
949{
950    LOGV("[%d] setVideoSurfaceTexture(%p)", mConnId, surfaceTexture.get());
951    sp<MediaPlayerBase> p = getPlayer();
952    if (p == 0) return UNKNOWN_ERROR;
953    return p->setVideoSurfaceTexture(surfaceTexture);
954}
955
956status_t MediaPlayerService::Client::invoke(const Parcel& request,
957                                            Parcel *reply)
958{
959    sp<MediaPlayerBase> p = getPlayer();
960    if (p == NULL) return UNKNOWN_ERROR;
961    return p->invoke(request, reply);
962}
963
964// This call doesn't need to access the native player.
965status_t MediaPlayerService::Client::setMetadataFilter(const Parcel& filter)
966{
967    status_t status;
968    media::Metadata::Filter allow, drop;
969
970    if (unmarshallFilter(filter, &allow, &status) &&
971        unmarshallFilter(filter, &drop, &status)) {
972        Mutex::Autolock lock(mLock);
973
974        mMetadataAllow = allow;
975        mMetadataDrop = drop;
976    }
977    return status;
978}
979
980status_t MediaPlayerService::Client::getMetadata(
981        bool update_only, bool apply_filter, Parcel *reply)
982{
983    sp<MediaPlayerBase> player = getPlayer();
984    if (player == 0) return UNKNOWN_ERROR;
985
986    status_t status;
987    // Placeholder for the return code, updated by the caller.
988    reply->writeInt32(-1);
989
990    media::Metadata::Filter ids;
991
992    // We don't block notifications while we fetch the data. We clear
993    // mMetadataUpdated first so we don't lose notifications happening
994    // during the rest of this call.
995    {
996        Mutex::Autolock lock(mLock);
997        if (update_only) {
998            ids = mMetadataUpdated;
999        }
1000        mMetadataUpdated.clear();
1001    }
1002
1003    media::Metadata metadata(reply);
1004
1005    metadata.appendHeader();
1006    status = player->getMetadata(ids, reply);
1007
1008    if (status != OK) {
1009        metadata.resetParcel();
1010        LOGE("getMetadata failed %d", status);
1011        return status;
1012    }
1013
1014    // FIXME: Implement filtering on the result. Not critical since
1015    // filtering takes place on the update notifications already. This
1016    // would be when all the metadata are fetch and a filter is set.
1017
1018    // Everything is fine, update the metadata length.
1019    metadata.updateLength();
1020    return OK;
1021}
1022
1023status_t MediaPlayerService::Client::prepareAsync()
1024{
1025    LOGV("[%d] prepareAsync", mConnId);
1026    sp<MediaPlayerBase> p = getPlayer();
1027    if (p == 0) return UNKNOWN_ERROR;
1028    status_t ret = p->prepareAsync();
1029#if CALLBACK_ANTAGONIZER
1030    LOGD("start Antagonizer");
1031    if (ret == NO_ERROR) mAntagonizer->start();
1032#endif
1033    return ret;
1034}
1035
1036status_t MediaPlayerService::Client::start()
1037{
1038    LOGV("[%d] start", mConnId);
1039    sp<MediaPlayerBase> p = getPlayer();
1040    if (p == 0) return UNKNOWN_ERROR;
1041    p->setLooping(mLoop);
1042    return p->start();
1043}
1044
1045status_t MediaPlayerService::Client::stop()
1046{
1047    LOGV("[%d] stop", mConnId);
1048    sp<MediaPlayerBase> p = getPlayer();
1049    if (p == 0) return UNKNOWN_ERROR;
1050    return p->stop();
1051}
1052
1053status_t MediaPlayerService::Client::pause()
1054{
1055    LOGV("[%d] pause", mConnId);
1056    sp<MediaPlayerBase> p = getPlayer();
1057    if (p == 0) return UNKNOWN_ERROR;
1058    return p->pause();
1059}
1060
1061status_t MediaPlayerService::Client::isPlaying(bool* state)
1062{
1063    *state = false;
1064    sp<MediaPlayerBase> p = getPlayer();
1065    if (p == 0) return UNKNOWN_ERROR;
1066    *state = p->isPlaying();
1067    LOGV("[%d] isPlaying: %d", mConnId, *state);
1068    return NO_ERROR;
1069}
1070
1071status_t MediaPlayerService::Client::getCurrentPosition(int *msec)
1072{
1073    LOGV("getCurrentPosition");
1074    sp<MediaPlayerBase> p = getPlayer();
1075    if (p == 0) return UNKNOWN_ERROR;
1076    status_t ret = p->getCurrentPosition(msec);
1077    if (ret == NO_ERROR) {
1078        LOGV("[%d] getCurrentPosition = %d", mConnId, *msec);
1079    } else {
1080        LOGE("getCurrentPosition returned %d", ret);
1081    }
1082    return ret;
1083}
1084
1085status_t MediaPlayerService::Client::getDuration(int *msec)
1086{
1087    LOGV("getDuration");
1088    sp<MediaPlayerBase> p = getPlayer();
1089    if (p == 0) return UNKNOWN_ERROR;
1090    status_t ret = p->getDuration(msec);
1091    if (ret == NO_ERROR) {
1092        LOGV("[%d] getDuration = %d", mConnId, *msec);
1093    } else {
1094        LOGE("getDuration returned %d", ret);
1095    }
1096    return ret;
1097}
1098
1099status_t MediaPlayerService::Client::seekTo(int msec)
1100{
1101    LOGV("[%d] seekTo(%d)", mConnId, msec);
1102    sp<MediaPlayerBase> p = getPlayer();
1103    if (p == 0) return UNKNOWN_ERROR;
1104    return p->seekTo(msec);
1105}
1106
1107status_t MediaPlayerService::Client::reset()
1108{
1109    LOGV("[%d] reset", mConnId);
1110    sp<MediaPlayerBase> p = getPlayer();
1111    if (p == 0) return UNKNOWN_ERROR;
1112    return p->reset();
1113}
1114
1115status_t MediaPlayerService::Client::setAudioStreamType(int type)
1116{
1117    LOGV("[%d] setAudioStreamType(%d)", mConnId, type);
1118    // TODO: for hardware output, call player instead
1119    Mutex::Autolock l(mLock);
1120    if (mAudioOutput != 0) mAudioOutput->setAudioStreamType(type);
1121    return NO_ERROR;
1122}
1123
1124status_t MediaPlayerService::Client::setLooping(int loop)
1125{
1126    LOGV("[%d] setLooping(%d)", mConnId, loop);
1127    mLoop = loop;
1128    sp<MediaPlayerBase> p = getPlayer();
1129    if (p != 0) return p->setLooping(loop);
1130    return NO_ERROR;
1131}
1132
1133status_t MediaPlayerService::Client::setVolume(float leftVolume, float rightVolume)
1134{
1135    LOGV("[%d] setVolume(%f, %f)", mConnId, leftVolume, rightVolume);
1136    // TODO: for hardware output, call player instead
1137    Mutex::Autolock l(mLock);
1138    if (mAudioOutput != 0) mAudioOutput->setVolume(leftVolume, rightVolume);
1139    return NO_ERROR;
1140}
1141
1142status_t MediaPlayerService::Client::setAuxEffectSendLevel(float level)
1143{
1144    LOGV("[%d] setAuxEffectSendLevel(%f)", mConnId, level);
1145    Mutex::Autolock l(mLock);
1146    if (mAudioOutput != 0) return mAudioOutput->setAuxEffectSendLevel(level);
1147    return NO_ERROR;
1148}
1149
1150status_t MediaPlayerService::Client::attachAuxEffect(int effectId)
1151{
1152    LOGV("[%d] attachAuxEffect(%d)", mConnId, effectId);
1153    Mutex::Autolock l(mLock);
1154    if (mAudioOutput != 0) return mAudioOutput->attachAuxEffect(effectId);
1155    return NO_ERROR;
1156}
1157
1158void MediaPlayerService::Client::notify(void* cookie, int msg, int ext1, int ext2)
1159{
1160    Client* client = static_cast<Client*>(cookie);
1161
1162    if (MEDIA_INFO == msg &&
1163        MEDIA_INFO_METADATA_UPDATE == ext1) {
1164        const media::Metadata::Type metadata_type = ext2;
1165
1166        if(client->shouldDropMetadata(metadata_type)) {
1167            return;
1168        }
1169
1170        // Update the list of metadata that have changed. getMetadata
1171        // also access mMetadataUpdated and clears it.
1172        client->addNewMetadataUpdate(metadata_type);
1173    }
1174    LOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, cookie, msg, ext1, ext2);
1175    client->mClient->notify(msg, ext1, ext2);
1176}
1177
1178
1179bool MediaPlayerService::Client::shouldDropMetadata(media::Metadata::Type code) const
1180{
1181    Mutex::Autolock lock(mLock);
1182
1183    if (findMetadata(mMetadataDrop, code)) {
1184        return true;
1185    }
1186
1187    if (mMetadataAllow.isEmpty() || findMetadata(mMetadataAllow, code)) {
1188        return false;
1189    } else {
1190        return true;
1191    }
1192}
1193
1194
1195void MediaPlayerService::Client::addNewMetadataUpdate(media::Metadata::Type metadata_type) {
1196    Mutex::Autolock lock(mLock);
1197    if (mMetadataUpdated.indexOf(metadata_type) < 0) {
1198        mMetadataUpdated.add(metadata_type);
1199    }
1200}
1201
1202#if CALLBACK_ANTAGONIZER
1203const int Antagonizer::interval = 10000; // 10 msecs
1204
1205Antagonizer::Antagonizer(notify_callback_f cb, void* client) :
1206    mExit(false), mActive(false), mClient(client), mCb(cb)
1207{
1208    createThread(callbackThread, this);
1209}
1210
1211void Antagonizer::kill()
1212{
1213    Mutex::Autolock _l(mLock);
1214    mActive = false;
1215    mExit = true;
1216    mCondition.wait(mLock);
1217}
1218
1219int Antagonizer::callbackThread(void* user)
1220{
1221    LOGD("Antagonizer started");
1222    Antagonizer* p = reinterpret_cast<Antagonizer*>(user);
1223    while (!p->mExit) {
1224        if (p->mActive) {
1225            LOGV("send event");
1226            p->mCb(p->mClient, 0, 0, 0);
1227        }
1228        usleep(interval);
1229    }
1230    Mutex::Autolock _l(p->mLock);
1231    p->mCondition.signal();
1232    LOGD("Antagonizer stopped");
1233    return 0;
1234}
1235#endif
1236
1237static size_t kDefaultHeapSize = 1024 * 1024; // 1MB
1238
1239sp<IMemory> MediaPlayerService::decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
1240{
1241    LOGV("decode(%s)", url);
1242    sp<MemoryBase> mem;
1243    sp<MediaPlayerBase> player;
1244
1245    // Protect our precious, precious DRMd ringtones by only allowing
1246    // decoding of http, but not filesystem paths or content Uris.
1247    // If the application wants to decode those, it should open a
1248    // filedescriptor for them and use that.
1249    if (url != NULL && strncmp(url, "http://", 7) != 0) {
1250        LOGD("Can't decode %s by path, use filedescriptor instead", url);
1251        return mem;
1252    }
1253
1254    player_type playerType = getPlayerType(url);
1255    LOGV("player type = %d", playerType);
1256
1257    // create the right type of player
1258    sp<AudioCache> cache = new AudioCache(url);
1259    player = android::createPlayer(playerType, cache.get(), cache->notify);
1260    if (player == NULL) goto Exit;
1261    if (player->hardwareOutput()) goto Exit;
1262
1263    static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache);
1264
1265    // set data source
1266    if (player->setDataSource(url) != NO_ERROR) goto Exit;
1267
1268    LOGV("prepare");
1269    player->prepareAsync();
1270
1271    LOGV("wait for prepare");
1272    if (cache->wait() != NO_ERROR) goto Exit;
1273
1274    LOGV("start");
1275    player->start();
1276
1277    LOGV("wait for playback complete");
1278    if (cache->wait() != NO_ERROR) goto Exit;
1279
1280    mem = new MemoryBase(cache->getHeap(), 0, cache->size());
1281    *pSampleRate = cache->sampleRate();
1282    *pNumChannels = cache->channelCount();
1283    *pFormat = cache->format();
1284    LOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat);
1285
1286Exit:
1287    if (player != 0) player->reset();
1288    return mem;
1289}
1290
1291sp<IMemory> MediaPlayerService::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
1292{
1293    LOGV("decode(%d, %lld, %lld)", fd, offset, length);
1294    sp<MemoryBase> mem;
1295    sp<MediaPlayerBase> player;
1296
1297    player_type playerType = getPlayerType(fd, offset, length);
1298    LOGV("player type = %d", playerType);
1299
1300    // create the right type of player
1301    sp<AudioCache> cache = new AudioCache("decode_fd");
1302    player = android::createPlayer(playerType, cache.get(), cache->notify);
1303    if (player == NULL) goto Exit;
1304    if (player->hardwareOutput()) goto Exit;
1305
1306    static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache);
1307
1308    // set data source
1309    if (player->setDataSource(fd, offset, length) != NO_ERROR) goto Exit;
1310
1311    LOGV("prepare");
1312    player->prepareAsync();
1313
1314    LOGV("wait for prepare");
1315    if (cache->wait() != NO_ERROR) goto Exit;
1316
1317    LOGV("start");
1318    player->start();
1319
1320    LOGV("wait for playback complete");
1321    if (cache->wait() != NO_ERROR) goto Exit;
1322
1323    mem = new MemoryBase(cache->getHeap(), 0, cache->size());
1324    *pSampleRate = cache->sampleRate();
1325    *pNumChannels = cache->channelCount();
1326    *pFormat = cache->format();
1327    LOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat);
1328
1329Exit:
1330    if (player != 0) player->reset();
1331    ::close(fd);
1332    return mem;
1333}
1334
1335
1336#undef LOG_TAG
1337#define LOG_TAG "AudioSink"
1338MediaPlayerService::AudioOutput::AudioOutput(int sessionId)
1339    : mCallback(NULL),
1340      mCallbackCookie(NULL),
1341      mSessionId(sessionId) {
1342    LOGV("AudioOutput(%d)", sessionId);
1343    mTrack = 0;
1344    mStreamType = AudioSystem::MUSIC;
1345    mLeftVolume = 1.0;
1346    mRightVolume = 1.0;
1347    mLatency = 0;
1348    mMsecsPerFrame = 0;
1349    mAuxEffectId = 0;
1350    mSendLevel = 0.0;
1351    setMinBufferCount();
1352}
1353
1354MediaPlayerService::AudioOutput::~AudioOutput()
1355{
1356    close();
1357}
1358
1359void MediaPlayerService::AudioOutput::setMinBufferCount()
1360{
1361    char value[PROPERTY_VALUE_MAX];
1362    if (property_get("ro.kernel.qemu", value, 0)) {
1363        mIsOnEmulator = true;
1364        mMinBufferCount = 12;  // to prevent systematic buffer underrun for emulator
1365    }
1366}
1367
1368bool MediaPlayerService::AudioOutput::isOnEmulator()
1369{
1370    setMinBufferCount();
1371    return mIsOnEmulator;
1372}
1373
1374int MediaPlayerService::AudioOutput::getMinBufferCount()
1375{
1376    setMinBufferCount();
1377    return mMinBufferCount;
1378}
1379
1380ssize_t MediaPlayerService::AudioOutput::bufferSize() const
1381{
1382    if (mTrack == 0) return NO_INIT;
1383    return mTrack->frameCount() * frameSize();
1384}
1385
1386ssize_t MediaPlayerService::AudioOutput::frameCount() const
1387{
1388    if (mTrack == 0) return NO_INIT;
1389    return mTrack->frameCount();
1390}
1391
1392ssize_t MediaPlayerService::AudioOutput::channelCount() const
1393{
1394    if (mTrack == 0) return NO_INIT;
1395    return mTrack->channelCount();
1396}
1397
1398ssize_t MediaPlayerService::AudioOutput::frameSize() const
1399{
1400    if (mTrack == 0) return NO_INIT;
1401    return mTrack->frameSize();
1402}
1403
1404uint32_t MediaPlayerService::AudioOutput::latency () const
1405{
1406    return mLatency;
1407}
1408
1409float MediaPlayerService::AudioOutput::msecsPerFrame() const
1410{
1411    return mMsecsPerFrame;
1412}
1413
1414status_t MediaPlayerService::AudioOutput::getPosition(uint32_t *position)
1415{
1416    if (mTrack == 0) return NO_INIT;
1417    return mTrack->getPosition(position);
1418}
1419
1420status_t MediaPlayerService::AudioOutput::open(
1421        uint32_t sampleRate, int channelCount, int format, int bufferCount,
1422        AudioCallback cb, void *cookie)
1423{
1424    mCallback = cb;
1425    mCallbackCookie = cookie;
1426
1427    // Check argument "bufferCount" against the mininum buffer count
1428    if (bufferCount < mMinBufferCount) {
1429        LOGD("bufferCount (%d) is too small and increased to %d", bufferCount, mMinBufferCount);
1430        bufferCount = mMinBufferCount;
1431
1432    }
1433    LOGV("open(%u, %d, %d, %d, %d)", sampleRate, channelCount, format, bufferCount,mSessionId);
1434    if (mTrack) close();
1435    int afSampleRate;
1436    int afFrameCount;
1437    int frameCount;
1438
1439    if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) != NO_ERROR) {
1440        return NO_INIT;
1441    }
1442    if (AudioSystem::getOutputSamplingRate(&afSampleRate, mStreamType) != NO_ERROR) {
1443        return NO_INIT;
1444    }
1445
1446    frameCount = (sampleRate*afFrameCount*bufferCount)/afSampleRate;
1447
1448    AudioTrack *t;
1449    if (mCallback != NULL) {
1450        t = new AudioTrack(
1451                mStreamType,
1452                sampleRate,
1453                format,
1454                (channelCount == 2) ? AudioSystem::CHANNEL_OUT_STEREO : AudioSystem::CHANNEL_OUT_MONO,
1455                frameCount,
1456                0 /* flags */,
1457                CallbackWrapper,
1458                this,
1459                0,
1460                mSessionId);
1461    } else {
1462        t = new AudioTrack(
1463                mStreamType,
1464                sampleRate,
1465                format,
1466                (channelCount == 2) ? AudioSystem::CHANNEL_OUT_STEREO : AudioSystem::CHANNEL_OUT_MONO,
1467                frameCount,
1468                0,
1469                NULL,
1470                NULL,
1471                0,
1472                mSessionId);
1473    }
1474
1475    if ((t == 0) || (t->initCheck() != NO_ERROR)) {
1476        LOGE("Unable to create audio track");
1477        delete t;
1478        return NO_INIT;
1479    }
1480
1481    LOGV("setVolume");
1482    t->setVolume(mLeftVolume, mRightVolume);
1483
1484    mMsecsPerFrame = 1.e3 / (float) sampleRate;
1485    mLatency = t->latency();
1486    mTrack = t;
1487
1488    t->setAuxEffectSendLevel(mSendLevel);
1489    return t->attachAuxEffect(mAuxEffectId);;
1490}
1491
1492void MediaPlayerService::AudioOutput::start()
1493{
1494    LOGV("start");
1495    if (mTrack) {
1496        mTrack->setVolume(mLeftVolume, mRightVolume);
1497        mTrack->setAuxEffectSendLevel(mSendLevel);
1498        mTrack->start();
1499    }
1500}
1501
1502
1503
1504ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size)
1505{
1506    LOG_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback.");
1507
1508    //LOGV("write(%p, %u)", buffer, size);
1509    if (mTrack) {
1510        ssize_t ret = mTrack->write(buffer, size);
1511        return ret;
1512    }
1513    return NO_INIT;
1514}
1515
1516void MediaPlayerService::AudioOutput::stop()
1517{
1518    LOGV("stop");
1519    if (mTrack) mTrack->stop();
1520}
1521
1522void MediaPlayerService::AudioOutput::flush()
1523{
1524    LOGV("flush");
1525    if (mTrack) mTrack->flush();
1526}
1527
1528void MediaPlayerService::AudioOutput::pause()
1529{
1530    LOGV("pause");
1531    if (mTrack) mTrack->pause();
1532}
1533
1534void MediaPlayerService::AudioOutput::close()
1535{
1536    LOGV("close");
1537    delete mTrack;
1538    mTrack = 0;
1539}
1540
1541void MediaPlayerService::AudioOutput::setVolume(float left, float right)
1542{
1543    LOGV("setVolume(%f, %f)", left, right);
1544    mLeftVolume = left;
1545    mRightVolume = right;
1546    if (mTrack) {
1547        mTrack->setVolume(left, right);
1548    }
1549}
1550
1551status_t MediaPlayerService::AudioOutput::setAuxEffectSendLevel(float level)
1552{
1553    LOGV("setAuxEffectSendLevel(%f)", level);
1554    mSendLevel = level;
1555    if (mTrack) {
1556        return mTrack->setAuxEffectSendLevel(level);
1557    }
1558    return NO_ERROR;
1559}
1560
1561status_t MediaPlayerService::AudioOutput::attachAuxEffect(int effectId)
1562{
1563    LOGV("attachAuxEffect(%d)", effectId);
1564    mAuxEffectId = effectId;
1565    if (mTrack) {
1566        return mTrack->attachAuxEffect(effectId);
1567    }
1568    return NO_ERROR;
1569}
1570
1571// static
1572void MediaPlayerService::AudioOutput::CallbackWrapper(
1573        int event, void *cookie, void *info) {
1574    //LOGV("callbackwrapper");
1575    if (event != AudioTrack::EVENT_MORE_DATA) {
1576        return;
1577    }
1578
1579    AudioOutput *me = (AudioOutput *)cookie;
1580    AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
1581
1582    size_t actualSize = (*me->mCallback)(
1583            me, buffer->raw, buffer->size, me->mCallbackCookie);
1584
1585    buffer->size = actualSize;
1586
1587}
1588
1589int MediaPlayerService::AudioOutput::getSessionId()
1590{
1591    return mSessionId;
1592}
1593
1594#undef LOG_TAG
1595#define LOG_TAG "AudioCache"
1596MediaPlayerService::AudioCache::AudioCache(const char* name) :
1597    mChannelCount(0), mFrameCount(1024), mSampleRate(0), mSize(0),
1598    mError(NO_ERROR), mCommandComplete(false)
1599{
1600    // create ashmem heap
1601    mHeap = new MemoryHeapBase(kDefaultHeapSize, 0, name);
1602}
1603
1604uint32_t MediaPlayerService::AudioCache::latency () const
1605{
1606    return 0;
1607}
1608
1609float MediaPlayerService::AudioCache::msecsPerFrame() const
1610{
1611    return mMsecsPerFrame;
1612}
1613
1614status_t MediaPlayerService::AudioCache::getPosition(uint32_t *position)
1615{
1616    if (position == 0) return BAD_VALUE;
1617    *position = mSize;
1618    return NO_ERROR;
1619}
1620
1621////////////////////////////////////////////////////////////////////////////////
1622
1623struct CallbackThread : public Thread {
1624    CallbackThread(const wp<MediaPlayerBase::AudioSink> &sink,
1625                   MediaPlayerBase::AudioSink::AudioCallback cb,
1626                   void *cookie);
1627
1628protected:
1629    virtual ~CallbackThread();
1630
1631    virtual bool threadLoop();
1632
1633private:
1634    wp<MediaPlayerBase::AudioSink> mSink;
1635    MediaPlayerBase::AudioSink::AudioCallback mCallback;
1636    void *mCookie;
1637    void *mBuffer;
1638    size_t mBufferSize;
1639
1640    CallbackThread(const CallbackThread &);
1641    CallbackThread &operator=(const CallbackThread &);
1642};
1643
1644CallbackThread::CallbackThread(
1645        const wp<MediaPlayerBase::AudioSink> &sink,
1646        MediaPlayerBase::AudioSink::AudioCallback cb,
1647        void *cookie)
1648    : mSink(sink),
1649      mCallback(cb),
1650      mCookie(cookie),
1651      mBuffer(NULL),
1652      mBufferSize(0) {
1653}
1654
1655CallbackThread::~CallbackThread() {
1656    if (mBuffer) {
1657        free(mBuffer);
1658        mBuffer = NULL;
1659    }
1660}
1661
1662bool CallbackThread::threadLoop() {
1663    sp<MediaPlayerBase::AudioSink> sink = mSink.promote();
1664    if (sink == NULL) {
1665        return false;
1666    }
1667
1668    if (mBuffer == NULL) {
1669        mBufferSize = sink->bufferSize();
1670        mBuffer = malloc(mBufferSize);
1671    }
1672
1673    size_t actualSize =
1674        (*mCallback)(sink.get(), mBuffer, mBufferSize, mCookie);
1675
1676    if (actualSize > 0) {
1677        sink->write(mBuffer, actualSize);
1678    }
1679
1680    return true;
1681}
1682
1683////////////////////////////////////////////////////////////////////////////////
1684
1685status_t MediaPlayerService::AudioCache::open(
1686        uint32_t sampleRate, int channelCount, int format, int bufferCount,
1687        AudioCallback cb, void *cookie)
1688{
1689    LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount);
1690    if (mHeap->getHeapID() < 0) {
1691        return NO_INIT;
1692    }
1693
1694    mSampleRate = sampleRate;
1695    mChannelCount = (uint16_t)channelCount;
1696    mFormat = (uint16_t)format;
1697    mMsecsPerFrame = 1.e3 / (float) sampleRate;
1698
1699    if (cb != NULL) {
1700        mCallbackThread = new CallbackThread(this, cb, cookie);
1701    }
1702    return NO_ERROR;
1703}
1704
1705void MediaPlayerService::AudioCache::start() {
1706    if (mCallbackThread != NULL) {
1707        mCallbackThread->run("AudioCache callback");
1708    }
1709}
1710
1711void MediaPlayerService::AudioCache::stop() {
1712    if (mCallbackThread != NULL) {
1713        mCallbackThread->requestExitAndWait();
1714    }
1715}
1716
1717ssize_t MediaPlayerService::AudioCache::write(const void* buffer, size_t size)
1718{
1719    LOGV("write(%p, %u)", buffer, size);
1720    if ((buffer == 0) || (size == 0)) return size;
1721
1722    uint8_t* p = static_cast<uint8_t*>(mHeap->getBase());
1723    if (p == NULL) return NO_INIT;
1724    p += mSize;
1725    LOGV("memcpy(%p, %p, %u)", p, buffer, size);
1726    if (mSize + size > mHeap->getSize()) {
1727        LOGE("Heap size overflow! req size: %d, max size: %d", (mSize + size), mHeap->getSize());
1728        size = mHeap->getSize() - mSize;
1729    }
1730    memcpy(p, buffer, size);
1731    mSize += size;
1732    return size;
1733}
1734
1735// call with lock held
1736status_t MediaPlayerService::AudioCache::wait()
1737{
1738    Mutex::Autolock lock(mLock);
1739    while (!mCommandComplete) {
1740        mSignal.wait(mLock);
1741    }
1742    mCommandComplete = false;
1743
1744    if (mError == NO_ERROR) {
1745        LOGV("wait - success");
1746    } else {
1747        LOGV("wait - error");
1748    }
1749    return mError;
1750}
1751
1752void MediaPlayerService::AudioCache::notify(void* cookie, int msg, int ext1, int ext2)
1753{
1754    LOGV("notify(%p, %d, %d, %d)", cookie, msg, ext1, ext2);
1755    AudioCache* p = static_cast<AudioCache*>(cookie);
1756
1757    // ignore buffering messages
1758    switch (msg)
1759    {
1760    case MEDIA_ERROR:
1761        LOGE("Error %d, %d occurred", ext1, ext2);
1762        p->mError = ext1;
1763        break;
1764    case MEDIA_PREPARED:
1765        LOGV("prepared");
1766        break;
1767    case MEDIA_PLAYBACK_COMPLETE:
1768        LOGV("playback complete");
1769        break;
1770    default:
1771        LOGV("ignored");
1772        return;
1773    }
1774
1775    // wake up thread
1776    Mutex::Autolock lock(p->mLock);
1777    p->mCommandComplete = true;
1778    p->mSignal.signal();
1779}
1780
1781int MediaPlayerService::AudioCache::getSessionId()
1782{
1783    return 0;
1784}
1785
1786void MediaPlayerService::addBatteryData(uint32_t params)
1787{
1788    Mutex::Autolock lock(mLock);
1789
1790    int32_t time = systemTime() / 1000000L;
1791
1792    // change audio output devices. This notification comes from AudioFlinger
1793    if ((params & kBatteryDataSpeakerOn)
1794            || (params & kBatteryDataOtherAudioDeviceOn)) {
1795
1796        int deviceOn[NUM_AUDIO_DEVICES];
1797        for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
1798            deviceOn[i] = 0;
1799        }
1800
1801        if ((params & kBatteryDataSpeakerOn)
1802                && (params & kBatteryDataOtherAudioDeviceOn)) {
1803            deviceOn[SPEAKER_AND_OTHER] = 1;
1804        } else if (params & kBatteryDataSpeakerOn) {
1805            deviceOn[SPEAKER] = 1;
1806        } else {
1807            deviceOn[OTHER_AUDIO_DEVICE] = 1;
1808        }
1809
1810        for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
1811            if (mBatteryAudio.deviceOn[i] != deviceOn[i]){
1812
1813                if (mBatteryAudio.refCount > 0) { // if playing audio
1814                    if (!deviceOn[i]) {
1815                        mBatteryAudio.lastTime[i] += time;
1816                        mBatteryAudio.totalTime[i] += mBatteryAudio.lastTime[i];
1817                        mBatteryAudio.lastTime[i] = 0;
1818                    } else {
1819                        mBatteryAudio.lastTime[i] = 0 - time;
1820                    }
1821                }
1822
1823                mBatteryAudio.deviceOn[i] = deviceOn[i];
1824            }
1825        }
1826        return;
1827    }
1828
1829    // an sudio stream is started
1830    if (params & kBatteryDataAudioFlingerStart) {
1831        // record the start time only if currently no other audio
1832        // is being played
1833        if (mBatteryAudio.refCount == 0) {
1834            for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
1835                if (mBatteryAudio.deviceOn[i]) {
1836                    mBatteryAudio.lastTime[i] -= time;
1837                }
1838            }
1839        }
1840
1841        mBatteryAudio.refCount ++;
1842        return;
1843
1844    } else if (params & kBatteryDataAudioFlingerStop) {
1845        if (mBatteryAudio.refCount <= 0) {
1846            LOGW("Battery track warning: refCount is <= 0");
1847            return;
1848        }
1849
1850        // record the stop time only if currently this is the only
1851        // audio being played
1852        if (mBatteryAudio.refCount == 1) {
1853            for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
1854                if (mBatteryAudio.deviceOn[i]) {
1855                    mBatteryAudio.lastTime[i] += time;
1856                    mBatteryAudio.totalTime[i] += mBatteryAudio.lastTime[i];
1857                    mBatteryAudio.lastTime[i] = 0;
1858                }
1859            }
1860        }
1861
1862        mBatteryAudio.refCount --;
1863        return;
1864    }
1865
1866    int uid = IPCThreadState::self()->getCallingUid();
1867    if (uid == AID_MEDIA) {
1868        return;
1869    }
1870    int index = mBatteryData.indexOfKey(uid);
1871
1872    if (index < 0) { // create a new entry for this UID
1873        BatteryUsageInfo info;
1874        info.audioTotalTime = 0;
1875        info.videoTotalTime = 0;
1876        info.audioLastTime = 0;
1877        info.videoLastTime = 0;
1878        info.refCount = 0;
1879
1880        if (mBatteryData.add(uid, info) == NO_MEMORY) {
1881            LOGE("Battery track error: no memory for new app");
1882            return;
1883        }
1884    }
1885
1886    BatteryUsageInfo &info = mBatteryData.editValueFor(uid);
1887
1888    if (params & kBatteryDataCodecStarted) {
1889        if (params & kBatteryDataTrackAudio) {
1890            info.audioLastTime -= time;
1891            info.refCount ++;
1892        }
1893        if (params & kBatteryDataTrackVideo) {
1894            info.videoLastTime -= time;
1895            info.refCount ++;
1896        }
1897    } else {
1898        if (info.refCount == 0) {
1899            LOGW("Battery track warning: refCount is already 0");
1900            return;
1901        } else if (info.refCount < 0) {
1902            LOGE("Battery track error: refCount < 0");
1903            mBatteryData.removeItem(uid);
1904            return;
1905        }
1906
1907        if (params & kBatteryDataTrackAudio) {
1908            info.audioLastTime += time;
1909            info.refCount --;
1910        }
1911        if (params & kBatteryDataTrackVideo) {
1912            info.videoLastTime += time;
1913            info.refCount --;
1914        }
1915
1916        // no stream is being played by this UID
1917        if (info.refCount == 0) {
1918            info.audioTotalTime += info.audioLastTime;
1919            info.audioLastTime = 0;
1920            info.videoTotalTime += info.videoLastTime;
1921            info.videoLastTime = 0;
1922        }
1923    }
1924}
1925
1926status_t MediaPlayerService::pullBatteryData(Parcel* reply) {
1927    Mutex::Autolock lock(mLock);
1928
1929    // audio output devices usage
1930    int32_t time = systemTime() / 1000000L; //in ms
1931    int32_t totalTime;
1932
1933    for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
1934        totalTime = mBatteryAudio.totalTime[i];
1935
1936        if (mBatteryAudio.deviceOn[i]
1937            && (mBatteryAudio.lastTime[i] != 0)) {
1938                int32_t tmpTime = mBatteryAudio.lastTime[i] + time;
1939                totalTime += tmpTime;
1940        }
1941
1942        reply->writeInt32(totalTime);
1943        // reset the total time
1944        mBatteryAudio.totalTime[i] = 0;
1945   }
1946
1947    // codec usage
1948    BatteryUsageInfo info;
1949    int size = mBatteryData.size();
1950
1951    reply->writeInt32(size);
1952    int i = 0;
1953
1954    while (i < size) {
1955        info = mBatteryData.valueAt(i);
1956
1957        reply->writeInt32(mBatteryData.keyAt(i)); //UID
1958        reply->writeInt32(info.audioTotalTime);
1959        reply->writeInt32(info.videoTotalTime);
1960
1961        info.audioTotalTime = 0;
1962        info.videoTotalTime = 0;
1963
1964        // remove the UID entry where no stream is being played
1965        if (info.refCount <= 0) {
1966            mBatteryData.removeItemsAt(i);
1967            size --;
1968            i --;
1969        }
1970        i++;
1971    }
1972    return NO_ERROR;
1973}
1974} // namespace android
1975