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

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

Add more tests for battery checker code

There is no change on functionality, only refactoring
to allow unit testing.

bug: 138381810
bug: 139440234

Change-Id: Id927c091607d9ea5ea84b6e292d53154ef5171a6
parent 49851fcb
Loading
Loading
Loading
Loading
+51 −18
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@
#include <media/stagefright/foundation/avc_utils.h>
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/ACodec.h>
#include <media/stagefright/BatteryChecker.h>
#include <media/stagefright/BufferProducerWrapper.h>
#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/MediaCodecList.h>
@@ -116,7 +117,6 @@ static bool isResourceError(status_t err) {
static const int kMaxRetry = 2;
static const int kMaxReclaimWaitTimeInUs = 500000;  // 0.5s
static const int kNumBuffersAlign = 16;
static const int kBatteryStatsTimeoutUs = 3000000ll; // 3 seconds

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

@@ -539,10 +539,7 @@ MediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid, uid_t uid)
      mHaveInputSurface(false),
      mHavePendingInputBuffers(false),
      mCpuBoostRequested(false),
      mLatencyUnknown(0),
      mLastActivityTimeUs(-1ll),
      mBatteryStatNotified(false),
      mBatteryCheckerGeneration(0) {
      mLatencyUnknown(0) {
    if (uid == kNoUid) {
        mUid = IPCThreadState::self()->getCallingUid();
    } else {
@@ -755,7 +752,11 @@ void MediaCodec::statsBufferSent(int64_t presentationUs) {
        return;
    }

    scheduleBatteryCheckerIfNeeded();
    if (mBatteryChecker != nullptr) {
        mBatteryChecker->onCodecActivity([this] () {
            addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1);
        });
    }

    const int64_t nowNs = systemTime(SYSTEM_TIME_MONOTONIC);
    BufferFlightTiming_t startdata = { presentationUs, nowNs };
@@ -791,7 +792,11 @@ void MediaCodec::statsBufferReceived(int64_t presentationUs) {
        return;
    }

    scheduleBatteryCheckerIfNeeded();
    if (mBatteryChecker != nullptr) {
        mBatteryChecker->onCodecActivity([this] () {
            addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1);
        });
    }

    BufferFlightTiming_t startdata;
    bool valid = false;
@@ -981,6 +986,10 @@ status_t MediaCodec::init(const AString &name) {
        mAnalyticsItem->setCString(kCodecMode, mIsVideo ? kCodecModeVideo : kCodecModeAudio);
    }

    if (mIsVideo) {
        mBatteryChecker = new BatteryChecker(new AMessage(kWhatCheckBatteryStats, this));
    }

    status_t err;
    Vector<MediaResource> resources;
    MediaResource::Type type =
@@ -1706,19 +1715,27 @@ void MediaCodec::requestCpuBoostIfNeeded() {
    }
}

void MediaCodec::scheduleBatteryCheckerIfNeeded() {
    if (!mIsVideo || !isExecuting()) {
BatteryChecker::BatteryChecker(const sp<AMessage> &msg, int64_t timeoutUs)
    : mTimeoutUs(timeoutUs)
    , mLastActivityTimeUs(-1ll)
    , mBatteryStatNotified(false)
    , mBatteryCheckerGeneration(0)
    , mIsExecuting(false)
    , mBatteryCheckerMsg(msg) {}

void BatteryChecker::onCodecActivity(std::function<void()> batteryOnCb) {
    if (!isExecuting()) {
        // ignore if not executing
        return;
    }
    if (!mBatteryStatNotified) {
        addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1);
        batteryOnCb();
        mBatteryStatNotified = true;
        sp<AMessage> msg = new AMessage(kWhatCheckBatteryStats, this);
        sp<AMessage> msg = mBatteryCheckerMsg->dup();
        msg->setInt32("generation", mBatteryCheckerGeneration);

        // post checker and clear last activity time
        msg->post(kBatteryStatsTimeoutUs);
        msg->post(mTimeoutUs);
        mLastActivityTimeUs = -1ll;
    } else {
        // update last activity time
@@ -1726,7 +1743,8 @@ void MediaCodec::scheduleBatteryCheckerIfNeeded() {
    }
}

void MediaCodec::onBatteryChecker(const sp<AMessage> &msg) {
void BatteryChecker::onCheckBatteryTimer(
        const sp<AMessage> &msg, std::function<void()> batteryOffCb) {
    // ignore if this checker already expired because the client resource was removed
    int32_t generation;
    if (!msg->findInt32("generation", &generation)
@@ -1736,15 +1754,20 @@ void MediaCodec::onBatteryChecker(const sp<AMessage> &msg) {

    if (mLastActivityTimeUs < 0ll) {
        // timed out inactive, do not repost checker
        removeResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1);
        batteryOffCb();
        mBatteryStatNotified = false;
    } else {
        // repost checker and clear last activity time
        msg->post(kBatteryStatsTimeoutUs + mLastActivityTimeUs - ALooper::GetNowUs());
        msg->post(mTimeoutUs + mLastActivityTimeUs - ALooper::GetNowUs());
        mLastActivityTimeUs = -1ll;
    }
}

void BatteryChecker::onClientRemoved() {
    mBatteryStatNotified = false;
    mBatteryCheckerGeneration++;
}

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

void MediaCodec::cancelPendingDequeueOperations() {
@@ -2382,8 +2405,10 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                    mFlags &= ~kFlagIsComponentAllocated;

                    // off since we're removing all resources including the battery on
                    mBatteryStatNotified = false;
                    mBatteryCheckerGeneration++;
                    if (mBatteryChecker != nullptr) {
                        mBatteryChecker->onClientRemoved();
                    }

                    mResourceManagerService->removeClient(getId(mResourceManagerClient));

                    (new AMessage)->postReply(mReplyID);
@@ -3097,7 +3122,11 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {

        case kWhatCheckBatteryStats:
        {
            onBatteryChecker(msg);
            if (mBatteryChecker != nullptr) {
                mBatteryChecker->onCheckBatteryTimer(msg, [this] () {
                    removeResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1);
                });
            }
            break;
        }

@@ -3197,6 +3226,10 @@ void MediaCodec::setState(State newState) {

    mState = newState;

    if (mBatteryChecker != nullptr) {
        mBatteryChecker->setExecuting(isExecuting());
    }

    cancelPendingDequeueOperations();
}

+3 −0
Original line number Diff line number Diff line
@@ -7,6 +7,9 @@
          "include-annotation": "android.platform.test.annotations.RequiresDevice"
        }
      ]
    },
    {
       "name": "BatteryChecker_test"
    }
  ]
}
+47 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef BATTERY_CHECKER_H_
#define BATTERY_CHECKER_H_

#include <media/stagefright/foundation/AMessage.h>

namespace android {

struct BatteryChecker : public RefBase {
    BatteryChecker(const sp<AMessage> &msg, int64_t timeout = 3000000ll);

    void setExecuting(bool executing) { mIsExecuting = executing; }
    void onCodecActivity(std::function<void()> batteryOnCb);
    void onCheckBatteryTimer(const sp<AMessage>& msg, std::function<void()> batteryOffCb);
    void onClientRemoved();

private:
    const int64_t mTimeoutUs;
    int64_t mLastActivityTimeUs;
    bool mBatteryStatNotified;
    int32_t mBatteryCheckerGeneration;
    bool mIsExecuting;
    sp<AMessage> mBatteryCheckerMsg;

    bool isExecuting() { return mIsExecuting; }

    DISALLOW_EVIL_CONSTRUCTORS(BatteryChecker);
};

}  // namespace android

#endif // BATTERY_CHECKER_H_
+2 −5
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ struct ABuffer;
struct AMessage;
struct AReplyToken;
struct AString;
struct BatteryChecker;
class BufferChannelBase;
struct CodecBase;
class IBatteryStats;
@@ -463,11 +464,7 @@ private:
    Mutex mLatencyLock;
    int64_t mLatencyUnknown;    // buffers for which we couldn't calculate latency

    int64_t mLastActivityTimeUs;
    bool mBatteryStatNotified;
    int32_t mBatteryCheckerGeneration;
    void onBatteryChecker(const sp<AMessage>& msg);
    void scheduleBatteryCheckerIfNeeded();
    sp<BatteryChecker> mBatteryChecker;

    void statsBufferSent(int64_t presentationUs);
    void statsBufferReceived(int64_t presentationUs);
+18 −0
Original line number Diff line number Diff line
@@ -27,3 +27,21 @@ cc_test {
        "-Wall",
    ],
}

cc_test {
    name: "BatteryChecker_test",
    srcs: ["BatteryChecker_test.cpp"],
    test_suites: ["device-tests"],

    shared_libs: [
        "libstagefright",
        "libstagefright_foundation",
        "libutils",
        "liblog",
    ],

    cflags: [
        "-Werror",
        "-Wall",
    ],
}
 No newline at end of file
Loading