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 #pragma once
18 
19 #include <graphicsenv/GpuStatsInfo.h>
20 #include <graphicsenv/GraphicsEnv.h>
21 #include <stats_pull_atom_callback.h>
22 #include <utils/String16.h>
23 #include <utils/Vector.h>
24 
25 #include <mutex>
26 #include <unordered_map>
27 #include <vector>
28 
29 namespace android {
30 
31 class GpuStats {
32 public:
33     ~GpuStats();
34 
35     // Insert new gpu driver stats into global stats and app stats.
36     void insertDriverStats(const std::string& driverPackageName,
37                            const std::string& driverVersionName, uint64_t driverVersionCode,
38                            int64_t driverBuildTime, const std::string& appPackageName,
39                            const int32_t vulkanVersion, GpuStatsInfo::Driver driver,
40                            bool isDriverLoaded, int64_t driverLoadingTime);
41     // Insert target stats into app stats or potentially global stats as well.
42     void insertTargetStats(const std::string& appPackageName, const uint64_t driverVersionCode,
43                            const GpuStatsInfo::Stats stats, const uint64_t value);
44     // dumpsys interface
45     void dump(const Vector<String16>& args, std::string* result);
46 
47     // This limits the worst case number of loading times tracked.
48     static const size_t MAX_NUM_LOADING_TIMES = 50;
49 
50 private:
51     // Friend class for testing.
52     friend class TestableGpuStats;
53 
54     // Native atom puller callback registered in statsd.
55     static AStatsManager_PullAtomCallbackReturn pullAtomCallback(int32_t atomTag,
56                                                                  AStatsEventList* data,
57                                                                  void* cookie);
58     // Pull global into into global atom.
59     AStatsManager_PullAtomCallbackReturn pullGlobalInfoAtom(AStatsEventList* data);
60     // Pull app into into app atom.
61     AStatsManager_PullAtomCallbackReturn pullAppInfoAtom(AStatsEventList* data);
62     // Dump global stats
63     void dumpGlobalLocked(std::string* result);
64     // Dump app stats
65     void dumpAppLocked(std::string* result);
66     // Append cpuVulkanVersion and glesVersion to system driver stats
67     void interceptSystemDriverStatsLocked();
68     // Registers statsd callbacks if they have not already been registered
69     void registerStatsdCallbacksIfNeeded();
70 
71     // Below limits the memory usage of GpuStats to be less than 10KB. This is
72     // the preferred number for statsd while maintaining nice data quality.
73     static const size_t MAX_NUM_APP_RECORDS = 100;
74     // GpuStats access should be guarded by mLock.
75     std::mutex mLock;
76     // True if statsd callbacks have been registered.
77     bool mStatsdRegistered = false;
78     // Key is driver version code.
79     std::unordered_map<uint64_t, GpuStatsGlobalInfo> mGlobalStats;
80     // Key is <app package name>+<driver version code>.
81     std::unordered_map<std::string, GpuStatsAppInfo> mAppStats;
82 };
83 
84 } // namespace android
85