/* * Copyright (C) 2023 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. */ #define LOG_TAG "pixelstats: PowerMitigationDurationCounts" #include #include #include #include #include #include #include #include #include #include namespace android { namespace hardware { namespace google { namespace pixel { using aidl::android::frameworks::stats::IStats; using aidl::android::frameworks::stats::VendorAtom; using aidl::android::frameworks::stats::VendorAtomValue; using android::base::ReadFileToString; using android::hardware::google::pixel::PixelAtoms::PowerMitigationDurationCounts; enum DurationOutputOrder { UVLO1, UVLO1_MMWAVE, UVLO1_RFFE, UVLO2, UVLO2_MMWAVE, UVLO2_RFFE, BATOILO, BATOILO_MMWAVE, BATOILO_RFFE, MAIN0, MAIN1, MAIN2, MAIN3, MAIN4, MAIN5, MAIN6, MAIN7, MAIN8, MAIN9, MAIN10, MAIN11, SUB0, SUB1, SUB2, SUB3, SUB4, SUB5, SUB6, SUB7, SUB8, SUB9, SUB10, SUB11, }; MitigationDurationReporter::MitigationDurationReporter() {} bool MitigationDurationReporter::getStatFromLine(const std::string *line, int *val) { std::vector strs = android::base::Split(*line, ":"); if (strs.size() != 2) { ALOGI("Unable to split %s", line->c_str()); return false; } std::string str = strs[1]; str = android::base::Trim(str); str.erase(std::remove(str.begin(), str.end(), '\n'), str.cend()); if (!android::base::ParseInt(str, val)) { ALOGI("Unable to convert %s to int - %s", str.c_str(), strerror(errno)); return false; } return true; } void MitigationDurationReporter::valueAssignmentHelper(std::vector *values, int *val, int fieldNumber) { VendorAtomValue tmp; tmp.set(*val); (*values)[fieldNumber - kVendorAtomOffset] = tmp; } void MitigationDurationReporter::logMitigationDuration(const std::shared_ptr &stats_client, const std::string &path) { struct IrqDurationCounts greater_than_thresh = {}; if (!getIrqDurationCountHelper(path + kGreaterThanTenMsSysfsNode, &greater_than_thresh)) return; VendorAtomValue tmp; std::vector values(33); valueAssignmentHelper(&values, &greater_than_thresh.uvlo1_none, PowerMitigationDurationCounts::kGreaterThanThreshUvlo1NoneFieldNumber); valueAssignmentHelper(&values, &greater_than_thresh.uvlo1_mmwave, PowerMitigationDurationCounts::kGreaterThanThreshUvlo1MmwaveFieldNumber); valueAssignmentHelper(&values, &greater_than_thresh.uvlo1_rffe, PowerMitigationDurationCounts::kGreaterThanThreshUvlo1RffeFieldNumber); valueAssignmentHelper(&values, &greater_than_thresh.uvlo2_none, PowerMitigationDurationCounts::kGreaterThanThreshUvlo2NoneFieldNumber); valueAssignmentHelper(&values, &greater_than_thresh.uvlo2_mmwave, PowerMitigationDurationCounts::kGreaterThanThreshUvlo2MmwaveFieldNumber); valueAssignmentHelper(&values, &greater_than_thresh.uvlo2_rffe, PowerMitigationDurationCounts::kGreaterThanThreshUvlo2RffeFieldNumber); valueAssignmentHelper(&values, &greater_than_thresh.batoilo_none, PowerMitigationDurationCounts::kGreaterThanThreshBatoiloNoneFieldNumber); valueAssignmentHelper( &values, &greater_than_thresh.batoilo_mmwave, PowerMitigationDurationCounts::kGreaterThanThreshBatoiloMmwaveFieldNumber); valueAssignmentHelper(&values, &greater_than_thresh.batoilo_rffe, PowerMitigationDurationCounts::kGreaterThanThreshBatoiloRffeFieldNumber); int i; for (i = 0; i < MITIGATION_DURATION_MAIN_COUNT; i++) { valueAssignmentHelper( &values, &greater_than_thresh.main[i], PowerMitigationDurationCounts::kGreaterThanThreshMain0FieldNumber + i); } for (i = 0; i < MITIGATION_DURATION_SUB_COUNT; i++) { valueAssignmentHelper(&values, &greater_than_thresh.sub[i], PowerMitigationDurationCounts::kGreaterThanThreshSub0FieldNumber + i); } // Send vendor atom to IStats HAL VendorAtom event = {.reverseDomainName = "", .atomId = PixelAtoms::Atom::kMitigationDuration, .values = std::move(values)}; const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event); if (!ret.isOk()) ALOGE("Unable to report to Stats service"); } int MitigationDurationReporter::updateStat(const std::string *line, int *val) { int stat_value; if (!getStatFromLine(line, &stat_value) || *val == stat_value) { return 0; } *val = stat_value; return 1; } bool MitigationDurationReporter::getIrqDurationCountHelper( const std::string kMitigationDurationFile, struct IrqDurationCounts *counts) { std::string file_contents; if (!ReadFileToString(kMitigationDurationFile, &file_contents)) { ALOGI("Unable to read %s - %s", kMitigationDurationFile.c_str(), strerror(errno)); return false; } std::vector lines = android::base::Split(file_contents, "\n"); if (lines.size() < kExpectedNumberOfLines) { ALOGI("Readback size is invalid"); return false; } int16_t i; int num_stats = 0; num_stats += updateStat(&lines[UVLO1], &counts->uvlo1_none); num_stats += updateStat(&lines[UVLO1_MMWAVE], &counts->uvlo1_mmwave); num_stats += updateStat(&lines[UVLO1_RFFE], &counts->uvlo1_rffe); num_stats += updateStat(&lines[UVLO2], &counts->uvlo2_none); num_stats += updateStat(&lines[UVLO2_MMWAVE], &counts->uvlo2_mmwave); num_stats += updateStat(&lines[UVLO2_RFFE], &counts->uvlo2_rffe); num_stats += updateStat(&lines[BATOILO], &counts->batoilo_none); num_stats += updateStat(&lines[BATOILO_MMWAVE], &counts->batoilo_mmwave); num_stats += updateStat(&lines[BATOILO_RFFE], &counts->batoilo_rffe); for (i = MAIN0; i <= MAIN11; i++) { num_stats += updateStat(&lines[i], &counts->main[i - MAIN0]); } for (i = SUB0; i <= SUB11; i++) { num_stats += updateStat(&lines[i], &counts->sub[i - SUB0]); } return num_stats > 0; } } // namespace pixel } // namespace google } // namespace hardware } // namespace android