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