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

Commit 1af17b8b authored by David Anderson's avatar David Anderson
Browse files

healthd: Add batterySerialNumber support to BatteryMonitor.

With some conversion to ASCII in case the battery serial number contains
characters that will be rejected by the HAL vts test.

Bug: 397546424
Test: adb shell tradeinmode getstatus
Change-Id: I0b63ddf00e6e78c3cb1b20aab03ea25dd6158b52
parent 29033a81
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -294,6 +294,30 @@ cc_binary {
    },
}

cc_test {
    name: "battery_monitor_test",
    cflags: [
        "-Wall",
        "-Werror",
    ],
    shared_libs: [
        "libutils",
    ],
    static_libs: [
        "android.hardware.health-V4-ndk",
        "libbatterymonitor",
    ],
    srcs: ["battery_monitor_test.cpp"],
    whole_static_libs: [
        "android.hardware.health-translate-ndk",
    ],
    test_suites: [
        "general-tests",
        "device-tests",
    ],
    require_root: true,
}

cc_test {
    name: "charger_test",
    defaults: ["charger_defaults"],
+41 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <healthd/healthd.h>
#include <healthd/BatteryMonitor.h>

#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
@@ -353,6 +354,30 @@ static T getIntField(const String8& path) {
    return value;
}

String8 sanitizeSerialNumber(const std::string& serial) {
    String8 sanitized;
    for (const auto& c : serial) {
        if (isupper(c) || isdigit(c)) {
            sanitized.appendFormat("%c", c);
        } else if (islower(c)) {
            sanitized.appendFormat("%c", toupper(c));
        } else {
            // Some devices return non-ASCII characters as part of the serial
            // number. Handle these gracefully since VTS requires alphanumeric
            // characters.
            sanitized.appendFormat("%02X", (unsigned int)c);
        }
    }
    return sanitized;
}

static String8 readSerialNumber(const String8& path) {
    std::string unsanitized;
    if (readFromFile(path, &unsanitized) <= 0) return {};

    return sanitizeSerialNumber(unsanitized);
}

static bool isScopedPowerSupply(const char* name) {
    constexpr char kScopeDevice[] = "Device";

@@ -423,6 +448,11 @@ void BatteryMonitor::updateValues(void) {
        ensureBatteryHealthData(mHealthInfo.get())->batteryFirstUsageSeconds =
                getIntField<int64_t>(mHealthdConfig->batteryFirstUsageDatePath);

    if (!mHealthdConfig->batterySerialPath.empty()) {
        ensureBatteryHealthData(mHealthInfo.get())->batterySerialNumber =
                readSerialNumber(mHealthdConfig->batterySerialPath);
    }

    mHealthInfo->batteryTemperatureTenthsCelsius =
            mBatteryFixedTemperature ? mBatteryFixedTemperature
                                     : getIntField(mHealthdConfig->batteryTemperaturePath);
@@ -707,7 +737,9 @@ status_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) {
}

status_t BatteryMonitor::getSerialNumber(std::optional<std::string>* out) {
    *out = std::nullopt;
    if (!mHealthdConfig->batterySerialPath.empty()) {
        *out = readSerialNumber(mHealthdConfig->batterySerialPath);
    }
    return OK;
}

@@ -976,6 +1008,12 @@ void BatteryMonitor::init(struct healthd_config *hc) {
                    if (access(path.c_str(), R_OK) == 0) mHealthdConfig->chargingPolicyPath = path;
                }

                if (mHealthdConfig->batterySerialPath.empty()) {
                    path.clear();
                    path.appendFormat("%s/%s/serial_number", POWER_SUPPLY_SYSFS_PATH, name);
                    if (access(path.c_str(), R_OK) == 0) mHealthdConfig->batterySerialPath = path;
                }

                break;

            case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN:
@@ -1038,6 +1076,8 @@ void BatteryMonitor::init(struct healthd_config *hc) {
            KLOG_WARNING(LOG_TAG, "chargingStatePath not found\n");
        if (mHealthdConfig->chargingPolicyPath.empty())
            KLOG_WARNING(LOG_TAG, "chargingPolicyPath not found\n");
        if (mHealthdConfig->batterySerialPath.empty())
            KLOG_WARNING(LOG_TAG, "batterySerialPath not found\n");
    }

    if (property_get("ro.boot.fake_battery", pval, NULL) > 0
+5 −0
Original line number Diff line number Diff line
@@ -4,6 +4,11 @@
      "name": "libhealthd_charger_test"
    }
  ],
  "postsubmit": [
    {
      "name": "battery_monitor_test"
    }
  ],
  "hwasan-postsubmit": [
    {
      "name": "libhealthd_charger_test"
+26 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.
 */
#pragma once

#include <string>

#include <utils/String8.h>

namespace android {

String8 sanitizeSerialNumber(const std::string& serial);

}  // namespace android
+27 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.
 */

#include "battery_monitor_internal.h"

#include <gtest/gtest.h>

using namespace android;

TEST(BatteryMonitor, SanitizeSerialNumber) {
    ASSERT_EQ(sanitizeSerialNumber("abcd1234"), "ABCD1234");
    ASSERT_EQ(sanitizeSerialNumber("ABCD1234"), "ABCD1234");
    ASSERT_EQ(sanitizeSerialNumber("H+-"), "H2B2D");
}
Loading