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

Commit 2d8b8bb8 authored by Dmitri Plotnikov's avatar Dmitri Plotnikov Committed by Android (Google) Code Review
Browse files

Merge "Add MultiStateCounter"

parents 4ba17109 5effd856
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
[Builtin Hooks]
clang_format = true
bpfmt = true

[Builtin Hooks Options]
# Only turn on clang-format check for the following subfolders.
@@ -26,6 +27,7 @@ clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
               services/vibratorservice/
               services/vr/
               vulkan/
bpfmt = -d

[Hook Scripts]
owners_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "OWNERS$"
+37 −0
Original line number Diff line number Diff line
package {
    // See: http://go/android-license-faq
    default_applicable_licenses: ["frameworks_native_license"],
}

cc_library {
    name: "libbattery",
    srcs: [
        "LongArrayMultiStateCounter.cpp",
    ],
    shared_libs: [
        "liblog",
    ],
    cflags: [
        "-Werror",
        "-Wall",
        "-Wextra",
    ],
    export_include_dirs: ["."],
}

cc_test {
    name: "libbattery_test",
    srcs: [
        "MultiStateCounterTest.cpp",
        "LongArrayMultiStateCounterTest.cpp",
    ],
    static_libs: ["libbattery"],
    shared_libs: [
        "liblog",
    ],
    cflags: [
        "-Werror",
        "-Wall",
        "-Wextra",
    ],
}
+79 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 * Android BPF library - public API
 *
 * 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.
 */

#include "LongArrayMultiStateCounter.h"
#include <log/log.h>

namespace android {
namespace battery {

template <>
bool LongArrayMultiStateCounter::delta(const std::vector<uint64_t>& previousValue,
                                       const std::vector<uint64_t>& newValue,
                                       std::vector<uint64_t>* outValue) const {
    size_t size = previousValue.size();
    if (newValue.size() != size) {
        ALOGE("Incorrect array size: %d, should be %d", (int)newValue.size(), (int)size);
        return false;
    }

    bool is_delta_valid = true;
    for (int i = size - 1; i >= 0; i--) {
        if (newValue[i] >= previousValue[i]) {
            (*outValue)[i] = newValue[i] - previousValue[i];
        } else {
            (*outValue)[i] = 0;
            is_delta_valid = false;
        }
    }
    return is_delta_valid;
}

template <>
void LongArrayMultiStateCounter::add(std::vector<uint64_t>* value1,
                                     const std::vector<uint64_t>& value2, const uint64_t numerator,
                                     const uint64_t denominator) const {
    if (numerator != denominator) {
        for (int i = value2.size() - 1; i >= 0; i--) {
            // The caller ensures that denominator != 0
            (*value1)[i] += value2[i] * numerator / denominator;
        }
    } else {
        for (int i = value2.size() - 1; i >= 0; i--) {
            (*value1)[i] += value2[i];
        }
    }
}

template <>
std::string LongArrayMultiStateCounter::valueToString(const std::vector<uint64_t>& v) const {
    std::stringstream s;
    s << "{ ";
    bool first = true;
    for (uint64_t n : v) {
        if (!first) {
            s << ", ";
        }
        s << n;
        first = false;
    }
    s << "}";
    return s.str();
}

} // namespace battery
} // namespace android
+29 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 * Android BPF library - public API
 *
 * 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.
 */

#pragma once

#include <vector>
#include "MultiStateCounter.h"

namespace android {
namespace battery {

typedef MultiStateCounter<std::vector<uint64_t>> LongArrayMultiStateCounter;

} // namespace battery
} // namespace android
+54 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 * Android BPF library - public API
 *
 * 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.
 */

#include <gtest/gtest.h>
#include "LongArrayMultiStateCounter.h"

namespace android {
namespace battery {

class LongArrayMultiStateCounterTest : public testing::Test {};

TEST_F(LongArrayMultiStateCounterTest, stateChange) {
    LongArrayMultiStateCounter testCounter(2, 0, std::vector<uint64_t>(4), 1000);
    testCounter.setState(1, 2000);
    testCounter.updateValue(std::vector<uint64_t>({100, 200, 300, 400}), 3000);

    // Time was split in half between the two states, so the counts will be split 50:50 too
    EXPECT_EQ(std::vector<uint64_t>({50, 100, 150, 200}), testCounter.getCount(0));
    EXPECT_EQ(std::vector<uint64_t>({50, 100, 150, 200}), testCounter.getCount(1));
}

TEST_F(LongArrayMultiStateCounterTest, accumulation) {
    LongArrayMultiStateCounter testCounter(2, 0, std::vector<uint64_t>(4), 1000);
    testCounter.setState(1, 2000);
    testCounter.updateValue(std::vector<uint64_t>({100, 200, 300, 400}), 3000);
    testCounter.setState(0, 4000);
    testCounter.updateValue(std::vector<uint64_t>({200, 300, 400, 500}), 8000);

    // The first delta is split 50:50:
    //   0: {50, 100, 150, 200}
    //   1: {50, 100, 150, 200}
    // The second delta is split 4:1
    //   0: {80, 80, 80, 80}
    //   1: {20, 20, 20, 20}
    EXPECT_EQ(std::vector<uint64_t>({130, 180, 230, 280}), testCounter.getCount(0));
    EXPECT_EQ(std::vector<uint64_t>({70, 120, 170, 220}), testCounter.getCount(1));
}

} // namespace battery
} // namespace android
Loading