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