MediaPlayerService.cpp revision bb3ae0dc89b06ddf81c34fc1ba7f972712ab8a92
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            || !strncasecmp("https://", url, 8)) {
749        size_t len = strlen(url);
750        if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
751            return NU_PLAYER;
752        }
753
754        if (strstr(url,"m3u8")) {
755            return NU_PLAYER;
756        }
757    }
758
759    // use MidiFile for MIDI extensions
760    int lenURL = strlen(url);
761    for (int i = 0; i < NELEM(FILE_EXTS); ++i) {
762        int len = strlen(FILE_EXTS[i].extension);
763        int start = lenURL - len;
764        if (start > 0) {
765            if (!strncasecmp(url + start, FILE_EXTS[i].extension, len)) {
766                return FILE_EXTS[i].playertype;
767            }
768        }
769    }
770
771    return getDefaultPlayerType();
772}
773
774static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie,
775        notify_callback_f notifyFunc)
776{
777    sp<MediaPlayerBase> p;
778    switch (playerType) {
779        case SONIVOX_PLAYER:
780            LOGV(" create MidiFile");
781            p = new MidiFile();
782            break;
783        case STAGEFRIGHT_PLAYER:
784            LOGV(" create StagefrightPlayer");
785            p = new StagefrightPlayer;
786            break;
787        case NU_PLAYER:
788            LOGV(" create NuPlayer");
789            p = new NuPlayerDriver;
790            break;
791        case TEST_PLAYER:
792            LOGV("Create Test Player stub");
793            p = new TestPlayerStub();
794            break;
795        default:
796            LOGE("Unknown player type: %d", playerType);
797            return NULL;
798    }
799    if (p != NULL) {
800        if (p->initCheck() == NO_ERROR) {
801            p->setNotifyCallback(cookie, notifyFunc);
802        } else {
803            p.clear();
804        }
805    }
806    if (p == NULL) {
807        LOGE("Failed to create player object");
808    }
809    return p;
810}
811
812sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)
813{
814    // determine if we have the right player type
815    sp<MediaPlayerBase> p = mPlayer;
816    if ((p != NULL) && (p->playerType() != playerType)) {
817        LOGV("delete player");
818        p.clear();
819    }
820    if (p == NULL) {
821        p = android::createPlayer(playerType, this, notify);
822    }
823    return p;
824}
825
826status_t MediaPlayerService::Client::setDataSource(
827        const char *url, const KeyedVector<String8, String8> *headers)
828{
829    LOGV("setDataSource(%s)", url);
830    if (url == NULL)
831        return UNKNOWN_ERROR;
832
833    if (strncmp(url, "content://", 10) == 0) {
834        // get a filedescriptor for the content Uri and
835        // pass it to the setDataSource(fd) method
836
837        String16 url16(url);
838        int fd = android::openContentProviderFile(url16);
839        if (fd < 0)
840        {
841            LOGE("Couldn't open fd for %s", url);
842            return UNKNOWN_ERROR;
843        }
844        setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus
845        close(fd);
846        return mStatus;
847    } else {
848        player_type playerType = getPlayerType(url);
849        LOGV("player type = %d", playerType);
850
851        // create the right type of player
852        sp<MediaPlayerBase> p = createPlayer(playerType);
853        if (p == NULL) return NO_INIT;
854
855        if (!p->hardwareOutput()) {
856            mAudioOutput = new AudioOutput(mAudioSessionId);
857            static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
858        }
859
860        // now set data source
861        LOGV(" setDataSource");
862        mStatus = p->setDataSource(url, headers);
863        if (mStatus == NO_ERROR) {
864            mPlayer = p;
865        } else {
866            LOGE("  error: %d", mStatus);
867        }
868        return mStatus;
869    }
870}
871
872status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)
873{
874    LOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length);
875    struct stat sb;
876    int ret = fstat(fd, &sb);
877    if (ret != 0) {
878        LOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno));
879        return UNKNOWN_ERROR;
880    }
881
882    LOGV("st_dev  = %llu", sb.st_dev);
883    LOGV("st_mode = %u", sb.st_mode);
884    LOGV("st_uid  = %lu", sb.st_uid);
885    LOGV("st_gid  = %lu", sb.st_gid);
886    LOGV("st_size = %llu", sb.st_size);
887
888    if (offset >= sb.st_size) {
889        LOGE("offset error");
890        ::close(fd);
891        return UNKNOWN_ERROR;
892    }
893    if (offset + length > sb.st_size) {
894        length = sb.st_size - offset;
895        LOGV("calculated length = %lld", length);
896    }
897
898    player_type playerType = getPlayerType(fd, offset, length);
899    LOGV("player type = %d", playerType);
900
901    // create the right type of player
902    sp<MediaPlayerBase> p = createPlayer(playerType);
903    if (p == NULL) return NO_INIT;
904
905    if (!p->hardwareOutput()) {
906        mAudioOutput = new AudioOutput(mAudioSessionId);
907        static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
908    }
909
910    // now set data source
911    mStatus = p->setDataSource(fd, offset, length);
912    if (mStatus == NO_ERROR) mPlayer = p;
913    return mStatus;
914}
915
916status_t MediaPlayerService::Client::setDataSource(
917        const sp<IStreamSource> &source) {
918    // create the right type of player
919    sp<MediaPlayerBase> p = createPlayer(NU_PLAYER);
920
921    if (p == NULL) {
922        return NO_INIT;
923    }
924
925    if (!p->hardwareOutput()) {
926        mAudioOutput = new AudioOutput(mAudioSessionId);
927        static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
928    }
929
930    // now set data source
931    mStatus = p->setDataSource(source);
932
933    if (mStatus == OK) {
934        mPlayer = p;
935    }
936
937    return mStatus;
938}
939
940status_t MediaPlayerService::Client::setVideoSurface(const sp<Surface>& surface)
941{
942    LOGV("[%d] setVideoSurface(%p)", mConnId, surface.get());
943    sp<MediaPlayerBase> p = getPlayer();
944    if (p == 0) return UNKNOWN_ERROR;
945    return p->setVideoSurface(surface);
946}
947
948status_t MediaPlayerService::Client::setVideoSurfaceTexture(
949        const sp<ISurfaceTexture>& surfaceTexture)
950{
951    LOGV("[%d] setVideoSurfaceTexture(%p)", mConnId, surfaceTexture.get());
952    sp<MediaPlayerBase> p = getPlayer();
953    if (p == 0) return UNKNOWN_ERROR;
954    return p->setVideoSurfaceTexture(surfaceTexture);
955}
956
957status_t MediaPlayerService::Client::invoke(const Parcel& request,
958                                            Parcel *reply)
959{
960    sp<MediaPlayerBase> p = getPlayer();
961    if (p == NULL) return UNKNOWN_ERROR;
962    return p->invoke(request, reply);
963}
964
965// This call doesn't need to access the native player.
966status_t MediaPlayerService::Client::setMetadataFilter(const Parcel& filter)
967{
968    status_t status;
969    media::Metadata::Filter allow, drop;
970
971    if (unmarshallFilter(filter, &allow, &status) &&
972        unmarshallFilter(filter, &drop, &status)) {
973        Mutex::Autolock lock(mLock);
974
975        mMetadataAllow = allow;
976        mMetadataDrop = drop;
977    }
978    return status;
979}
980
981status_t MediaPlayerService::Client::getMetadata(
982        bool update_only, bool apply_filter, Parcel *reply)
983{
984    sp<MediaPlayerBase> player = getPlayer();
985    if (player == 0) return UNKNOWN_ERROR;
986
987    status_t status;
988    // Placeholder for the return code, updated by the caller.
989    reply->writeInt32(-1);
990
991    media::Metadata::Filter ids;
992
993    // We don't block notifications while we fetch the data. We clear
994    // mMetadataUpdated first so we don't lose notifications happening
995    // during the rest of this call.
996    {
997        Mutex::Autolock lock(mLock);
998        if (update_only) {
999            ids = mMetadataUpdated;
1000        }
1001        mMetadataUpdated.clear();
1002    }
1003
1004    media::Metadata metadata(reply);
1005
1006    metadata.appendHeader();
1007    status = player->getMetadata(ids, reply);
1008
1009    if (status != OK) {
1010        metadata.resetParcel();
1011        LOGE("getMetadata failed %d", status);
1012        return status;
1013    }
1014
1015    // FIXME: Implement filtering on the result. Not critical since
1016    // filtering takes place on the update notifications already. This
1017    // would be when all the metadata are fetch and a filter is set.
1018
1019    // Everything is fine, update the metadata length.
1020    metadata.updateLength();
1021    return OK;
1022}
1023
1024status_t MediaPlayerService::Client::prepareAsync()
1025{
1026    LOGV("[%d] prepareAsync", mConnId);
1027    sp<MediaPlayerBase> p = getPlayer();
1028    if (p == 0) return UNKNOWN_ERROR;
1029    status_t ret = p->prepareAsync();
1030#if CALLBACK_ANTAGONIZER
1031    LOGD("start Antagonizer");
1032    if (ret == NO_ERROR) mAntagonizer->start();
1033#endif
1034    return ret;
1035}
1036
1037status_t MediaPlayerService::Client::start()
1038{
1039    LOGV("[%d] start", mConnId);
1040    sp<MediaPlayerBase> p = getPlayer();
1041    if (p == 0) return UNKNOWN_ERROR;
1042    p->setLooping(mLoop);
1043    return p->start();
1044}
1045
1046status_t MediaPlayerService::Client::stop()
1047{
1048    LOGV("[%d] stop", mConnId);
1049    sp<MediaPlayerBase> p = getPlayer();
1050    if (p == 0) return UNKNOWN_ERROR;
1051    return p->stop();
1052}
1053
1054status_t MediaPlayerService::Client::pause()
1055{
1056    LOGV("[%d] pause", mConnId);
1057    sp<MediaPlayerBase> p = getPlayer();
1058    if (p == 0) return UNKNOWN_ERROR;
1059    return p->pause();
1060}
1061
1062status_t MediaPlayerService::Client::isPlaying(bool* state)
1063{
1064    *state = false;
1065    sp<MediaPlayerBase> p = getPlayer();
1066    if (p == 0) return UNKNOWN_ERROR;
1067    *state = p->isPlaying();
1068    LOGV("[%d] isPlaying: %d", mConnId, *state);
1069    return NO_ERROR;
1070}
1071
1072status_t MediaPlayerService::Client::getCurrentPosition(int *msec)
1073{
1074    LOGV("getCurrentPosition");
1075    sp<MediaPlayerBase> p = getPlayer();
1076    if (p == 0) return UNKNOWN_ERROR;
1077    status_t ret = p->getCurrentPosition(msec);
1078    if (ret == NO_ERROR) {
1079        LOGV("[%d] getCurrentPosition = %d", mConnId, *msec);
1080    } else {
1081        LOGE("getCurrentPosition returned %d", ret);
1082    }
1083    return ret;
1084}
1085
1086status_t MediaPlayerService::Client::getDuration(int *msec)
1087{
1088    LOGV("getDuration");
1089    sp<MediaPlayerBase> p = getPlayer();
1090    if (p == 0) return UNKNOWN_ERROR;
1091    status_t ret = p->getDuration(msec);
1092    if (ret == NO_ERROR) {
1093        LOGV("[%d] getDuration = %d", mConnId, *msec);
1094    } else {
1095        LOGE("getDuration returned %d", ret);
1096    }
1097    return ret;
1098}
1099
1100status_t MediaPlayerService::Client::seekTo(int msec)
1101{
1102    LOGV("[%d] seekTo(%d)", mConnId, msec);
1103    sp<MediaPlayerBase> p = getPlayer();
1104    if (p == 0) return UNKNOWN_ERROR;
1105    return p->seekTo(msec);
1106}
1107
1108status_t MediaPlayerService::Client::reset()
1109{
1110    LOGV("[%d] reset", mConnId);
1111    sp<MediaPlayerBase> p = getPlayer();
1112    if (p == 0) return UNKNOWN_ERROR;
1113    return p->reset();
1114}
1115
1116status_t MediaPlayerService::Client::setAudioStreamType(int type)
1117{
1118    LOGV("[%d] setAudioStreamType(%d)", mConnId, type);
1119    // TODO: for hardware output, call player instead
1120    Mutex::Autolock l(mLock);
1121    if (mAudioOutput != 0) mAudioOutput->setAudioStreamType(type);
1122    return NO_ERROR;
1123}
1124
1125status_t MediaPlayerService::Client::setLooping(int loop)
1126{
1127    LOGV("[%d] setLooping(%d)", mConnId, loop);
1128    mLoop = loop;
1129    sp<MediaPlayerBase> p = getPlayer();
1130    if (p != 0) return p->setLooping(loop);
1131    return NO_ERROR;
1132}
1133
1134status_t MediaPlayerService::Client::setVolume(float leftVolume, float rightVolume)
1135{
1136    LOGV("[%d] setVolume(%f, %f)", mConnId, leftVolume, rightVolume);
1137    // TODO: for hardware output, call player instead
1138    Mutex::Autolock l(mLock);
1139    if (mAudioOutput != 0) mAudioOutput->setVolume(leftVolume, rightVolume);
1140    return NO_ERROR;
1141}
1142
1143status_t MediaPlayerService::Client::setAuxEffectSendLevel(float level)
1144{
1145    LOGV("[%d] setAuxEffectSendLevel(%f)", mConnId, level);
1146    Mutex::Autolock l(mLock);
1147    if (mAudioOutput != 0) return mAudioOutput->setAuxEffectSendLevel(level);
1148    return NO_ERROR;
1149}
1150
1151status_t MediaPlayerService::Client::attachAuxEffect(int effectId)
1152{
1153    LOGV("[%d] attachAuxEffect(%d)", mConnId, effectId);
1154    Mutex::Autolock l(mLock);
1155    if (mAudioOutput != 0) return mAudioOutput->attachAuxEffect(effectId);
1156    return NO_ERROR;
1157}
1158
1159void MediaPlayerService::Client::notify(void* cookie, int msg, int ext1, int ext2)
1160{
1161    Client* client = static_cast<Client*>(cookie);
1162
1163    if (MEDIA_INFO == msg &&
1164        MEDIA_INFO_METADATA_UPDATE == ext1) {
1165        const media::Metadata::Type metadata_type = ext2;
1166
1167        if(client->shouldDropMetadata(metadata_type)) {
1168            return;
1169        }
1170
1171        // Update the list of metadata that have changed. getMetadata
1172        // also access mMetadataUpdated and clears it.
1173        client->addNewMetadataUpdate(metadata_type);
1174    }
1175    LOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, cookie, msg, ext1, ext2);
1176    client->mClient->notify(msg, ext1, ext2);
1177}
1178
1179
1180bool MediaPlayerService::Client::shouldDropMetadata(media::Metadata::Type code) const
1181{
1182    Mutex::Autolock lock(mLock);
1183
1184    if (findMetadata(mMetadataDrop, code)) {
1185        return true;
1186    }
1187
1188    if (mMetadataAllow.isEmpty() || findMetadata(mMetadataAllow, code)) {
1189        return false;
1190    } else {
1191        return true;
1192    }
1193}
1194
1195
1196void MediaPlayerService::Client::addNewMetadataUpdate(media::Metadata::Type metadata_type) {
1197    Mutex::Autolock lock(mLock);
1198    if (mMetadataUpdated.indexOf(metadata_type) < 0) {
1199        mMetadataUpdated.add(metadata_type);
1200    }
1201}
1202
1203#if CALLBACK_ANTAGONIZER
1204const int Antagonizer::interval = 10000; // 10 msecs
1205
1206Antagonizer::Antagonizer(notify_callback_f cb, void* client) :
1207    mExit(false), mActive(false), mClient(client), mCb(cb)
1208{
1209    createThread(callbackThread, this);
1210}
1211
1212void Antagonizer::kill()
1213{
1214    Mutex::Autolock _l(mLock);
1215    mActive = false;
1216    mExit = true;
1217    mCondition.wait(mLock);
1218}
1219
1220int Antagonizer::callbackThread(void* user)
1221{
1222    LOGD("Antagonizer started");
1223    Antagonizer* p = reinterpret_cast<Antagonizer*>(user);
1224    while (!p->mExit) {
1225        if (p->mActive) {
1226            LOGV("send event");
1227            p->mCb(p->mClient, 0, 0, 0);
1228        }
1229        usleep(interval);
1230    }
1231    Mutex::Autolock _l(p->mLock);
1232    p->mCondition.signal();
1233    LOGD("Antagonizer stopped");
1234    return 0;
1235}
1236#endif
1237
1238static size_t kDefaultHeapSize = 1024 * 1024; // 1MB
1239
1240sp<IMemory> MediaPlayerService::decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
1241{
1242    LOGV("decode(%s)", url);
1243    sp<MemoryBase> mem;
1244    sp<MediaPlayerBase> player;
1245
1246    // Protect our precious, precious DRMd ringtones by only allowing
1247    // decoding of http, but not filesystem paths or content Uris.
1248    // If the application wants to decode those, it should open a
1249    // filedescriptor for them and use that.
1250    if (url != NULL && strncmp(url, "http://", 7) != 0) {
1251        LOGD("Can't decode %s by path, use filedescriptor instead", url);
1252        return mem;
1253    }
1254
1255    player_type playerType = getPlayerType(url);
1256    LOGV("player type = %d", playerType);
1257
1258    // create the right type of player
1259    sp<AudioCache> cache = new AudioCache(url);
1260    player = android::createPlayer(playerType, cache.get(), cache->notify);
1261    if (player == NULL) goto Exit;
1262    if (player->hardwareOutput()) goto Exit;
1263
1264    static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache);
1265
1266    // set data source
1267    if (player->setDataSource(url) != NO_ERROR) goto Exit;
1268
1269    LOGV("prepare");
1270    player->prepareAsync();
1271
1272    LOGV("wait for prepare");
1273    if (cache->wait() != NO_ERROR) goto Exit;
1274
1275    LOGV("start");
1276    player->start();
1277
1278    LOGV("wait for playback complete");
1279    if (cache->wait() != NO_ERROR) goto Exit;
1280
1281    mem = new MemoryBase(cache->getHeap(), 0, cache->size());
1282    *pSampleRate = cache->sampleRate();
1283    *pNumChannels = cache->channelCount();
1284    *pFormat = cache->format();
1285    LOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat);
1286
1287Exit:
1288    if (player != 0) player->reset();
1289    return mem;
1290}
1291
1292sp<IMemory> MediaPlayerService::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
1293{
1294    LOGV("decode(%d, %lld, %lld)", fd, offset, length);
1295    sp<MemoryBase> mem;
1296    sp<MediaPlayerBase> player;
1297
1298    player_type playerType = getPlayerType(fd, offset, length);
1299    LOGV("player type = %d", playerType);
1300
1301    // create the right type of player
1302    sp<AudioCache> cache = new AudioCache("decode_fd");
1303    player = android::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(fd, offset, length) != NO_ERROR) goto Exit;
1311
1312    LOGV("prepare");
1313    player->prepareAsync();
1314
1315    LOGV("wait for prepare");
1316    if (cache->wait() != NO_ERROR) goto Exit;
1317
1318    LOGV("start");
1319    player->start();
1320
1321    LOGV("wait for playback complete");
1322    if (cache->wait() != NO_ERROR) goto Exit;
1323
1324    mem = new MemoryBase(cache->getHeap(), 0, cache->size());
1325    *pSampleRate = cache->sampleRate();
1326    *pNumChannels = cache->channelCount();
1327    *pFormat = cache->format();
1328    LOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat);
1329
1330Exit:
1331    if (player != 0) player->reset();
1332    ::close(fd);
1333    return mem;
1334}
1335
1336
1337#undef LOG_TAG
1338#define LOG_TAG "AudioSink"
1339MediaPlayerService::AudioOutput::AudioOutput(int sessionId)
1340    : mCallback(NULL),
1341      mCallbackCookie(NULL),
1342      mSessionId(sessionId) {
1343    LOGV("AudioOutput(%d)", sessionId);
1344    mTrack = 0;
1345    mStreamType = AudioSystem::MUSIC;
1346    mLeftVolume = 1.0;
1347    mRightVolume = 1.0;
1348    mLatency = 0;
1349    mMsecsPerFrame = 0;
1350    mAuxEffectId = 0;
1351    mSendLevel = 0.0;
1352    setMinBufferCount();
1353}
1354
1355MediaPlayerService::AudioOutput::~AudioOutput()
1356{
1357    close();
1358}
1359
1360void MediaPlayerService::AudioOutput::setMinBufferCount()
1361{
1362    char value[PROPERTY_VALUE_MAX];
1363    if (property_get("ro.kernel.qemu", value, 0)) {
1364        mIsOnEmulator = true;
1365        mMinBufferCount = 12;  // to prevent systematic buffer underrun for emulator
1366    }
1367}
1368
1369bool MediaPlayerService::AudioOutput::isOnEmulator()
1370{
1371    setMinBufferCount();
1372    return mIsOnEmulator;
1373}
1374
1375int MediaPlayerService::AudioOutput::getMinBufferCount()
1376{
1377    setMinBufferCount();
1378    return mMinBufferCount;
1379}
1380
1381ssize_t MediaPlayerService::AudioOutput::bufferSize() const
1382{
1383    if (mTrack == 0) return NO_INIT;
1384    return mTrack->frameCount() * frameSize();
1385}
1386
1387ssize_t MediaPlayerService::AudioOutput::frameCount() const
1388{
1389    if (mTrack == 0) return NO_INIT;
1390    return mTrack->frameCount();
1391}
1392
1393ssize_t MediaPlayerService::AudioOutput::channelCount() const
1394{
1395    if (mTrack == 0) return NO_INIT;
1396    return mTrack->channelCount();
1397}
1398
1399ssize_t MediaPlayerService::AudioOutput::frameSize() const
1400{
1401    if (mTrack == 0) return NO_INIT;
1402    return mTrack->frameSize();
1403}
1404
1405uint32_t MediaPlayerService::AudioOutput::latency () const
1406{
1407    return mLatency;
1408}
1409
1410float MediaPlayerService::AudioOutput::msecsPerFrame() const
1411{
1412    return mMsecsPerFrame;
1413}
1414
1415status_t MediaPlayerService::AudioOutput::getPosition(uint32_t *position)
1416{
1417    if (mTrack == 0) return NO_INIT;
1418    return mTrack->getPosition(position);
1419}
1420
1421status_t MediaPlayerService::AudioOutput::open(
1422        uint32_t sampleRate, int channelCount, int format, int bufferCount,
1423        AudioCallback cb, void *cookie)
1424{
1425    mCallback = cb;
1426    mCallbackCookie = cookie;
1427
1428    // Check argument "bufferCount" against the mininum buffer count
1429    if (bufferCount < mMinBufferCount) {
1430        LOGD("bufferCount (%d) is too small and increased to %d", bufferCount, mMinBufferCount);
1431        bufferCount = mMinBufferCount;
1432
1433    }
1434    LOGV("open(%u, %d, %d, %d, %d)", sampleRate, channelCount, format, bufferCount,mSessionId);
1435    if (mTrack) close();
1436    int afSampleRate;
1437    int afFrameCount;
1438    int frameCount;
1439
1440    if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) != NO_ERROR) {
1441        return NO_INIT;
1442    }
1443    if (AudioSystem::getOutputSamplingRate(&afSampleRate, mStreamType) != NO_ERROR) {
1444        return NO_INIT;
1445    }
1446
1447    frameCount = (sampleRate*afFrameCount*bufferCount)/afSampleRate;
1448
1449    AudioTrack *t;
1450    if (mCallback != NULL) {
1451        t = new AudioTrack(
1452                mStreamType,
1453                sampleRate,
1454                format,
1455                (channelCount == 2) ? AudioSystem::CHANNEL_OUT_STEREO : AudioSystem::CHANNEL_OUT_MONO,
1456                frameCount,
1457                0 /* flags */,
1458                CallbackWrapper,
1459                this,
1460                0,
1461                mSessionId);
1462    } else {
1463        t = new AudioTrack(
1464                mStreamType,
1465                sampleRate,
1466                format,
1467                (channelCount == 2) ? AudioSystem::CHANNEL_OUT_STEREO : AudioSystem::CHANNEL_OUT_MONO,
1468                frameCount,
1469                0,
1470                NULL,
1471                NULL,
1472                0,
1473                mSessionId);
1474    }
1475
1476    if ((t == 0) || (t->initCheck() != NO_ERROR)) {
1477        LOGE("Unable to create audio track");
1478        delete t;
1479        return NO_INIT;
1480    }
1481
1482    LOGV("setVolume");
1483    t->setVolume(mLeftVolume, mRightVolume);
1484
1485    mMsecsPerFrame = 1.e3 / (float) sampleRate;
1486    mLatency = t->latency();
1487    mTrack = t;
1488
1489    t->setAuxEffectSendLevel(mSendLevel);
1490    return t->attachAuxEffect(mAuxEffectId);;
1491}
1492
1493void MediaPlayerService::AudioOutput::start()
1494{
1495    LOGV("start");
1496    if (mTrack) {
1497        mTrack->setVolume(mLeftVolume, mRightVolume);
1498        mTrack->setAuxEffectSendLevel(mSendLevel);
1499        mTrack->start();
1500    }
1501}
1502
1503
1504
1505ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size)
1506{
1507    LOG_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback.");
1508
1509    //LOGV("write(%p, %u)", buffer, size);
1510    if (mTrack) {
1511        ssize_t ret = mTrack->write(buffer, size);
1512        return ret;
1513    }
1514    return NO_INIT;
1515}
1516
1517void MediaPlayerService::AudioOutput::stop()
1518{
1519    LOGV("stop");
1520    if (mTrack) mTrack->stop();
1521}
1522
1523void MediaPlayerService::AudioOutput::flush()
1524{
1525    LOGV("flush");
1526    if (mTrack) mTrack->flush();
1527}
1528
1529void MediaPlayerService::AudioOutput::pause()
1530{
1531    LOGV("pause");
1532    if (mTrack) mTrack->pause();
1533}
1534
1535void MediaPlayerService::AudioOutput::close()
1536{
1537    LOGV("close");
1538    delete mTrack;
1539    mTrack = 0;
1540}
1541
1542void MediaPlayerService::AudioOutput::setVolume(float left, float right)
1543{
1544    LOGV("setVolume(%f, %f)", left, right);
1545    mLeftVolume = left;
1546    mRightVolume = right;
1547    if (mTrack) {
1548        mTrack->setVolume(left, right);
1549    }
1550}
1551
1552status_t MediaPlayerService::AudioOutput::setAuxEffectSendLevel(float level)
1553{
1554    LOGV("setAuxEffectSendLevel(%f)", level);
1555    mSendLevel = level;
1556    if (mTrack) {
1557        return mTrack->setAuxEffectSendLevel(level);
1558    }
1559    return NO_ERROR;
1560}
1561
1562status_t MediaPlayerService::AudioOutput::attachAuxEffect(int effectId)
1563{
1564    LOGV("attachAuxEffect(%d)", effectId);
1565    mAuxEffectId = effectId;
1566    if (mTrack) {
1567        return mTrack->attachAuxEffect(effectId);
1568    }
1569    return NO_ERROR;
1570}
1571
1572// static
1573void MediaPlayerService::AudioOutput::CallbackWrapper(
1574        int event, void *cookie, void *info) {
1575    //LOGV("callbackwrapper");
1576    if (event != AudioTrack::EVENT_MORE_DATA) {
1577        return;
1578    }
1579
1580    AudioOutput *me = (AudioOutput *)cookie;
1581    AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
1582
1583    size_t actualSize = (*me->mCallback)(
1584            me, buffer->raw, buffer->size, me->mCallbackCookie);
1585
1586    buffer->size = actualSize;
1587
1588}
1589
1590int MediaPlayerService::AudioOutput::getSessionId()
1591{
1592    return mSessionId;
1593}
1594
1595#undef LOG_TAG
1596#define LOG_TAG "AudioCache"
1597MediaPlayerService::AudioCache::AudioCache(const char* name) :
1598    mChannelCount(0), mFrameCount(1024), mSampleRate(0), mSize(0),
1599    mError(NO_ERROR), mCommandComplete(false)
1600{
1601    // create ashmem heap
1602    mHeap = new MemoryHeapBase(kDefaultHeapSize, 0, name);
1603}
1604
1605uint32_t MediaPlayerService::AudioCache::latency () const
1606{
1607    return 0;
1608}
1609
1610float MediaPlayerService::AudioCache::msecsPerFrame() const
1611{
1612    return mMsecsPerFrame;
1613}
1614
1615status_t MediaPlayerService::AudioCache::getPosition(uint32_t *position)
1616{
1617    if (position == 0) return BAD_VALUE;
1618    *position = mSize;
1619    return NO_ERROR;
1620}
1621
1622////////////////////////////////////////////////////////////////////////////////
1623
1624struct CallbackThread : public Thread {
1625    CallbackThread(const wp<MediaPlayerBase::AudioSink> &sink,
1626                   MediaPlayerBase::AudioSink::AudioCallback cb,
1627                   void *cookie);
1628
1629protected:
1630    virtual ~CallbackThread();
1631
1632    virtual bool threadLoop();
1633
1634private:
1635    wp<MediaPlayerBase::AudioSink> mSink;
1636    MediaPlayerBase::AudioSink::AudioCallback mCallback;
1637    void *mCookie;
1638    void *mBuffer;
1639    size_t mBufferSize;
1640
1641    CallbackThread(const CallbackThread &);
1642    CallbackThread &operator=(const CallbackThread &);
1643};
1644
1645CallbackThread::CallbackThread(
1646        const wp<MediaPlayerBase::AudioSink> &sink,
1647        MediaPlayerBase::AudioSink::AudioCallback cb,
1648        void *cookie)
1649    : mSink(sink),
1650      mCallback(cb),
1651      mCookie(cookie),
1652      mBuffer(NULL),
1653      mBufferSize(0) {
1654}
1655
1656CallbackThread::~CallbackThread() {
1657    if (mBuffer) {
1658        free(mBuffer);
1659        mBuffer = NULL;
1660    }
1661}
1662
1663bool CallbackThread::threadLoop() {
1664    sp<MediaPlayerBase::AudioSink> sink = mSink.promote();
1665    if (sink == NULL) {
1666        return false;
1667    }
1668
1669    if (mBuffer == NULL) {
1670        mBufferSize = sink->bufferSize();
1671        mBuffer = malloc(mBufferSize);
1672    }
1673
1674    size_t actualSize =
1675        (*mCallback)(sink.get(), mBuffer, mBufferSize, mCookie);
1676
1677    if (actualSize > 0) {
1678        sink->write(mBuffer, actualSize);
1679    }
1680
1681    return true;
1682}
1683
1684////////////////////////////////////////////////////////////////////////////////
1685
1686status_t MediaPlayerService::AudioCache::open(
1687        uint32_t sampleRate, int channelCount, int format, int bufferCount,
1688        AudioCallback cb, void *cookie)
1689{
1690    LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount);
1691    if (mHeap->getHeapID() < 0) {
1692        return NO_INIT;
1693    }
1694
1695    mSampleRate = sampleRate;
1696    mChannelCount = (uint16_t)channelCount;
1697    mFormat = (uint16_t)format;
1698    mMsecsPerFrame = 1.e3 / (float) sampleRate;
1699
1700    if (cb != NULL) {
1701        mCallbackThread = new CallbackThread(this, cb, cookie);
1702    }
1703    return NO_ERROR;
1704}
1705
1706void MediaPlayerService::AudioCache::start() {
1707    if (mCallbackThread != NULL) {
1708        mCallbackThread->run("AudioCache callback");
1709    }
1710}
1711
1712void MediaPlayerService::AudioCache::stop() {
1713    if (mCallbackThread != NULL) {
1714        mCallbackThread->requestExitAndWait();
1715    }
1716}
1717
1718ssize_t MediaPlayerService::AudioCache::write(const void* buffer, size_t size)
1719{
1720    LOGV("write(%p, %u)", buffer, size);
1721    if ((buffer == 0) || (size == 0)) return size;
1722
1723    uint8_t* p = static_cast<uint8_t*>(mHeap->getBase());
1724    if (p == NULL) return NO_INIT;
1725    p += mSize;
1726    LOGV("memcpy(%p, %p, %u)", p, buffer, size);
1727    if (mSize + size > mHeap->getSize()) {
1728        LOGE("Heap size overflow! req size: %d, max size: %d", (mSize + size), mHeap->getSize());
1729        size = mHeap->getSize() - mSize;
1730    }
1731    memcpy(p, buffer, size);
1732    mSize += size;
1733    return size;
1734}
1735
1736// call with lock held
1737status_t MediaPlayerService::AudioCache::wait()
1738{
1739    Mutex::Autolock lock(mLock);
1740    while (!mCommandComplete) {
1741        mSignal.wait(mLock);
1742    }
1743    mCommandComplete = false;
1744
1745    if (mError == NO_ERROR) {
1746        LOGV("wait - success");
1747    } else {
1748        LOGV("wait - error");
1749    }
1750    return mError;
1751}
1752
1753void MediaPlayerService::AudioCache::notify(void* cookie, int msg, int ext1, int ext2)
1754{
1755    LOGV("notify(%p, %d, %d, %d)", cookie, msg, ext1, ext2);
1756    AudioCache* p = static_cast<AudioCache*>(cookie);
1757
1758    // ignore buffering messages
1759    switch (msg)
1760    {
1761    case MEDIA_ERROR:
1762        LOGE("Error %d, %d occurred", ext1, ext2);
1763        p->mError = ext1;
1764        break;
1765    case MEDIA_PREPARED:
1766        LOGV("prepared");
1767        break;
1768    case MEDIA_PLAYBACK_COMPLETE:
1769        LOGV("playback complete");
1770        break;
1771    default:
1772        LOGV("ignored");
1773        return;
1774    }
1775
1776    // wake up thread
1777    Mutex::Autolock lock(p->mLock);
1778    p->mCommandComplete = true;
1779    p->mSignal.signal();
1780}
1781
1782int MediaPlayerService::AudioCache::getSessionId()
1783{
1784    return 0;
1785}
1786
1787void MediaPlayerService::addBatteryData(uint32_t params)
1788{
1789    Mutex::Autolock lock(mLock);
1790
1791    int32_t time = systemTime() / 1000000L;
1792
1793    // change audio output devices. This notification comes from AudioFlinger
1794    if ((params & kBatteryDataSpeakerOn)
1795            || (params & kBatteryDataOtherAudioDeviceOn)) {
1796
1797        int deviceOn[NUM_AUDIO_DEVICES];
1798        for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
1799            deviceOn[i] = 0;
1800        }
1801
1802        if ((params & kBatteryDataSpeakerOn)
1803                && (params & kBatteryDataOtherAudioDeviceOn)) {
1804            deviceOn[SPEAKER_AND_OTHER] = 1;
1805        } else if (params & kBatteryDataSpeakerOn) {
1806            deviceOn[SPEAKER] = 1;
1807        } else {
1808            deviceOn[OTHER_AUDIO_DEVICE] = 1;
1809        }
1810
1811        for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
1812            if (mBatteryAudio.deviceOn[i] != deviceOn[i]){
1813
1814                if (mBatteryAudio.refCount > 0) { // if playing audio
1815                    if (!deviceOn[i]) {
1816                        mBatteryAudio.lastTime[i] += time;
1817                        mBatteryAudio.totalTime[i] += mBatteryAudio.lastTime[i];
1818                        mBatteryAudio.lastTime[i] = 0;
1819                    } else {
1820                        mBatteryAudio.lastTime[i] = 0 - time;
1821                    }
1822                }
1823
1824                mBatteryAudio.deviceOn[i] = deviceOn[i];
1825            }
1826        }
1827        return;
1828    }
1829
1830    // an sudio stream is started
1831    if (params & kBatteryDataAudioFlingerStart) {
1832        // record the start time only if currently no other audio
1833        // is being played
1834        if (mBatteryAudio.refCount == 0) {
1835            for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
1836                if (mBatteryAudio.deviceOn[i]) {
1837                    mBatteryAudio.lastTime[i] -= time;
1838                }
1839            }
1840        }
1841
1842        mBatteryAudio.refCount ++;
1843        return;
1844
1845    } else if (params & kBatteryDataAudioFlingerStop) {
1846        if (mBatteryAudio.refCount <= 0) {
1847            LOGW("Battery track warning: refCount is <= 0");
1848            return;
1849        }
1850
1851        // record the stop time only if currently this is the only
1852        // audio being played
1853        if (mBatteryAudio.refCount == 1) {
1854            for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
1855                if (mBatteryAudio.deviceOn[i]) {
1856                    mBatteryAudio.lastTime[i] += time;
1857                    mBatteryAudio.totalTime[i] += mBatteryAudio.lastTime[i];
1858                    mBatteryAudio.lastTime[i] = 0;
1859                }
1860            }
1861        }
1862
1863        mBatteryAudio.refCount --;
1864        return;
1865    }
1866
1867    int uid = IPCThreadState::self()->getCallingUid();
1868    if (uid == AID_MEDIA) {
1869        return;
1870    }
1871    int index = mBatteryData.indexOfKey(uid);
1872
1873    if (index < 0) { // create a new entry for this UID
1874        BatteryUsageInfo info;
1875        info.audioTotalTime = 0;
1876        info.videoTotalTime = 0;
1877        info.audioLastTime = 0;
1878        info.videoLastTime = 0;
1879        info.refCount = 0;
1880
1881        if (mBatteryData.add(uid, info) == NO_MEMORY) {
1882            LOGE("Battery track error: no memory for new app");
1883            return;
1884        }
1885    }
1886
1887    BatteryUsageInfo &info = mBatteryData.editValueFor(uid);
1888
1889    if (params & kBatteryDataCodecStarted) {
1890        if (params & kBatteryDataTrackAudio) {
1891            info.audioLastTime -= time;
1892            info.refCount ++;
1893        }
1894        if (params & kBatteryDataTrackVideo) {
1895            info.videoLastTime -= time;
1896            info.refCount ++;
1897        }
1898    } else {
1899        if (info.refCount == 0) {
1900            LOGW("Battery track warning: refCount is already 0");
1901            return;
1902        } else if (info.refCount < 0) {
1903            LOGE("Battery track error: refCount < 0");
1904            mBatteryData.removeItem(uid);
1905            return;
1906        }
1907
1908        if (params & kBatteryDataTrackAudio) {
1909            info.audioLastTime += time;
1910            info.refCount --;
1911        }
1912        if (params & kBatteryDataTrackVideo) {
1913            info.videoLastTime += time;
1914            info.refCount --;
1915        }
1916
1917        // no stream is being played by this UID
1918        if (info.refCount == 0) {
1919            info.audioTotalTime += info.audioLastTime;
1920            info.audioLastTime = 0;
1921            info.videoTotalTime += info.videoLastTime;
1922            info.videoLastTime = 0;
1923        }
1924    }
1925}
1926
1927status_t MediaPlayerService::pullBatteryData(Parcel* reply) {
1928    Mutex::Autolock lock(mLock);
1929
1930    // audio output devices usage
1931    int32_t time = systemTime() / 1000000L; //in ms
1932    int32_t totalTime;
1933
1934    for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
1935        totalTime = mBatteryAudio.totalTime[i];
1936
1937        if (mBatteryAudio.deviceOn[i]
1938            && (mBatteryAudio.lastTime[i] != 0)) {
1939                int32_t tmpTime = mBatteryAudio.lastTime[i] + time;
1940                totalTime += tmpTime;
1941        }
1942
1943        reply->writeInt32(totalTime);
1944        // reset the total time
1945        mBatteryAudio.totalTime[i] = 0;
1946   }
1947
1948    // codec usage
1949    BatteryUsageInfo info;
1950    int size = mBatteryData.size();
1951
1952    reply->writeInt32(size);
1953    int i = 0;
1954
1955    while (i < size) {
1956        info = mBatteryData.valueAt(i);
1957
1958        reply->writeInt32(mBatteryData.keyAt(i)); //UID
1959        reply->writeInt32(info.audioTotalTime);
1960        reply->writeInt32(info.videoTotalTime);
1961
1962        info.audioTotalTime = 0;
1963        info.videoTotalTime = 0;
1964
1965        // remove the UID entry where no stream is being played
1966        if (info.refCount <= 0) {
1967            mBatteryData.removeItemsAt(i);
1968            size --;
1969            i --;
1970        }
1971        i++;
1972    }
1973    return NO_ERROR;
1974}
1975} // namespace android
1976