• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2025 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 #include "MetricUploader.h"
18 
19 #include <android-base/logging.h>
20 #include <android/binder_manager.h>
21 
22 namespace aidl {
23 namespace google {
24 namespace hardware {
25 namespace power {
26 namespace impl {
27 namespace pixel {
28 
29 using android::frameworks::stats::VendorAtom;
30 
connectIStatsService()31 bool MetricUploader::connectIStatsService() {
32     if (mIStatsClient) {
33         LOG(INFO) << "IStats service client exists, skip this";
34         return true;
35     }
36 
37     const std::string iStatsServiceName = std::string(IStats::descriptor) + "/default";
38 
39     if (!AServiceManager_isDeclared(iStatsServiceName.c_str())) {
40         LOG(ERROR) << "IStats service not declared";
41         return false;
42     }
43 
44     ndk::SpAIBinder iStatsBinder =
45             ndk::SpAIBinder(AServiceManager_waitForService(iStatsServiceName.c_str()));
46     if (iStatsBinder.get() == nullptr) {
47         LOG(ERROR) << "Cannot get IStats binder!";
48         return false;
49     }
50 
51     mIStatsClient = IStats::fromBinder(iStatsBinder);
52     if (mIStatsClient == nullptr) {
53         LOG(ERROR) << "Cannot create IStats AIDL client!";
54         return false;
55     }
56 
57     LOG(INFO) << "Connected to IStats service.";
58     return true;
59 }
60 
init()61 bool MetricUploader::init() {
62     return connectIStatsService();
63 }
64 
reportAtom(const int32_t & atomId,std::vector<VendorAtomValue> && values)65 bool MetricUploader::reportAtom(const int32_t &atomId, std::vector<VendorAtomValue> &&values) {
66     LOG(VERBOSE) << "Reporting powerhal metrics ...";
67     VendorAtom event = {.reverseDomainName = "", .atomId = atomId, .values = std::move(values)};
68     if (!mIStatsClient) {
69         if (!connectIStatsService()) {
70             LOG(ERROR) << "Don't have valid connection to IStats service!";
71             return false;
72         }
73     }
74     const ndk::ScopedAStatus ret = mIStatsClient->reportVendorAtom(event);
75     if (!ret.isOk()) {
76         LOG(ERROR) << "Failed at reporting atom: " << ret.getMessage();
77         return false;
78     }
79     return true;
80 }
81 
uploadMetrics(const SessionJankStatsWithThermal & sessMetrics)82 bool MetricUploader::uploadMetrics(const SessionJankStatsWithThermal &sessMetrics) {
83     // TODO(guibing): Store the sessMetrics into the format of the metric atom
84     // and then call "reportAtom" to upload them.
85     std::string sessMetricDescriptor = std::string(toString(sessMetrics.scenarioType)) + "-" +
86                                        toString(sessMetrics.frameTimelineType);
87     if (sessMetrics.uid) {
88         sessMetricDescriptor += "-" + std::to_string(sessMetrics.uid.value());
89     }
90     LOG(VERBOSE) << "Uploading session metrics for " << sessMetricDescriptor;
91     return true;
92 }
93 
94 }  // namespace pixel
95 }  // namespace impl
96 }  // namespace power
97 }  // namespace hardware
98 }  // namespace google
99 }  // namespace aidl
100