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