• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "pixelstats: DisplayStats"
18 
19 #include <aidl/android/frameworks/stats/IStats.h>
20 #include <android-base/file.h>
21 #include <android-base/parseint.h>
22 #include <android-base/properties.h>
23 #include <android-base/stringprintf.h>
24 #include <android-base/strings.h>
25 #include <android/binder_manager.h>
26 #include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
27 #include <pixelstats/DisplayStatsReporter.h>
28 #include <utils/Log.h>
29 
30 #include <cinttypes>
31 
32 namespace android {
33 namespace hardware {
34 namespace google {
35 namespace pixel {
36 
37 using aidl::android::frameworks::stats::IStats;
38 using aidl::android::frameworks::stats::VendorAtom;
39 using aidl::android::frameworks::stats::VendorAtomValue;
40 using android::base::ReadFileToString;
41 using android::hardware::google::pixel::PixelAtoms::DisplayPanelErrorStats;
42 
DisplayStatsReporter()43 DisplayStatsReporter::DisplayStatsReporter() {}
44 
readDisplayPanelErrorCount(const std::string & path,int64_t * val)45 bool DisplayStatsReporter::readDisplayPanelErrorCount(const std::string &path, int64_t *val) {
46     std::string file_contents;
47 
48     if (path.empty()) {
49         return false;
50     }
51 
52     if (!ReadFileToString(path.c_str(), &file_contents)) {
53         if (errno != ENOENT) {
54             ALOGD("readDisplayPanelErrorCount Unable to read %s - %s", path.c_str(),
55                   strerror(errno));
56         }
57         return false;
58     } else {
59         file_contents = android::base::Trim(file_contents);
60         if (!android::base::ParseInt(file_contents, val)) {
61             return false;
62         }
63     }
64 
65     return true;
66 }
67 
captureDisplayPanelErrorStats(const std::vector<std::string> & display_stats_paths,struct DisplayPanelErrorStats * pcur_data)68 bool DisplayStatsReporter::captureDisplayPanelErrorStats(
69         const std::vector<std::string> &display_stats_paths,
70         struct DisplayPanelErrorStats *pcur_data) {
71     bool report_stats = false;
72     std::string path;
73 
74     if (display_stats_paths.size() < kNumOfDisplayPanelErrorStats) {
75         ALOGE("Number of display stats paths (%zu) is less than expected (%d)",
76               display_stats_paths.size(), kNumOfDisplayPanelErrorStats);
77         return false;
78     }
79 
80     int64_t index = PixelAtoms::DisplayPanelErrorStats::kPrimaryErrorCountTeFieldNumber;
81     index = index - kVendorAtomOffset;
82     path = display_stats_paths[index];
83 
84     // Read primary panel error stats.
85     if (!readDisplayPanelErrorCount(path, &(pcur_data->primary_error_count_te))) {
86         pcur_data->primary_error_count_te = prev_data_.primary_error_count_te;
87     } else {
88         report_stats |= (pcur_data->primary_error_count_te > prev_data_.primary_error_count_te);
89     }
90 
91     index = PixelAtoms::DisplayPanelErrorStats::kPrimaryErrorCountUnknownFieldNumber;
92     index = index - kVendorAtomOffset;
93     path = display_stats_paths[index];
94     if (!readDisplayPanelErrorCount(path, &(pcur_data->primary_error_count_unknown))) {
95         pcur_data->primary_error_count_unknown = prev_data_.primary_error_count_unknown;
96     } else {
97         report_stats |=
98                 (pcur_data->primary_error_count_unknown > prev_data_.primary_error_count_unknown);
99     }
100 
101     // Read secondary panel error stats.
102     index = PixelAtoms::DisplayPanelErrorStats::kSecondaryErrorCountTeFieldNumber;
103     index = index - kVendorAtomOffset;
104     path = display_stats_paths[index];
105     if (!readDisplayPanelErrorCount(path, &(pcur_data->secondary_error_count_te))) {
106         pcur_data->secondary_error_count_te = prev_data_.secondary_error_count_te;
107     } else {
108         report_stats |= (pcur_data->secondary_error_count_te > prev_data_.secondary_error_count_te);
109     }
110 
111     index = PixelAtoms::DisplayPanelErrorStats::kSecondaryErrorCountUnknownFieldNumber;
112     index = index - kVendorAtomOffset;
113     path = display_stats_paths[index];
114     if (!readDisplayPanelErrorCount(path, &(pcur_data->secondary_error_count_unknown))) {
115         pcur_data->secondary_error_count_unknown = prev_data_.secondary_error_count_unknown;
116     } else {
117         report_stats |= (pcur_data->secondary_error_count_unknown >
118                          prev_data_.secondary_error_count_unknown);
119     }
120 
121     return report_stats;
122 }
123 
logDisplayPanelErrorStats(const std::shared_ptr<IStats> & stats_client,const std::vector<std::string> & display_stats_paths)124 void DisplayStatsReporter::logDisplayPanelErrorStats(
125         const std::shared_ptr<IStats> &stats_client,
126         const std::vector<std::string> &display_stats_paths) {
127     struct DisplayPanelErrorStats cur_data = prev_data_;
128 
129     if (!captureDisplayPanelErrorStats(display_stats_paths, &cur_data)) {
130         prev_data_ = cur_data;
131         return;
132     }
133 
134     VendorAtomValue tmp;
135     int64_t max_error_count = static_cast<int64_t>(INT32_MAX);
136     int error_count;
137     std::vector<VendorAtomValue> values(kNumOfDisplayPanelErrorStats);
138 
139     error_count = std::min<int64_t>(
140             cur_data.primary_error_count_te - prev_data_.primary_error_count_te, max_error_count);
141     tmp.set<VendorAtomValue::intValue>(error_count);
142     int64_t index = PixelAtoms::DisplayPanelErrorStats::kPrimaryErrorCountTeFieldNumber;
143     index = index - kVendorAtomOffset;
144     values[index] = tmp;
145 
146     error_count = std::min<int64_t>(
147             cur_data.primary_error_count_unknown - prev_data_.primary_error_count_unknown,
148             max_error_count);
149     tmp.set<VendorAtomValue::intValue>(error_count);
150     index = PixelAtoms::DisplayPanelErrorStats::kPrimaryErrorCountUnknownFieldNumber;
151     index = index - kVendorAtomOffset;
152     values[index] = tmp;
153 
154     prev_data_ = cur_data;
155 
156     ALOGD("Report updated display panel metrics to stats service");
157     // Send vendor atom to IStats HAL
158     VendorAtom event = {.reverseDomainName = "",
159                         .atomId = PixelAtoms::Atom::kDisplayPanelErrorStats,
160                         .values = std::move(values)};
161     const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
162     if (!ret.isOk())
163         ALOGE("Unable to report display Display Panel stats to Stats service");
164 }
165 
logDisplayStats(const std::shared_ptr<IStats> & stats_client,const std::vector<std::string> & display_stats_paths)166 void DisplayStatsReporter::logDisplayStats(const std::shared_ptr<IStats> &stats_client,
167                                            const std::vector<std::string> &display_stats_paths) {
168     logDisplayPanelErrorStats(stats_client, display_stats_paths);
169 }
170 
171 }  // namespace pixel
172 }  // namespace google
173 }  // namespace hardware
174 }  // namespace android
175