Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 396f6de6 authored by Gloria Wang's avatar Gloria Wang Committed by Android (Google) Code Review
Browse files

Merge "- To track the usage of all audio output devices - To track the...

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()"
parents 6c1bebe3 9b3f1521
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -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;
+110 −2
Original line number Diff line number Diff line
@@ -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();

+19 −0
Original line number Diff line number Diff line
@@ -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
+50 −0
Original line number Diff line number Diff line
@@ -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);
            }
        }
    }