You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
6.5 KiB
175 lines
6.5 KiB
/*
|
|
* 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: DisplayStats"
|
|
|
|
#include <aidl/android/frameworks/stats/IStats.h>
|
|
#include <android-base/file.h>
|
|
#include <android-base/parseint.h>
|
|
#include <android-base/properties.h>
|
|
#include <android-base/stringprintf.h>
|
|
#include <android-base/strings.h>
|
|
#include <android/binder_manager.h>
|
|
#include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
|
|
#include <pixelstats/DisplayStatsReporter.h>
|
|
#include <utils/Log.h>
|
|
|
|
#include <cinttypes>
|
|
|
|
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::DisplayPanelErrorStats;
|
|
|
|
DisplayStatsReporter::DisplayStatsReporter() {}
|
|
|
|
bool DisplayStatsReporter::readDisplayPanelErrorCount(const std::string &path, int64_t *val) {
|
|
std::string file_contents;
|
|
|
|
if (path.empty()) {
|
|
return false;
|
|
}
|
|
|
|
if (!ReadFileToString(path.c_str(), &file_contents)) {
|
|
if (errno != ENOENT) {
|
|
ALOGD("readDisplayPanelErrorCount Unable to read %s - %s", path.c_str(),
|
|
strerror(errno));
|
|
}
|
|
return false;
|
|
} else {
|
|
file_contents = android::base::Trim(file_contents);
|
|
if (!android::base::ParseInt(file_contents, val)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool DisplayStatsReporter::captureDisplayPanelErrorStats(
|
|
const std::vector<std::string> &display_stats_paths,
|
|
struct DisplayPanelErrorStats *pcur_data) {
|
|
bool report_stats = false;
|
|
std::string path;
|
|
|
|
if (display_stats_paths.size() < kNumOfDisplayPanelErrorStats) {
|
|
ALOGE("Number of display stats paths (%zu) is less than expected (%d)",
|
|
display_stats_paths.size(), kNumOfDisplayPanelErrorStats);
|
|
return false;
|
|
}
|
|
|
|
int64_t index = PixelAtoms::DisplayPanelErrorStats::kPrimaryErrorCountTeFieldNumber;
|
|
index = index - kVendorAtomOffset;
|
|
path = display_stats_paths[index];
|
|
|
|
// Read primary panel error stats.
|
|
if (!readDisplayPanelErrorCount(path, &(pcur_data->primary_error_count_te))) {
|
|
pcur_data->primary_error_count_te = prev_data_.primary_error_count_te;
|
|
} else {
|
|
report_stats |= (pcur_data->primary_error_count_te > prev_data_.primary_error_count_te);
|
|
}
|
|
|
|
index = PixelAtoms::DisplayPanelErrorStats::kPrimaryErrorCountUnknownFieldNumber;
|
|
index = index - kVendorAtomOffset;
|
|
path = display_stats_paths[index];
|
|
if (!readDisplayPanelErrorCount(path, &(pcur_data->primary_error_count_unknown))) {
|
|
pcur_data->primary_error_count_unknown = prev_data_.primary_error_count_unknown;
|
|
} else {
|
|
report_stats |=
|
|
(pcur_data->primary_error_count_unknown > prev_data_.primary_error_count_unknown);
|
|
}
|
|
|
|
// Read secondary panel error stats.
|
|
index = PixelAtoms::DisplayPanelErrorStats::kSecondaryErrorCountTeFieldNumber;
|
|
index = index - kVendorAtomOffset;
|
|
path = display_stats_paths[index];
|
|
if (!readDisplayPanelErrorCount(path, &(pcur_data->secondary_error_count_te))) {
|
|
pcur_data->secondary_error_count_te = prev_data_.secondary_error_count_te;
|
|
} else {
|
|
report_stats |= (pcur_data->secondary_error_count_te > prev_data_.secondary_error_count_te);
|
|
}
|
|
|
|
index = PixelAtoms::DisplayPanelErrorStats::kSecondaryErrorCountUnknownFieldNumber;
|
|
index = index - kVendorAtomOffset;
|
|
path = display_stats_paths[index];
|
|
if (!readDisplayPanelErrorCount(path, &(pcur_data->secondary_error_count_unknown))) {
|
|
pcur_data->secondary_error_count_unknown = prev_data_.secondary_error_count_unknown;
|
|
} else {
|
|
report_stats |= (pcur_data->secondary_error_count_unknown >
|
|
prev_data_.secondary_error_count_unknown);
|
|
}
|
|
|
|
return report_stats;
|
|
}
|
|
|
|
void DisplayStatsReporter::logDisplayPanelErrorStats(
|
|
const std::shared_ptr<IStats> &stats_client,
|
|
const std::vector<std::string> &display_stats_paths) {
|
|
struct DisplayPanelErrorStats cur_data = prev_data_;
|
|
|
|
if (!captureDisplayPanelErrorStats(display_stats_paths, &cur_data)) {
|
|
prev_data_ = cur_data;
|
|
return;
|
|
}
|
|
|
|
VendorAtomValue tmp;
|
|
int64_t max_error_count = static_cast<int64_t>(INT32_MAX);
|
|
int error_count;
|
|
std::vector<VendorAtomValue> values(kNumOfDisplayPanelErrorStats);
|
|
|
|
error_count = std::min<int64_t>(
|
|
cur_data.primary_error_count_te - prev_data_.primary_error_count_te, max_error_count);
|
|
tmp.set<VendorAtomValue::intValue>(error_count);
|
|
int64_t index = PixelAtoms::DisplayPanelErrorStats::kPrimaryErrorCountTeFieldNumber;
|
|
index = index - kVendorAtomOffset;
|
|
values[index] = tmp;
|
|
|
|
error_count = std::min<int64_t>(
|
|
cur_data.primary_error_count_unknown - prev_data_.primary_error_count_unknown,
|
|
max_error_count);
|
|
tmp.set<VendorAtomValue::intValue>(error_count);
|
|
index = PixelAtoms::DisplayPanelErrorStats::kPrimaryErrorCountUnknownFieldNumber;
|
|
index = index - kVendorAtomOffset;
|
|
values[index] = tmp;
|
|
|
|
prev_data_ = cur_data;
|
|
|
|
ALOGD("Report updated display panel metrics to stats service");
|
|
// Send vendor atom to IStats HAL
|
|
VendorAtom event = {.reverseDomainName = "",
|
|
.atomId = PixelAtoms::Atom::kDisplayPanelErrorStats,
|
|
.values = std::move(values)};
|
|
const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
|
|
if (!ret.isOk())
|
|
ALOGE("Unable to report display Display Panel stats to Stats service");
|
|
}
|
|
|
|
void DisplayStatsReporter::logDisplayStats(const std::shared_ptr<IStats> &stats_client,
|
|
const std::vector<std::string> &display_stats_paths) {
|
|
logDisplayPanelErrorStats(stats_client, display_stats_paths);
|
|
}
|
|
|
|
} // namespace pixel
|
|
} // namespace google
|
|
} // namespace hardware
|
|
} // namespace android
|