1 /*
2  * Copyright (C) 2016 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 #ifndef _STORAGED_UID_MONITOR_H_
18 #define _STORAGED_UID_MONITOR_H_
19 
20 #include <stdint.h>
21 
22 #include <string>
23 #include <unordered_map>
24 #include <vector>
25 
26 enum uid_stat_t {
27     FOREGROUND = 0,
28     BACKGROUND = 1,
29     UID_STATS = 2
30 };
31 
32 enum charger_stat_t {
33     CHARGER_OFF = 0,
34     CHARGER_ON = 1,
35     CHARGER_STATS = 2
36 };
37 
38 enum io_type_t {
39     READ = 0,
40     WRITE = 1,
41     IO_TYPES = 2
42 };
43 
44 struct uid_io_stats {
45     uint64_t rchar;                 // characters read
46     uint64_t wchar;                 // characters written
47     uint64_t read_bytes;            // bytes read (from storage layer)
48     uint64_t write_bytes;           // bytes written (to storage layer)
49     uint64_t fsync;                 // number of fsync syscalls
50 };
51 
52 struct uid_info {
53     uint32_t uid;                   // user id
54     std::string name;               // package name
55     struct uid_io_stats io[UID_STATS];    // [0]:foreground [1]:background
56 };
57 
58 struct uid_io_usage {
59     uint64_t bytes[IO_TYPES][UID_STATS][CHARGER_STATS];
60 };
61 
62 struct uid_record {
63     std::string name;
64     struct uid_io_usage ios;
65 };
66 
67 struct uid_records {
68     uint64_t start_ts;
69     std::vector<struct uid_record> entries;
70 };
71 
72 class uid_monitor {
73 private:
74     // last dump from /proc/uid_io/stats, uid -> uid_info
75     std::unordered_map<uint32_t, struct uid_info> last_uid_io_stats;
76     // current io usage for next report, app name -> uid_io_usage
77     std::unordered_map<std::string, struct uid_io_usage> curr_io_stats;
78     // io usage records, end timestamp -> {start timestamp, vector of records}
79     std::map<uint64_t, struct uid_records> records;
80     // charger ON/OFF
81     charger_stat_t charger_stat;
82     // protects curr_io_stats, last_uid_io_stats, records and charger_stat
83     sem_t um_lock;
84     // start time for IO records
85     uint64_t start_ts;
86 
87     // reads from /proc/uid_io/stats
88     std::unordered_map<uint32_t, struct uid_info> get_uid_io_stats_locked();
89     // flushes curr_io_stats to records
90     void add_records_locked(uint64_t curr_ts);
91     // updates curr_io_stats and set last_uid_io_stats
92     void update_curr_io_stats_locked();
93 
94 public:
95     uid_monitor();
96     ~uid_monitor();
97     // called by storaged main thread
98     void init(charger_stat_t stat);
99     // called by storaged -u
100     std::unordered_map<uint32_t, struct uid_info> get_uid_io_stats();
101     // called by dumpsys
102     std::map<uint64_t, struct uid_records> dump(
103         double hours, uint64_t threshold, bool force_report);
104     // called by battery properties listener
105     void set_charger_state(charger_stat_t stat);
106     // called by storaged periodic_chore or dump with force_report
107     void report();
108 };
109 
110 #endif /* _STORAGED_UID_MONITOR_H_ */
111