summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGloria Wang <gwang@google.com>2011-03-02 19:51:04 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-03-02 19:51:04 -0800
commit4f46fed004b76d462ef859aa94a3c056b0e79b60 (patch)
treeafd68cec4f63a8576a539064a48b80dbe7ff92e4
parent9a5f9b7dbe9ecdebfbd9e8f96452c42213b08a31 (diff)
parent9ee159b79022b2e1a050acb3890ce948e99e9ccb (diff)
downloadframeworks_av-4f46fed004b76d462ef859aa94a3c056b0e79b60.zip
frameworks_av-4f46fed004b76d462ef859aa94a3c056b0e79b60.tar.gz
frameworks_av-4f46fed004b76d462ef859aa94a3c056b0e79b60.tar.bz2
Merge "- To track the usage of all audio output devices - To track the currently used audio device - The devices are separated as speaker and other audio devices - Provide the collected data to battery application through pullBatteryData()"
-rw-r--r--include/media/IMediaPlayerService.h18
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp112
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h19
-rw-r--r--services/audioflinger/AudioFlinger.cpp50
4 files changed, 192 insertions, 7 deletions
diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h
index cce9129..7956788 100644
--- a/include/media/IMediaPlayerService.h
+++ b/include/media/IMediaPlayerService.h
@@ -55,17 +55,25 @@ public:
virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;
virtual sp<IOMX> getOMX() = 0;
- // codecs usage tracking for the battery app
+ // codecs and audio devices usage tracking for the battery app
enum BatteryDataBits {
// tracking audio codec
- kBatteryDataTrackAudio = 1,
+ kBatteryDataTrackAudio = 0x1,
// tracking video codec
- kBatteryDataTrackVideo = 2,
+ kBatteryDataTrackVideo = 0x2,
// codec is started, otherwise codec is paused
- kBatteryDataCodecStarted = 4,
+ kBatteryDataCodecStarted = 0x4,
// tracking decoder (for media player),
// otherwise tracking encoder (for media recorder)
- kBatteryDataTrackDecoder = 8,
+ kBatteryDataTrackDecoder = 0x8,
+ // start to play an audio on an audio device
+ kBatteryDataAudioFlingerStart = 0x10,
+ // stop/pause the audio playback
+ kBatteryDataAudioFlingerStop = 0x20,
+ // audio is rounted to speaker
+ kBatteryDataSpeakerOn = 0x40,
+ // audio is rounted to devices other than speaker
+ kBatteryDataOtherAudioDeviceOn = 0x80,
};
virtual void addBatteryData(uint32_t params) = 0;
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index ec6188f..a42cca5 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -214,6 +214,15 @@ MediaPlayerService::MediaPlayerService()
{
LOGV("MediaPlayerService created");
mNextConnId = 1;
+
+ mBatteryAudio.refCount = 0;
+ for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
+ mBatteryAudio.deviceOn[i] = 0;
+ mBatteryAudio.lastTime[i] = 0;
+ mBatteryAudio.totalTime[i] = 0;
+ }
+ // speaker is on by default
+ mBatteryAudio.deviceOn[SPEAKER] = 1;
}
MediaPlayerService::~MediaPlayerService()
@@ -1777,12 +1786,88 @@ int MediaPlayerService::AudioCache::getSessionId()
void MediaPlayerService::addBatteryData(uint32_t params)
{
Mutex::Autolock lock(mLock);
+
+ int32_t time = systemTime() / 1000000L;
+
+ // change audio output devices. This notification comes from AudioFlinger
+ if ((params & kBatteryDataSpeakerOn)
+ || (params & kBatteryDataOtherAudioDeviceOn)) {
+
+ int deviceOn[NUM_AUDIO_DEVICES];
+ for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
+ deviceOn[i] = 0;
+ }
+
+ if ((params & kBatteryDataSpeakerOn)
+ && (params & kBatteryDataOtherAudioDeviceOn)) {
+ deviceOn[SPEAKER_AND_OTHER] = 1;
+ } else if (params & kBatteryDataSpeakerOn) {
+ deviceOn[SPEAKER] = 1;
+ } else {
+ deviceOn[OTHER_AUDIO_DEVICE] = 1;
+ }
+
+ for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
+ if (mBatteryAudio.deviceOn[i] != deviceOn[i]){
+
+ if (mBatteryAudio.refCount > 0) { // if playing audio
+ if (!deviceOn[i]) {
+ mBatteryAudio.lastTime[i] += time;
+ mBatteryAudio.totalTime[i] += mBatteryAudio.lastTime[i];
+ mBatteryAudio.lastTime[i] = 0;
+ } else {
+ mBatteryAudio.lastTime[i] = 0 - time;
+ }
+ }
+
+ mBatteryAudio.deviceOn[i] = deviceOn[i];
+ }
+ }
+ return;
+ }
+
+ // an sudio stream is started
+ if (params & kBatteryDataAudioFlingerStart) {
+ // record the start time only if currently no other audio
+ // is being played
+ if (mBatteryAudio.refCount == 0) {
+ for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
+ if (mBatteryAudio.deviceOn[i]) {
+ mBatteryAudio.lastTime[i] -= time;
+ }
+ }
+ }
+
+ mBatteryAudio.refCount ++;
+ return;
+
+ } else if (params & kBatteryDataAudioFlingerStop) {
+ if (mBatteryAudio.refCount <= 0) {
+ LOGW("Battery track warning: refCount is <= 0");
+ return;
+ }
+
+ // record the stop time only if currently this is the only
+ // audio being played
+ if (mBatteryAudio.refCount == 1) {
+ for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
+ if (mBatteryAudio.deviceOn[i]) {
+ mBatteryAudio.lastTime[i] += time;
+ mBatteryAudio.totalTime[i] += mBatteryAudio.lastTime[i];
+ mBatteryAudio.lastTime[i] = 0;
+ }
+ }
+ }
+
+ mBatteryAudio.refCount --;
+ return;
+ }
+
int uid = IPCThreadState::self()->getCallingUid();
if (uid == AID_MEDIA) {
return;
}
int index = mBatteryData.indexOfKey(uid);
- int32_t time = systemTime() / 1000000L;
if (index < 0) { // create a new entry for this UID
BatteryUsageInfo info;
@@ -1792,7 +1877,10 @@ void MediaPlayerService::addBatteryData(uint32_t params)
info.videoLastTime = 0;
info.refCount = 0;
- mBatteryData.add(uid, info);
+ if (mBatteryData.add(uid, info) == NO_MEMORY) {
+ LOGE("Battery track error: no memory for new app");
+ return;
+ }
}
BatteryUsageInfo &info = mBatteryData.editValueFor(uid);
@@ -1837,6 +1925,26 @@ void MediaPlayerService::addBatteryData(uint32_t params)
status_t MediaPlayerService::pullBatteryData(Parcel* reply) {
Mutex::Autolock lock(mLock);
+
+ // audio output devices usage
+ int32_t time = systemTime() / 1000000L; //in ms
+ int32_t totalTime;
+
+ for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
+ totalTime = mBatteryAudio.totalTime[i];
+
+ if (mBatteryAudio.deviceOn[i]
+ && (mBatteryAudio.lastTime[i] != 0)) {
+ int32_t tmpTime = mBatteryAudio.lastTime[i] + time;
+ totalTime += tmpTime;
+ }
+
+ reply->writeInt32(totalTime);
+ // reset the total time
+ mBatteryAudio.totalTime[i] = 0;
+ }
+
+ // codec usage
BatteryUsageInfo info;
int size = mBatteryData.size();
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 1175ed0..ff6ccf5 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -225,6 +225,25 @@ public:
};
KeyedVector<int, BatteryUsageInfo> mBatteryData;
+ enum {
+ SPEAKER,
+ OTHER_AUDIO_DEVICE,
+ SPEAKER_AND_OTHER,
+ NUM_AUDIO_DEVICES
+ };
+
+ struct BatteryAudioFlingerUsageInfo {
+ int refCount; // how many audio streams are being played
+ int deviceOn[NUM_AUDIO_DEVICES]; // whether the device is currently used
+ int32_t lastTime[NUM_AUDIO_DEVICES]; // in ms
+ // totalTime[]: total time of audio output devices usage
+ int32_t totalTime[NUM_AUDIO_DEVICES]; // in ms
+ };
+
+ // This varialble is used to record the usage of audio output device
+ // for battery app
+ BatteryAudioFlingerUsageInfo mBatteryAudio;
+
// Collect info of the codec usage from media player and media recorder
virtual void addBatteryData(uint32_t params);
// API for the Battery app to pull the data of codecs usage
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index a07ebfc..2b08ab5 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -24,6 +24,7 @@
#include <sys/time.h>
#include <sys/resource.h>
+#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
#include <binder/Parcel.h>
@@ -35,6 +36,7 @@
#include <media/AudioTrack.h>
#include <media/AudioRecord.h>
+#include <media/IMediaPlayerService.h>
#include <private/media/AudioTrackShared.h>
#include <private/media/AudioEffectShared.h>
@@ -121,6 +123,19 @@ static bool settingsAllowed() {
#endif
}
+// To collect the amplifier usage
+static void addBatteryData(uint32_t params) {
+ sp<IBinder> binder =
+ defaultServiceManager()->getService(String16("media.player"));
+ sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
+ if (service.get() == NULL) {
+ LOGW("Cannot connect to the MediaPlayerService for battery tracking");
+ return;
+ }
+
+ service->addBatteryData(params);
+}
+
// ----------------------------------------------------------------------------
AudioFlinger::AudioFlinger()
@@ -1833,6 +1848,27 @@ bool AudioFlinger::MixerThread::checkForNewParameters_l()
}
}
if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) {
+ // when changing the audio output device, call addBatteryData to notify
+ // the change
+ if (mDevice != value) {
+ uint32_t params = 0;
+ // check whether speaker is on
+ if (value & AudioSystem::DEVICE_OUT_SPEAKER) {
+ params |= IMediaPlayerService::kBatteryDataSpeakerOn;
+ }
+
+ int deviceWithoutSpeaker
+ = AudioSystem::DEVICE_OUT_ALL & ~AudioSystem::DEVICE_OUT_SPEAKER;
+ // check if any other device (except speaker) is on
+ if (value & deviceWithoutSpeaker ) {
+ params |= IMediaPlayerService::kBatteryDataOtherAudioDeviceOn;
+ }
+
+ if (params != 0) {
+ addBatteryData(params);
+ }
+ }
+
// forward device change to effects that have requested to be
// aware of attached audio device.
mDevice = (uint32_t)value;
@@ -2831,6 +2867,9 @@ void AudioFlinger::PlaybackThread::Track::destroy()
AudioSystem::stopOutput(thread->id(),
(AudioSystem::stream_type)mStreamType,
mSessionId);
+
+ // to track the speaker usage
+ addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStop);
}
AudioSystem::releaseOutput(thread->id());
}
@@ -2941,6 +2980,11 @@ status_t AudioFlinger::PlaybackThread::Track::start()
(AudioSystem::stream_type)mStreamType,
mSessionId);
thread->mLock.lock();
+
+ // to track the speaker usage
+ if (status == NO_ERROR) {
+ addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStart);
+ }
}
if (status == NO_ERROR) {
PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
@@ -2976,6 +3020,9 @@ void AudioFlinger::PlaybackThread::Track::stop()
(AudioSystem::stream_type)mStreamType,
mSessionId);
thread->mLock.lock();
+
+ // to track the speaker usage
+ addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStop);
}
}
}
@@ -2995,6 +3042,9 @@ void AudioFlinger::PlaybackThread::Track::pause()
(AudioSystem::stream_type)mStreamType,
mSessionId);
thread->mLock.lock();
+
+ // to track the speaker usage
+ addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStop);
}
}
}