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