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