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

Commit 47db2ff1 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
parent 28355761
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -72,12 +72,14 @@ public:

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

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

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

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

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

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

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

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),
      mSoftRenderer(NULL),
      mAnalyticsItem(NULL),
      mResourceManagerClient(new ResourceManagerClient(this)),
      mResourceManagerService(new ResourceManagerServiceProxy(pid)),
      mBatteryStatNotified(false),
      mIsVideo(false),
      mVideoWidth(0),
@@ -537,6 +535,8 @@ MediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid, uid_t uid)
    } else {
        mUid = uid;
    }
    mResourceManagerClient = new ResourceManagerClient(this);
    mResourceManagerService = new ResourceManagerServiceProxy(pid, mUid);

    initAnalyticsItem();
}
@@ -1977,6 +1977,11 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                    if (mIsVideo) {
                        // audio codec is currently ignored.
                        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);
@@ -3126,8 +3131,6 @@ void MediaCodec::setState(State newState) {
    mState = newState;

    cancelPendingDequeueOperations();

    updateBatteryStat();
}

void MediaCodec::returnBuffersToCodec(bool isReclaim) {
@@ -3631,20 +3634,6 @@ status_t MediaCodec::amendOutputFormatWithCodecSpecificData(
    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) {
    const char *rval = NULL;
    char rawbuffer[16]; // room for "%d"
+2 −2
Original line number Diff line number Diff line
@@ -283,7 +283,7 @@ private:
    };

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

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

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

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

    uint64_t getGraphicBufferSize();
Loading