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

Commit e5b9b692 authored by Chong Zhang's avatar Chong Zhang
Browse files

stagefright: put battery update under a separate lock

Battery update doesn't need to lock the main lock for
mediaplayerservice. Battery update sometimes is called
from lower level componenet (eg. StagefrightRecorder),
locking the main lock here has potential to deadlock.

Puting the battery update in a separate class so that
it's clear this is not to be mixed with the rest of
the mediaplayerservice states.

bug: 38230347
Change-Id: Idf5f26f2b07ad6303775763ce283dad0679843d5
parent bbdae2f5
Loading
Loading
Loading
Loading
+26 −16
Original line number Diff line number Diff line
@@ -275,20 +275,6 @@ MediaPlayerService::MediaPlayerService()
    ALOGV("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;

    // reset battery stats
    // if the mediaserver has crashed, battery stats could be left
    // in bad state, reset the state upon service start.
    BatteryNotifier::getInstance().noteResetVideo();

    MediaPlayerFactory::registerBuiltinFactories();
}

@@ -2485,7 +2471,31 @@ bool CallbackThread::threadLoop() {

////////////////////////////////////////////////////////////////////////////////

void MediaPlayerService::addBatteryData(uint32_t params)
void MediaPlayerService::addBatteryData(uint32_t params) {
    mBatteryTracker.addBatteryData(params);
}

status_t MediaPlayerService::pullBatteryData(Parcel* reply) {
    return mBatteryTracker.pullBatteryData(reply);
}

MediaPlayerService::BatteryTracker::BatteryTracker() {
    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;

    // reset battery stats
    // if the mediaserver has crashed, battery stats could be left
    // in bad state, reset the state upon service start.
    BatteryNotifier::getInstance().noteResetVideo();
}

void MediaPlayerService::BatteryTracker::addBatteryData(uint32_t params)
{
    Mutex::Autolock lock(mLock);

@@ -2625,7 +2635,7 @@ void MediaPlayerService::addBatteryData(uint32_t params)
    }
}

status_t MediaPlayerService::pullBatteryData(Parcel* reply) {
status_t MediaPlayerService::BatteryTracker::pullBatteryData(Parcel* reply) {
    Mutex::Autolock lock(mLock);

    // audio output devices usage
+51 −40
Original line number Diff line number Diff line
@@ -246,6 +246,19 @@ public:
        CAMERA_PROCESS_DEATH = 4
    };

    // 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
    virtual status_t            pullBatteryData(Parcel* reply);
private:
    struct BatteryTracker {
        BatteryTracker();
        // Collect info of the codec usage from media player and media recorder
        void addBatteryData(uint32_t params);
        // API for the Battery app to pull the data of codecs usage
        status_t pullBatteryData(Parcel* reply);

    private:
        // For battery usage tracking purpose
        struct BatteryUsageInfo {
            // how many streams are being played by one UID
@@ -286,11 +299,9 @@ public:
        // 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
    virtual status_t            pullBatteryData(Parcel* reply);
private:
        mutable Mutex mLock;
    };
    BatteryTracker mBatteryTracker;

    class Client : public BnMediaPlayer {
        // IMediaPlayer interface