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