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