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