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

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

Report video battery on/off from mediaserver

    We can't track video stats accurately if it's reported from
    app side MediaCodec. If the app dies, video stats get stuck
    in On state forever. This can be easily triggered by forcefully
    kill and app that uses MediaCodec from app side (instead of
    through mediaserver's Recorder or Player service), eg.
    launch GoogleCamera app and switch to Video tab, and kill it
    from adb shell.

    In order to track MediaCodec usage from apps we need to move
    the battery stats reporting from MediaCodec into ResourceManager.

bug: 138381810
test:
1. test if app uses MediaCodec directly and it dies off, the video
   off is received: launch GoogleCamera app, swipe to Video tab,
   "dumpsys batterystats --history" and see +video; now adb shell
   kill GoogleCamera, dumpsys should show -video.
2. test app that uses MediaCodec through mediaserver: use Chrome
   (which uses MediaPlayer) to play some website with video, kills
   Chrome from adb shell, and check -video is received.
   In anycase it shouldn't stuck in On state.
3. ResourceManagerService_test

Change-Id: I164b31681c4e72e8cce02342641dbec14b8df374
(cherry picked from commit 47db2ff1)
parent 5f555242
Loading
Loading
Loading
Loading
+4 −1
Original line number Original line Diff line number Diff line
@@ -72,12 +72,14 @@ public:


    virtual void addResource(
    virtual void addResource(
            int pid,
            int pid,
            int uid,
            int64_t clientId,
            int64_t clientId,
            const sp<IResourceManagerClient> client,
            const sp<IResourceManagerClient> client,
            const Vector<MediaResource> &resources) {
            const Vector<MediaResource> &resources) {
        Parcel data, reply;
        Parcel data, reply;
        data.writeInterfaceToken(IResourceManagerService::getInterfaceDescriptor());
        data.writeInterfaceToken(IResourceManagerService::getInterfaceDescriptor());
        data.writeInt32(pid);
        data.writeInt32(pid);
        data.writeInt32(uid);
        data.writeInt64(clientId);
        data.writeInt64(clientId);
        data.writeStrongBinder(IInterface::asBinder(client));
        data.writeStrongBinder(IInterface::asBinder(client));
        writeToParcel(&data, resources);
        writeToParcel(&data, resources);
@@ -129,6 +131,7 @@ status_t BnResourceManagerService::onTransact(
        case ADD_RESOURCE: {
        case ADD_RESOURCE: {
            CHECK_INTERFACE(IResourceManagerService, data, reply);
            CHECK_INTERFACE(IResourceManagerService, data, reply);
            int pid = data.readInt32();
            int pid = data.readInt32();
            int uid = data.readInt32();
            int64_t clientId = data.readInt64();
            int64_t clientId = data.readInt64();
            sp<IResourceManagerClient> client(
            sp<IResourceManagerClient> client(
                    interface_cast<IResourceManagerClient>(data.readStrongBinder()));
                    interface_cast<IResourceManagerClient>(data.readStrongBinder()));
@@ -137,7 +140,7 @@ status_t BnResourceManagerService::onTransact(
            }
            }
            Vector<MediaResource> resources;
            Vector<MediaResource> resources;
            readFromParcel(data, &resources);
            readFromParcel(data, &resources);
            addResource(pid, clientId, client, resources);
            addResource(pid, uid, clientId, client, resources);
            return NO_ERROR;
            return NO_ERROR;
        } break;
        } break;


+1 −0
Original line number Original line Diff line number Diff line
@@ -39,6 +39,7 @@ public:


    virtual void addResource(
    virtual void addResource(
            int pid,
            int pid,
            int uid,
            int64_t clientId,
            int64_t clientId,
            const sp<IResourceManagerClient> client,
            const sp<IResourceManagerClient> client,
            const Vector<MediaResource> &resources) = 0;
            const Vector<MediaResource> &resources) = 0;
+2 −1
Original line number Original line Diff line number Diff line
@@ -31,12 +31,13 @@ public:
        kNonSecureCodec,
        kNonSecureCodec,
        kGraphicMemory,
        kGraphicMemory,
        kCpuBoost,
        kCpuBoost,
        kBattery,
    };
    };


    enum SubType {
    enum SubType {
        kUnspecifiedSubType = 0,
        kUnspecifiedSubType = 0,
        kAudioCodec,
        kAudioCodec,
        kVideoCodec
        kVideoCodec,
    };
    };


    MediaResource();
    MediaResource();
+11 −22
Original line number Original line Diff line number Diff line
@@ -57,7 +57,6 @@
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/PersistentSurface.h>
#include <media/stagefright/PersistentSurface.h>
#include <media/stagefright/SurfaceUtils.h>
#include <media/stagefright/SurfaceUtils.h>
#include <mediautils/BatteryNotifier.h>
#include <private/android_filesystem_config.h>
#include <private/android_filesystem_config.h>
#include <utils/Singleton.h>
#include <utils/Singleton.h>


@@ -166,8 +165,9 @@ private:
    DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
    DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
};
};


MediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy(pid_t pid)
MediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy(
        : mPid(pid) {
        pid_t pid, uid_t uid)
        : mPid(pid), mUid(uid) {
    if (mPid == MediaCodec::kNoPid) {
    if (mPid == MediaCodec::kNoPid) {
        mPid = IPCThreadState::self()->getCallingPid();
        mPid = IPCThreadState::self()->getCallingPid();
    }
    }
@@ -204,7 +204,7 @@ void MediaCodec::ResourceManagerServiceProxy::addResource(
    if (mService == NULL) {
    if (mService == NULL) {
        return;
        return;
    }
    }
    mService->addResource(mPid, clientId, client, resources);
    mService->addResource(mPid, mUid, clientId, client, resources);
}
}


void MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) {
void MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) {
@@ -517,8 +517,6 @@ MediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid, uid_t uid)
      mStickyError(OK),
      mStickyError(OK),
      mSoftRenderer(NULL),
      mSoftRenderer(NULL),
      mAnalyticsItem(NULL),
      mAnalyticsItem(NULL),
      mResourceManagerClient(new ResourceManagerClient(this)),
      mResourceManagerService(new ResourceManagerServiceProxy(pid)),
      mBatteryStatNotified(false),
      mBatteryStatNotified(false),
      mIsVideo(false),
      mIsVideo(false),
      mVideoWidth(0),
      mVideoWidth(0),
@@ -537,6 +535,8 @@ MediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid, uid_t uid)
    } else {
    } else {
        mUid = uid;
        mUid = uid;
    }
    }
    mResourceManagerClient = new ResourceManagerClient(this);
    mResourceManagerService = new ResourceManagerServiceProxy(pid, mUid);


    initAnalyticsItem();
    initAnalyticsItem();
}
}
@@ -1977,6 +1977,11 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                    if (mIsVideo) {
                    if (mIsVideo) {
                        // audio codec is currently ignored.
                        // audio codec is currently ignored.
                        addResource(resourceType, MediaResource::kVideoCodec, 1);
                        addResource(resourceType, MediaResource::kVideoCodec, 1);
                        // TODO: track battery on/off by actual queueing/dequeueing
                        // For now, keep existing behavior and request battery on/off
                        // together with codec init/uninit. We'll improve the tracking
                        // later by adding/removing this based on queue/dequeue timing.
                        addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1);
                    }
                    }


                    (new AMessage)->postReply(mReplyID);
                    (new AMessage)->postReply(mReplyID);
@@ -3126,8 +3131,6 @@ void MediaCodec::setState(State newState) {
    mState = newState;
    mState = newState;


    cancelPendingDequeueOperations();
    cancelPendingDequeueOperations();

    updateBatteryStat();
}
}


void MediaCodec::returnBuffersToCodec(bool isReclaim) {
void MediaCodec::returnBuffersToCodec(bool isReclaim) {
@@ -3631,20 +3634,6 @@ status_t MediaCodec::amendOutputFormatWithCodecSpecificData(
    return OK;
    return OK;
}
}


void MediaCodec::updateBatteryStat() {
    if (!mIsVideo) {
        return;
    }

    if (mState == CONFIGURED && !mBatteryStatNotified) {
        BatteryNotifier::getInstance().noteStartVideo(mUid);
        mBatteryStatNotified = true;
    } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
        BatteryNotifier::getInstance().noteStopVideo(mUid);
        mBatteryStatNotified = false;
    }
}

std::string MediaCodec::stateString(State state) {
std::string MediaCodec::stateString(State state) {
    const char *rval = NULL;
    const char *rval = NULL;
    char rawbuffer[16]; // room for "%d"
    char rawbuffer[16]; // room for "%d"
+2 −2
Original line number Original line Diff line number Diff line
@@ -283,7 +283,7 @@ private:
    };
    };


    struct ResourceManagerServiceProxy : public IBinder::DeathRecipient {
    struct ResourceManagerServiceProxy : public IBinder::DeathRecipient {
        ResourceManagerServiceProxy(pid_t pid);
        ResourceManagerServiceProxy(pid_t pid, uid_t uid);
        ~ResourceManagerServiceProxy();
        ~ResourceManagerServiceProxy();


        void init();
        void init();
@@ -304,6 +304,7 @@ private:
        Mutex mLock;
        Mutex mLock;
        sp<IResourceManagerService> mService;
        sp<IResourceManagerService> mService;
        pid_t mPid;
        pid_t mPid;
        uid_t mUid;
    };
    };


    State mState;
    State mState;
@@ -425,7 +426,6 @@ private:
    status_t onSetParameters(const sp<AMessage> &params);
    status_t onSetParameters(const sp<AMessage> &params);


    status_t amendOutputFormatWithCodecSpecificData(const sp<MediaCodecBuffer> &buffer);
    status_t amendOutputFormatWithCodecSpecificData(const sp<MediaCodecBuffer> &buffer);
    void updateBatteryStat();
    bool isExecuting() const;
    bool isExecuting() const;


    uint64_t getGraphicBufferSize();
    uint64_t getGraphicBufferSize();
Loading