1 /*
2 * Copyright 2019 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 "GpuStatsPuller.h"
18
19 #include <binder/IServiceManager.h>
20 #include <graphicsenv/GpuStatsInfo.h>
21 #include <graphicsenv/IGpuService.h>
22
23 #include "logd/LogEvent.h"
24
25 #include "stats_log_util.h"
26 #include "statslog.h"
27
28 namespace android {
29 namespace os {
30 namespace statsd {
31
32 using android::util::ProtoReader;
33
GpuStatsPuller(const int tagId)34 GpuStatsPuller::GpuStatsPuller(const int tagId) : StatsPuller(tagId) {
35 }
36
getGpuService()37 static sp<IGpuService> getGpuService() {
38 const sp<IBinder> binder = defaultServiceManager()->checkService(String16("gpu"));
39 if (!binder) {
40 ALOGE("Failed to get gpu service");
41 return nullptr;
42 }
43
44 return interface_cast<IGpuService>(binder);
45 }
46
pullGpuStatsGlobalInfo(const sp<IGpuService> & gpuService,std::vector<std::shared_ptr<LogEvent>> * data)47 static bool pullGpuStatsGlobalInfo(const sp<IGpuService>& gpuService,
48 std::vector<std::shared_ptr<LogEvent>>* data) {
49 std::vector<GpuStatsGlobalInfo> stats;
50 status_t status = gpuService->getGpuStatsGlobalInfo(&stats);
51 if (status != OK) {
52 return false;
53 }
54
55 data->clear();
56 data->reserve(stats.size());
57 for (const auto& info : stats) {
58 std::shared_ptr<LogEvent> event = make_shared<LogEvent>(
59 android::util::GPU_STATS_GLOBAL_INFO, getWallClockNs(), getElapsedRealtimeNs());
60 if (!event->write(info.driverPackageName)) return false;
61 if (!event->write(info.driverVersionName)) return false;
62 if (!event->write((int64_t)info.driverVersionCode)) return false;
63 if (!event->write(info.driverBuildTime)) return false;
64 if (!event->write((int64_t)info.glLoadingCount)) return false;
65 if (!event->write((int64_t)info.glLoadingFailureCount)) return false;
66 if (!event->write((int64_t)info.vkLoadingCount)) return false;
67 if (!event->write((int64_t)info.vkLoadingFailureCount)) return false;
68 if (!event->write(info.vulkanVersion)) return false;
69 if (!event->write(info.cpuVulkanVersion)) return false;
70 if (!event->write(info.glesVersion)) return false;
71 if (!event->write((int64_t)info.angleLoadingCount)) return false;
72 if (!event->write((int64_t)info.angleLoadingFailureCount)) return false;
73 event->init();
74 data->emplace_back(event);
75 }
76
77 return true;
78 }
79
pullGpuStatsAppInfo(const sp<IGpuService> & gpuService,std::vector<std::shared_ptr<LogEvent>> * data)80 static bool pullGpuStatsAppInfo(const sp<IGpuService>& gpuService,
81 std::vector<std::shared_ptr<LogEvent>>* data) {
82 std::vector<GpuStatsAppInfo> stats;
83 status_t status = gpuService->getGpuStatsAppInfo(&stats);
84 if (status != OK) {
85 return false;
86 }
87
88 data->clear();
89 data->reserve(stats.size());
90 for (const auto& info : stats) {
91 std::shared_ptr<LogEvent> event = make_shared<LogEvent>(
92 android::util::GPU_STATS_APP_INFO, getWallClockNs(), getElapsedRealtimeNs());
93 if (!event->write(info.appPackageName)) return false;
94 if (!event->write((int64_t)info.driverVersionCode)) return false;
95 if (!event->write(int64VectorToProtoByteString(info.glDriverLoadingTime))) return false;
96 if (!event->write(int64VectorToProtoByteString(info.vkDriverLoadingTime))) return false;
97 if (!event->write(int64VectorToProtoByteString(info.angleDriverLoadingTime))) return false;
98 if (!event->write(info.cpuVulkanInUse)) return false;
99 event->init();
100 data->emplace_back(event);
101 }
102
103 return true;
104 }
105
PullInternal(std::vector<std::shared_ptr<LogEvent>> * data)106 bool GpuStatsPuller::PullInternal(std::vector<std::shared_ptr<LogEvent>>* data) {
107 const sp<IGpuService> gpuService = getGpuService();
108 if (!gpuService) {
109 return false;
110 }
111
112 switch (mTagId) {
113 case android::util::GPU_STATS_GLOBAL_INFO:
114 return pullGpuStatsGlobalInfo(gpuService, data);
115 case android::util::GPU_STATS_APP_INFO:
116 return pullGpuStatsAppInfo(gpuService, data);
117 default:
118 break;
119 }
120
121 return false;
122 }
123
protoOutputStreamToByteString(ProtoOutputStream & proto)124 static std::string protoOutputStreamToByteString(ProtoOutputStream& proto) {
125 if (!proto.size()) return "";
126
127 std::string byteString;
128 sp<ProtoReader> reader = proto.data();
129 while (reader->readBuffer() != nullptr) {
130 const size_t toRead = reader->currentToRead();
131 byteString.append((char*)reader->readBuffer(), toRead);
132 reader->move(toRead);
133 }
134
135 if (byteString.size() != proto.size()) return "";
136
137 return byteString;
138 }
139
int64VectorToProtoByteString(const std::vector<int64_t> & value)140 std::string int64VectorToProtoByteString(const std::vector<int64_t>& value) {
141 if (value.empty()) return "";
142
143 ProtoOutputStream proto;
144 for (const auto& ele : value) {
145 proto.write(android::util::FIELD_TYPE_INT64 | android::util::FIELD_COUNT_REPEATED |
146 1 /* field id */,
147 (long long)ele);
148 }
149
150 return protoOutputStreamToByteString(proto);
151 }
152
153 } // namespace statsd
154 } // namespace os
155 } // namespace android
156