MediaPlayerService.cpp revision 2729ea9262ca60d93047e984739887cfc89e82eb
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 <dirent.h>
27#include <unistd.h>
28
29#include <string.h>
30#include <cutils/atomic.h>
31
32#include <android_runtime/ActivityManager.h>
33#include <utils/IPCThreadState.h>
34#include <utils/IServiceManager.h>
35#include <utils/MemoryHeapBase.h>
36#include <utils/MemoryBase.h>
37
38#include <media/MediaPlayerInterface.h>
39#include <media/AudioTrack.h>
40
41#include "MediaPlayerService.h"
42#include "MidiFile.h"
43#include "VorbisPlayer.h"
44#include <media/PVPlayer.h>
45
46/* desktop Linux needs a little help with gettid() */
47#if defined(HAVE_GETTID) && !defined(HAVE_ANDROID_OS)
48#define __KERNEL__
49# include <linux/unistd.h>
50#ifdef _syscall0
51_syscall0(pid_t,gettid)
52#else
53pid_t gettid() { return syscall(__NR_gettid);}
54#endif
55#undef __KERNEL__
56#endif
57
58/*
59    When USE_SIGBUS_HANDLER is set to 1, a handler for SIGBUS will be
60    installed, which allows us to recover when there is a read error
61    when accessing an mmap'ed file. However, since the kernel folks
62    don't seem to like it when non kernel folks install signal handlers
63    in their own process, this is currently disabled.
64    Without the handler, the process hosting this service will die and
65    then be restarted. This is mostly OK right now because the process is
66    not being shared with any other services, and clients of the service
67    will be notified of its death in their MediaPlayer.onErrorListener
68    callback, assuming they have installed one, and can then attempt to
69    do their own recovery.
70    It does open us up to a DOS attack against the media server, where
71    a malicious application can trivially force the media server to
72    restart continuously.
73*/
74#define USE_SIGBUS_HANDLER 0
75
76// TODO: Temp hack until we can register players
77static const char* MIDI_FILE_EXTS[] =
78{
79        ".mid",
80        ".smf",
81        ".xmf",
82        ".imy",
83        ".rtttl",
84        ".rtx",
85        ".ota"
86};
87
88namespace android {
89
90// TODO: should come from audio driver
91/* static */ const uint32_t MediaPlayerService::AudioOutput::kDriverLatencyInMsecs = 150;
92
93static struct sigaction oldact;
94static pthread_key_t sigbuskey;
95
96static void sigbushandler(int signal, siginfo_t *info, void *context)
97{
98    char *faultaddr = (char*) info->si_addr;
99    LOGE("SIGBUS at %p\n", faultaddr);
100
101    struct mediasigbushandler* h = (struct mediasigbushandler*) pthread_getspecific(sigbuskey);
102
103    if (h) {
104        if (h->len) {
105            if (faultaddr < h->base || faultaddr >= h->base + h->len) {
106                // outside specified range, call old handler
107                if (oldact.sa_flags & SA_SIGINFO) {
108                    oldact.sa_sigaction(signal, info, context);
109                } else {
110                    oldact.sa_handler(signal);
111                }
112                return;
113            }
114        }
115
116        // no range specified or address was in range
117
118        if (h->handlesigbus) {
119            if (h->handlesigbus(info, h)) {
120                // thread's handler didn't handle the signal
121                if (oldact.sa_flags & SA_SIGINFO) {
122                    oldact.sa_sigaction(signal, info, context);
123                } else {
124                    oldact.sa_handler(signal);
125                }
126            }
127            return;
128        }
129
130        if (h->sigbusvar) {
131            // map in a zeroed out page so the operation can succeed
132            long pagesize = sysconf(_SC_PAGE_SIZE);
133            long pagemask = ~(pagesize - 1);
134            void * pageaddr = (void*) (((long)(faultaddr)) & pagemask);
135
136            void * bar = mmap( pageaddr, pagesize, PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE|MAP_FIXED, -1, 0);
137            if (bar == MAP_FAILED) {
138                LOGE("couldn't map zero page at %p: %s", pageaddr, strerror(errno));
139                if (oldact.sa_flags & SA_SIGINFO) {
140                    oldact.sa_sigaction(signal, info, context);
141                } else {
142                    oldact.sa_handler(signal);
143                }
144                return;
145            }
146
147            LOGE("setting sigbusvar at %p", h->sigbusvar);
148            *(h->sigbusvar) = 1;
149            return;
150        }
151    }
152
153    LOGE("SIGBUS: no handler, or improperly configured handler (%p)", h);
154
155    if (oldact.sa_flags & SA_SIGINFO) {
156        oldact.sa_sigaction(signal, info, context);
157    } else {
158        oldact.sa_handler(signal);
159    }
160    return;
161}
162
163void MediaPlayerService::instantiate() {
164    defaultServiceManager()->addService(
165            String16("media.player"), new MediaPlayerService());
166}
167
168MediaPlayerService::MediaPlayerService()
169{
170    LOGV("MediaPlayerService created");
171    mNextConnId = 1;
172
173    pthread_key_create(&sigbuskey, NULL);
174
175
176#if USE_SIGBUS_HANDLER
177    struct sigaction act;
178    memset(&act,0, sizeof act);
179    act.sa_sigaction = sigbushandler;
180    act.sa_flags = SA_SIGINFO;
181    sigaction(SIGBUS, &act, &oldact);
182#endif
183}
184
185MediaPlayerService::~MediaPlayerService()
186{
187#if USE_SIGBUS_HANDLER
188    sigaction(SIGBUS, &oldact, NULL);
189#endif
190    pthread_key_delete(sigbuskey);
191    LOGV("MediaPlayerService destroyed");
192}
193
194sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url)
195{
196    int32_t connId = android_atomic_inc(&mNextConnId);
197    sp<Client> c = new Client(this, pid, connId, client);
198    LOGV("Create new client(%d) from pid %d, url=%s, connId=%d", connId, pid, url, connId);
199    if (NO_ERROR != c->setDataSource(url))
200    {
201        c.clear();
202        return c;
203    }
204    wp<Client> w = c;
205    Mutex::Autolock lock(mLock);
206    mClients.add(w);
207    return c;
208}
209
210sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client,
211        int fd, int64_t offset, int64_t length)
212{
213    int32_t connId = android_atomic_inc(&mNextConnId);
214    sp<Client> c = new Client(this, pid, connId, client);
215    LOGV("Create new client(%d) from pid %d, fd=%d, offset=%lld, length=%lld",
216            connId, pid, fd, offset, length);
217    if (NO_ERROR != c->setDataSource(fd, offset, length)) {
218        c.clear();
219    } else {
220        wp<Client> w = c;
221        Mutex::Autolock lock(mLock);
222        mClients.add(w);
223    }
224    ::close(fd);
225    return c;
226}
227
228status_t MediaPlayerService::AudioCache::dump(int fd, const Vector<String16>& args) const
229{
230    const size_t SIZE = 256;
231    char buffer[SIZE];
232    String8 result;
233
234    result.append(" AudioCache\n");
235    if (mHeap != 0) {
236        snprintf(buffer, 255, "  heap base(%p), size(%d), flags(%d), device(%s)\n",
237                mHeap->getBase(), mHeap->getSize(), mHeap->getFlags(), mHeap->getDevice());
238        result.append(buffer);
239    }
240    snprintf(buffer, 255, "  msec per frame(%f), channel count(%ld), frame count(%ld)\n",
241            mMsecsPerFrame, mChannelCount, mFrameCount);
242    result.append(buffer);
243    snprintf(buffer, 255, "  sample rate(%d), size(%d), error(%d), command complete(%s)\n",
244            mSampleRate, mSize, mError, mCommandComplete?"true":"false");
245    result.append(buffer);
246    ::write(fd, result.string(), result.size());
247    return NO_ERROR;
248}
249
250status_t MediaPlayerService::AudioOutput::dump(int fd, const Vector<String16>& args) const
251{
252    const size_t SIZE = 256;
253    char buffer[SIZE];
254    String8 result;
255
256    result.append(" AudioOutput\n");
257    snprintf(buffer, 255, "  stream type(%d), left - right volume(%f, %f)\n",
258            mStreamType, mLeftVolume, mRightVolume);
259    result.append(buffer);
260    snprintf(buffer, 255, "  msec per frame(%f), latency (%d), driver latency(%d)\n",
261            mMsecsPerFrame, mLatency, kDriverLatencyInMsecs);
262    result.append(buffer);
263    ::write(fd, result.string(), result.size());
264    if (mTrack != 0) {
265        mTrack->dump(fd, args);
266    }
267    return NO_ERROR;
268}
269
270status_t MediaPlayerService::Client::dump(int fd, const Vector<String16>& args) const
271{
272    const size_t SIZE = 256;
273    char buffer[SIZE];
274    String8 result;
275    result.append(" Client\n");
276    snprintf(buffer, 255, "  pid(%d), connId(%d), status(%d), looping(%s)\n",
277            mPid, mConnId, mStatus, mLoop?"true": "false");
278    result.append(buffer);
279    write(fd, result.string(), result.size());
280    if (mAudioOutput != 0) {
281        mAudioOutput->dump(fd, args);
282    }
283    write(fd, "\n", 1);
284    return NO_ERROR;
285}
286
287static int myTid() {
288#ifdef HAVE_GETTID
289    return gettid();
290#else
291    return getpid();
292#endif
293}
294
295status_t MediaPlayerService::dump(int fd, const Vector<String16>& args)
296{
297    const size_t SIZE = 256;
298    char buffer[SIZE];
299    String8 result;
300    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
301        snprintf(buffer, SIZE, "Permission Denial: "
302                "can't dump MediaPlayerService from pid=%d, uid=%d\n",
303                IPCThreadState::self()->getCallingPid(),
304                IPCThreadState::self()->getCallingUid());
305        result.append(buffer);
306    } else {
307        Mutex::Autolock lock(mLock);
308        for (int i = 0, n = mClients.size(); i < n; ++i) {
309            sp<Client> c = mClients[i].promote();
310            if (c != 0) c->dump(fd, args);
311        }
312        result.append(" Files opened and/or mapped:\n");
313        snprintf(buffer, SIZE, "/proc/%d/maps", myTid());
314        FILE *f = fopen(buffer, "r");
315        if (f) {
316            while (!feof(f)) {
317                fgets(buffer, SIZE, f);
318                if (strstr(buffer, " /sdcard/") ||
319                    strstr(buffer, " /system/sounds/") ||
320                    strstr(buffer, " /system/media/")) {
321                    result.append("  ");
322                    result.append(buffer);
323                }
324            }
325            fclose(f);
326        } else {
327            result.append("couldn't open ");
328            result.append(buffer);
329            result.append("\n");
330        }
331
332        snprintf(buffer, SIZE, "/proc/%d/fd", myTid());
333        DIR *d = opendir(buffer);
334        if (d) {
335            struct dirent *ent;
336            while((ent = readdir(d)) != NULL) {
337                if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) {
338                    snprintf(buffer, SIZE, "/proc/%d/fd/%s", myTid(), ent->d_name);
339                    struct stat s;
340                    if (lstat(buffer, &s) == 0) {
341                        if ((s.st_mode & S_IFMT) == S_IFLNK) {
342                            char linkto[256];
343                            int len = readlink(buffer, linkto, sizeof(linkto));
344                            if(len > 0) {
345                                if(len > 255) {
346                                    linkto[252] = '.';
347                                    linkto[253] = '.';
348                                    linkto[254] = '.';
349                                    linkto[255] = 0;
350                                } else {
351                                    linkto[len] = 0;
352                                }
353                                if (strstr(linkto, "/sdcard/") == linkto ||
354                                    strstr(linkto, "/system/sounds/") == linkto ||
355                                    strstr(linkto, "/system/media/") == linkto) {
356                                    result.append("  ");
357                                    result.append(buffer);
358                                    result.append(" -> ");
359                                    result.append(linkto);
360                                    result.append("\n");
361                                }
362                            }
363                        } else {
364                            result.append("  unexpected type for ");
365                            result.append(buffer);
366                            result.append("\n");
367                        }
368                    }
369                }
370            }
371            closedir(d);
372        } else {
373            result.append("couldn't open ");
374            result.append(buffer);
375            result.append("\n");
376        }
377    }
378    write(fd, result.string(), result.size());
379    return NO_ERROR;
380}
381
382void MediaPlayerService::removeClient(wp<Client> client)
383{
384    Mutex::Autolock lock(mLock);
385    mClients.remove(client);
386}
387
388MediaPlayerService::Client::Client(const sp<MediaPlayerService>& service, pid_t pid,
389        int32_t connId, const sp<IMediaPlayerClient>& client)
390{
391    LOGV("Client(%d) constructor", connId);
392    mPid = pid;
393    mConnId = connId;
394    mService = service;
395    mClient = client;
396    mLoop = false;
397    mStatus = NO_INIT;
398#if CALLBACK_ANTAGONIZER
399    LOGD("create Antagonizer");
400    mAntagonizer = new Antagonizer(notify, this);
401#endif
402}
403
404MediaPlayerService::Client::~Client()
405{
406    LOGV("Client(%d) destructor pid = %d", mConnId, mPid);
407    mAudioOutput.clear();
408    wp<Client> client(this);
409    disconnect();
410    mService->removeClient(client);
411}
412
413void MediaPlayerService::Client::disconnect()
414{
415    LOGV("disconnect(%d) from pid %d", mConnId, mPid);
416    // grab local reference and clear main reference to prevent future
417    // access to object
418    sp<MediaPlayerBase> p;
419    {
420        Mutex::Autolock l(mLock);
421        p = mPlayer;
422    }
423    mPlayer.clear();
424
425    // clear the notification to prevent callbacks to dead client
426    // and reset the player. We assume the player will serialize
427    // access to itself if necessary.
428    if (p != 0) {
429        p->setNotifyCallback(0, 0);
430#if CALLBACK_ANTAGONIZER
431        LOGD("kill Antagonizer");
432        mAntagonizer->kill();
433#endif
434        p->reset();
435    }
436
437    IPCThreadState::self()->flushCommands();
438}
439
440static player_type getPlayerType(int fd, int64_t offset, int64_t length)
441{
442    char buf[20];
443    lseek(fd, offset, SEEK_SET);
444    read(fd, buf, sizeof(buf));
445    lseek(fd, offset, SEEK_SET);
446
447    long ident = *((long*)buf);
448
449    // Ogg vorbis?
450    if (ident == 0x5367674f) // 'OggS'
451        return VORBIS_PLAYER;
452
453    // Some kind of MIDI?
454    EAS_DATA_HANDLE easdata;
455    if (EAS_Init(&easdata) == EAS_SUCCESS) {
456        EAS_FILE locator;
457        locator.path = NULL;
458        locator.fd = fd;
459        locator.offset = offset;
460        locator.length = length;
461        EAS_HANDLE  eashandle;
462        if (EAS_OpenFile(easdata, &locator, &eashandle, NULL) == EAS_SUCCESS) {
463            EAS_CloseFile(easdata, eashandle);
464            EAS_Shutdown(easdata);
465            return SONIVOX_PLAYER;
466        }
467        EAS_Shutdown(easdata);
468    }
469
470    // Fall through to PV
471    return PV_PLAYER;
472}
473
474static player_type getPlayerType(const char* url)
475{
476
477    // use MidiFile for MIDI extensions
478    int lenURL = strlen(url);
479    for (int i = 0; i < NELEM(MIDI_FILE_EXTS); ++i) {
480        int len = strlen(MIDI_FILE_EXTS[i]);
481        int start = lenURL - len;
482        if (start > 0) {
483            if (!strncmp(url + start, MIDI_FILE_EXTS[i], len)) {
484                LOGV("Type is MIDI");
485                return SONIVOX_PLAYER;
486            }
487        }
488    }
489
490    if (strcmp(url + strlen(url) - 4, ".ogg") == 0) {
491        LOGV("Type is Vorbis");
492        return VORBIS_PLAYER;
493    }
494
495    // Fall through to PV
496    return PV_PLAYER;
497}
498
499static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie,
500        notify_callback_f notifyFunc)
501{
502    sp<MediaPlayerBase> p;
503    switch (playerType) {
504        case PV_PLAYER:
505            LOGV(" create PVPlayer");
506            p = new PVPlayer();
507            break;
508        case SONIVOX_PLAYER:
509            LOGV(" create MidiFile");
510            p = new MidiFile();
511            break;
512        case VORBIS_PLAYER:
513            LOGV(" create VorbisPlayer");
514            p = new VorbisPlayer();
515            break;
516    }
517    if (p != NULL) {
518        if (p->initCheck() == NO_ERROR) {
519            p->setNotifyCallback(cookie, notifyFunc);
520            p->setSigBusHandlerStructTLSKey(sigbuskey);
521        } else {
522            p.clear();
523        }
524    }
525    if (p == NULL) {
526        LOGE("Failed to create player object");
527    }
528    return p;
529}
530
531sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)
532{
533    // determine if we have the right player type
534    sp<MediaPlayerBase> p = mPlayer;
535    if ((p != NULL) && (p->playerType() != playerType)) {
536        LOGV("delete player");
537        p.clear();
538    }
539    if (p == NULL) {
540        p = android::createPlayer(playerType, this, notify);
541    }
542    return p;
543}
544
545status_t MediaPlayerService::Client::setDataSource(const char *url)
546{
547    LOGV("setDataSource(%s)", url);
548    if (url == NULL)
549        return UNKNOWN_ERROR;
550
551    if (strncmp(url, "content://", 10) == 0) {
552        // get a filedescriptor for the content Uri and
553        // pass it to the setDataSource(fd) method
554
555        String16 url16(url);
556        int fd = android::openContentProviderFile(url16);
557        if (fd < 0)
558        {
559            LOGE("Couldn't open fd for %s", url);
560            return UNKNOWN_ERROR;
561        }
562        setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus
563        close(fd);
564        return mStatus;
565    } else {
566        player_type playerType = getPlayerType(url);
567        LOGV("player type = %d", playerType);
568
569        // create the right type of player
570        sp<MediaPlayerBase> p = createPlayer(playerType);
571        if (p == NULL) return NO_INIT;
572
573        if (!p->hardwareOutput()) {
574            mAudioOutput = new AudioOutput();
575            static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
576        }
577
578        // now set data source
579        LOGV(" setDataSource");
580        mStatus = p->setDataSource(url);
581        if (mStatus == NO_ERROR) mPlayer = p;
582        return mStatus;
583    }
584}
585
586status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)
587{
588    LOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length);
589    struct stat sb;
590    int ret = fstat(fd, &sb);
591    if (ret != 0) {
592        LOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno));
593        return UNKNOWN_ERROR;
594    }
595
596    LOGV("st_dev  = %llu", sb.st_dev);
597    LOGV("st_mode = %u", sb.st_mode);
598    LOGV("st_uid  = %lu", sb.st_uid);
599    LOGV("st_gid  = %lu", sb.st_gid);
600    LOGV("st_size = %llu", sb.st_size);
601
602    if (offset >= sb.st_size) {
603        LOGE("offset error");
604        ::close(fd);
605        return UNKNOWN_ERROR;
606    }
607    if (offset + length > sb.st_size) {
608        length = sb.st_size - offset;
609        LOGV("calculated length = %lld", length);
610    }
611
612    player_type playerType = getPlayerType(fd, offset, length);
613    LOGV("player type = %d", playerType);
614
615    // create the right type of player
616    sp<MediaPlayerBase> p = createPlayer(playerType);
617    if (p == NULL) return NO_INIT;
618
619    if (!p->hardwareOutput()) {
620        mAudioOutput = new AudioOutput();
621        static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
622    }
623
624    // now set data source
625    mStatus = p->setDataSource(fd, offset, length);
626    if (mStatus == NO_ERROR) mPlayer = p;
627    return mStatus;
628}
629
630status_t MediaPlayerService::Client::setVideoSurface(const sp<ISurface>& surface)
631{
632    LOGV("[%d] setVideoSurface(%p)", mConnId, surface.get());
633    sp<MediaPlayerBase> p = getPlayer();
634    if (p == 0) return UNKNOWN_ERROR;
635    return p->setVideoSurface(surface);
636}
637
638status_t MediaPlayerService::Client::prepareAsync()
639{
640    LOGV("[%d] prepareAsync", mConnId);
641    sp<MediaPlayerBase> p = getPlayer();
642    if (p == 0) return UNKNOWN_ERROR;
643    status_t ret = p->prepareAsync();
644#if CALLBACK_ANTAGONIZER
645    LOGD("start Antagonizer");
646    if (ret == NO_ERROR) mAntagonizer->start();
647#endif
648    return ret;
649}
650
651status_t MediaPlayerService::Client::start()
652{
653    LOGV("[%d] start", mConnId);
654    sp<MediaPlayerBase> p = getPlayer();
655    if (p == 0) return UNKNOWN_ERROR;
656    p->setLooping(mLoop);
657    return p->start();
658}
659
660status_t MediaPlayerService::Client::stop()
661{
662    LOGV("[%d] stop", mConnId);
663    sp<MediaPlayerBase> p = getPlayer();
664    if (p == 0) return UNKNOWN_ERROR;
665    return p->stop();
666}
667
668status_t MediaPlayerService::Client::pause()
669{
670    LOGV("[%d] pause", mConnId);
671    sp<MediaPlayerBase> p = getPlayer();
672    if (p == 0) return UNKNOWN_ERROR;
673    return p->pause();
674}
675
676status_t MediaPlayerService::Client::isPlaying(bool* state)
677{
678    *state = false;
679    sp<MediaPlayerBase> p = getPlayer();
680    if (p == 0) return UNKNOWN_ERROR;
681    *state = p->isPlaying();
682    LOGV("[%d] isPlaying: %d", mConnId, *state);
683    return NO_ERROR;
684}
685
686status_t MediaPlayerService::Client::getVideoSize(int *w, int *h)
687{
688    sp<MediaPlayerBase> p = getPlayer();
689    if (p == 0) return UNKNOWN_ERROR;
690    status_t ret = p->getVideoWidth(w);
691    if (ret == NO_ERROR) ret = p->getVideoHeight(h);
692    if (ret == NO_ERROR) {
693        LOGV("[%d] getVideoWidth = (%d, %d)", mConnId, *w, *h);
694    } else {
695        LOGE("getVideoSize returned %d", ret);
696    }
697    return ret;
698}
699
700status_t MediaPlayerService::Client::getCurrentPosition(int *msec)
701{
702    LOGV("getCurrentPosition");
703    sp<MediaPlayerBase> p = getPlayer();
704    if (p == 0) return UNKNOWN_ERROR;
705    status_t ret = p->getCurrentPosition(msec);
706    if (ret == NO_ERROR) {
707        LOGV("[%d] getCurrentPosition = %d", mConnId, *msec);
708    } else {
709        LOGE("getCurrentPosition returned %d", ret);
710    }
711    return ret;
712}
713
714status_t MediaPlayerService::Client::getDuration(int *msec)
715{
716    LOGV("getDuration");
717    sp<MediaPlayerBase> p = getPlayer();
718    if (p == 0) return UNKNOWN_ERROR;
719    status_t ret = p->getDuration(msec);
720    if (ret == NO_ERROR) {
721        LOGV("[%d] getDuration = %d", mConnId, *msec);
722    } else {
723        LOGE("getDuration returned %d", ret);
724    }
725    return ret;
726}
727
728status_t MediaPlayerService::Client::seekTo(int msec)
729{
730    LOGV("[%d] seekTo(%d)", mConnId, msec);
731    sp<MediaPlayerBase> p = getPlayer();
732    if (p == 0) return UNKNOWN_ERROR;
733    return p->seekTo(msec);
734}
735
736status_t MediaPlayerService::Client::reset()
737{
738    LOGV("[%d] reset", mConnId);
739    sp<MediaPlayerBase> p = getPlayer();
740    if (p == 0) return UNKNOWN_ERROR;
741    return p->reset();
742}
743
744status_t MediaPlayerService::Client::setAudioStreamType(int type)
745{
746    LOGV("[%d] setAudioStreamType(%d)", mConnId, type);
747    // TODO: for hardware output, call player instead
748    Mutex::Autolock l(mLock);
749    if (mAudioOutput != 0) mAudioOutput->setAudioStreamType(type);
750    return NO_ERROR;
751}
752
753status_t MediaPlayerService::Client::setLooping(int loop)
754{
755    LOGV("[%d] setLooping(%d)", mConnId, loop);
756    mLoop = loop;
757    sp<MediaPlayerBase> p = getPlayer();
758    if (p != 0) return p->setLooping(loop);
759    return NO_ERROR;
760}
761
762status_t MediaPlayerService::Client::setVolume(float leftVolume, float rightVolume)
763{
764    LOGV("[%d] setVolume(%f, %f)", mConnId, leftVolume, rightVolume);
765    // TODO: for hardware output, call player instead
766    Mutex::Autolock l(mLock);
767    if (mAudioOutput != 0) mAudioOutput->setVolume(leftVolume, rightVolume);
768    return NO_ERROR;
769}
770
771void MediaPlayerService::Client::notify(void* cookie, int msg, int ext1, int ext2)
772{
773    Client* client = static_cast<Client*>(cookie);
774    LOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, cookie, msg, ext1, ext2);
775    client->mClient->notify(msg, ext1, ext2);
776}
777
778#if CALLBACK_ANTAGONIZER
779const int Antagonizer::interval = 10000; // 10 msecs
780
781Antagonizer::Antagonizer(notify_callback_f cb, void* client) :
782    mExit(false), mActive(false), mClient(client), mCb(cb)
783{
784    createThread(callbackThread, this);
785}
786
787void Antagonizer::kill()
788{
789    Mutex::Autolock _l(mLock);
790    mActive = false;
791    mExit = true;
792    mCondition.wait(mLock);
793}
794
795int Antagonizer::callbackThread(void* user)
796{
797    LOGD("Antagonizer started");
798    Antagonizer* p = reinterpret_cast<Antagonizer*>(user);
799    while (!p->mExit) {
800        if (p->mActive) {
801            LOGV("send event");
802            p->mCb(p->mClient, 0, 0, 0);
803        }
804        usleep(interval);
805    }
806    Mutex::Autolock _l(p->mLock);
807    p->mCondition.signal();
808    LOGD("Antagonizer stopped");
809    return 0;
810}
811#endif
812
813static size_t kDefaultHeapSize = 1024 * 1024; // 1MB
814
815sp<IMemory> MediaPlayerService::decode(const char* url, uint32_t *pSampleRate, int* pNumChannels)
816{
817    LOGV("decode(%s)", url);
818    sp<MemoryBase> mem;
819    sp<MediaPlayerBase> player;
820
821    // Protect our precious, precious DRMd ringtones by only allowing
822    // decoding of http, but not filesystem paths or content Uris.
823    // If the application wants to decode those, it should open a
824    // filedescriptor for them and use that.
825    if (url != NULL && strncmp(url, "http://", 7) != 0) {
826        LOGD("Can't decode %s by path, use filedescriptor instead", url);
827        return mem;
828    }
829
830    player_type playerType = getPlayerType(url);
831    LOGV("player type = %d", playerType);
832
833    // create the right type of player
834    sp<AudioCache> cache = new AudioCache(url);
835    player = android::createPlayer(playerType, cache.get(), cache->notify);
836    if (player == NULL) goto Exit;
837    if (player->hardwareOutput()) goto Exit;
838
839    static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache);
840
841    // set data source
842    if (player->setDataSource(url) != NO_ERROR) goto Exit;
843
844    LOGV("prepare");
845    player->prepareAsync();
846
847    LOGV("wait for prepare");
848    if (cache->wait() != NO_ERROR) goto Exit;
849
850    LOGV("start");
851    player->start();
852
853    LOGV("wait for playback complete");
854    if (cache->wait() != NO_ERROR) goto Exit;
855
856    mem = new MemoryBase(cache->getHeap(), 0, cache->size());
857    *pSampleRate = cache->sampleRate();
858    *pNumChannels = cache->channelCount();
859    LOGV("return memory @ %p, sampleRate=%u, channelCount = %d", mem->pointer(), *pSampleRate, *pNumChannels);
860
861Exit:
862    if (player != 0) player->reset();
863    return mem;
864}
865
866sp<IMemory> MediaPlayerService::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels)
867{
868    LOGV("decode(%d, %lld, %lld)", fd, offset, length);
869    sp<MemoryBase> mem;
870    sp<MediaPlayerBase> player;
871
872    player_type playerType = getPlayerType(fd, offset, length);
873    LOGV("player type = %d", playerType);
874
875    // create the right type of player
876    sp<AudioCache> cache = new AudioCache("decode_fd");
877    player = android::createPlayer(playerType, cache.get(), cache->notify);
878    if (player == NULL) goto Exit;
879    if (player->hardwareOutput()) goto Exit;
880
881    static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache);
882
883    // set data source
884    if (player->setDataSource(fd, offset, length) != NO_ERROR) goto Exit;
885
886    LOGV("prepare");
887    player->prepareAsync();
888
889    LOGV("wait for prepare");
890    if (cache->wait() != NO_ERROR) goto Exit;
891
892    LOGV("start");
893    player->start();
894
895    LOGV("wait for playback complete");
896    if (cache->wait() != NO_ERROR) goto Exit;
897
898    mem = new MemoryBase(cache->getHeap(), 0, cache->size());
899    *pSampleRate = cache->sampleRate();
900    *pNumChannels = cache->channelCount();
901    LOGV("return memory @ %p, sampleRate=%u, channelCount = %d", mem->pointer(), *pSampleRate, *pNumChannels);
902
903Exit:
904    if (player != 0) player->reset();
905    ::close(fd);
906    return mem;
907}
908
909#undef LOG_TAG
910#define LOG_TAG "AudioSink"
911MediaPlayerService::AudioOutput::AudioOutput()
912{
913    mTrack = 0;
914    mStreamType = AudioTrack::MUSIC;
915    mLeftVolume = 1.0;
916    mRightVolume = 1.0;
917    mLatency = 0;
918    mMsecsPerFrame = 0;
919}
920
921MediaPlayerService::AudioOutput::~AudioOutput()
922{
923    close();
924}
925
926ssize_t MediaPlayerService::AudioOutput::bufferSize() const
927{
928    if (mTrack == 0) return NO_INIT;
929    return mTrack->frameCount() * mTrack->channelCount() * sizeof(int16_t);
930}
931
932ssize_t MediaPlayerService::AudioOutput::frameCount() const
933{
934    if (mTrack == 0) return NO_INIT;
935    return mTrack->frameCount();
936}
937
938ssize_t MediaPlayerService::AudioOutput::channelCount() const
939{
940    if (mTrack == 0) return NO_INIT;
941    return mTrack->channelCount();
942}
943
944ssize_t MediaPlayerService::AudioOutput::frameSize() const
945{
946    if (mTrack == 0) return NO_INIT;
947    return mTrack->channelCount() * sizeof(int16_t);
948}
949
950uint32_t MediaPlayerService::AudioOutput::latency () const
951{
952    return mLatency;
953}
954
955float MediaPlayerService::AudioOutput::msecsPerFrame() const
956{
957    return mMsecsPerFrame;
958}
959
960status_t MediaPlayerService::AudioOutput::open(uint32_t sampleRate, int channelCount, int bufferCount)
961{
962    LOGV("open(%u, %d, %d)", sampleRate, channelCount, bufferCount);
963    if (mTrack) close();
964
965    AudioTrack *t = new AudioTrack(mStreamType, sampleRate, AudioSystem::PCM_16_BIT, channelCount, bufferCount);
966    if ((t == 0) || (t->initCheck() != NO_ERROR)) {
967        LOGE("Unable to create audio track");
968        delete t;
969        return NO_INIT;
970    }
971
972    LOGV("setVolume");
973    t->setVolume(mLeftVolume, mRightVolume);
974    mMsecsPerFrame = 1.e3 / (float) sampleRate;
975    mLatency = (mMsecsPerFrame * bufferCount * t->frameCount()) + kDriverLatencyInMsecs;
976    mTrack = t;
977    return NO_ERROR;
978}
979
980void MediaPlayerService::AudioOutput::start()
981{
982    LOGV("start");
983    if (mTrack) {
984        mTrack->setVolume(mLeftVolume, mRightVolume);
985        mTrack->start();
986    }
987}
988
989ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size)
990{
991    //LOGV("write(%p, %u)", buffer, size);
992    if (mTrack) return mTrack->write(buffer, size);
993    return NO_INIT;
994}
995
996void MediaPlayerService::AudioOutput::stop()
997{
998    LOGV("stop");
999    if (mTrack) mTrack->stop();
1000}
1001
1002void MediaPlayerService::AudioOutput::flush()
1003{
1004    LOGV("flush");
1005    if (mTrack) mTrack->flush();
1006}
1007
1008void MediaPlayerService::AudioOutput::pause()
1009{
1010    LOGV("pause");
1011    if (mTrack) mTrack->pause();
1012}
1013
1014void MediaPlayerService::AudioOutput::close()
1015{
1016    LOGV("close");
1017    delete mTrack;
1018    mTrack = 0;
1019}
1020
1021void MediaPlayerService::AudioOutput::setVolume(float left, float right)
1022{
1023    LOGV("setVolume(%f, %f)", left, right);
1024    mLeftVolume = left;
1025    mRightVolume = right;
1026    if (mTrack) {
1027        mTrack->setVolume(left, right);
1028    }
1029}
1030
1031#undef LOG_TAG
1032#define LOG_TAG "AudioCache"
1033MediaPlayerService::AudioCache::AudioCache(const char* name) :
1034    mChannelCount(0), mFrameCount(0), mSampleRate(0), mSize(0),
1035    mError(NO_ERROR), mCommandComplete(false)
1036{
1037    // create ashmem heap
1038    mHeap = new MemoryHeapBase(kDefaultHeapSize, 0, name);
1039}
1040
1041uint32_t MediaPlayerService::AudioCache::latency () const
1042{
1043    return 0;
1044}
1045
1046float MediaPlayerService::AudioCache::msecsPerFrame() const
1047{
1048    return mMsecsPerFrame;
1049}
1050
1051status_t MediaPlayerService::AudioCache::open(uint32_t sampleRate, int channelCount, int bufferCount)
1052{
1053    LOGV("open(%u, %d, %d)", sampleRate, channelCount, bufferCount);
1054   if (mHeap->getHeapID() < 0) return NO_INIT;
1055   mSampleRate = sampleRate;
1056   mChannelCount = channelCount;
1057    mMsecsPerFrame = 1.e3 / (float) sampleRate;
1058    return NO_ERROR;
1059}
1060
1061ssize_t MediaPlayerService::AudioCache::write(const void* buffer, size_t size)
1062{
1063    LOGV("write(%p, %u)", buffer, size);
1064    if ((buffer == 0) || (size == 0)) return size;
1065
1066    uint8_t* p = static_cast<uint8_t*>(mHeap->getBase());
1067    if (p == NULL) return NO_INIT;
1068    p += mSize;
1069    LOGV("memcpy(%p, %p, %u)", p, buffer, size);
1070    memcpy(p, buffer, size);
1071    mSize += size;
1072    return size;
1073}
1074
1075// call with lock held
1076status_t MediaPlayerService::AudioCache::wait()
1077{
1078    Mutex::Autolock lock(mLock);
1079    if (!mCommandComplete) {
1080        mSignal.wait(mLock);
1081    }
1082    mCommandComplete = false;
1083
1084    if (mError == NO_ERROR) {
1085        LOGV("wait - success");
1086    } else {
1087        LOGV("wait - error");
1088    }
1089    return mError;
1090}
1091
1092void MediaPlayerService::AudioCache::notify(void* cookie, int msg, int ext1, int ext2)
1093{
1094    LOGV("notify(%p, %d, %d, %d)", cookie, msg, ext1, ext2);
1095    AudioCache* p = static_cast<AudioCache*>(cookie);
1096
1097    // ignore buffering messages
1098    if (msg == MEDIA_BUFFERING_UPDATE) return;
1099
1100    // set error condition
1101    if (msg == MEDIA_ERROR) {
1102        LOGE("Error %d, %d occurred", ext1, ext2);
1103        p->mError = ext1;
1104    }
1105
1106    // wake up thread
1107    LOGV("wakeup thread");
1108    p->mCommandComplete = true;
1109    p->mSignal.signal();
1110}
1111
1112}; // namespace android
1113