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 #include <cutils/multiuser.h> 27 #include <utils/Mutex.h> 28 29 #include "storaged.pb.h" 30 #include "uid_info.h" 31 32 #define FRIEND_TEST(test_case_name, test_name) \ 33 friend class test_case_name##_##test_name##_Test 34 35 using namespace std; 36 using namespace storaged_proto; 37 using namespace android; 38 using namespace android::os::storaged; 39 40 class uid_info : public UidInfo { 41 public: 42 bool parse_uid_io_stats(string&& s); 43 }; 44 45 class io_usage { 46 public: 47 io_usage() : bytes{{{0}}} {}; 48 uint64_t bytes[IO_TYPES][UID_STATS][CHARGER_STATS]; 49 bool is_zero() const; 50 io_usage& operator+= (const io_usage& stats) { 51 for (int i = 0; i < IO_TYPES; i++) { 52 for (int j = 0; j < UID_STATS; j++) { 53 for (int k = 0; k < CHARGER_STATS; k++) { 54 bytes[i][j][k] += stats.bytes[i][j][k]; 55 } 56 } 57 } 58 return *this; 59 } 60 }; 61 62 struct uid_io_usage { 63 userid_t user_id; 64 io_usage uid_ios; 65 // mapped from task comm to task io usage 66 map<string, io_usage> task_ios; 67 }; 68 69 struct uid_record { 70 string name; 71 struct uid_io_usage ios; 72 }; 73 74 struct uid_records { 75 uint64_t start_ts; 76 vector<struct uid_record> entries; 77 }; 78 79 class uid_monitor { 80 private: 81 FRIEND_TEST(storaged_test, uid_monitor); 82 // last dump from /proc/uid_io/stats, uid -> uid_info 83 unordered_map<uint32_t, uid_info> last_uid_io_stats; 84 // current io usage for next report, app name -> uid_io_usage 85 unordered_map<string, struct uid_io_usage> curr_io_stats; 86 // io usage records, end timestamp -> {start timestamp, vector of records} 87 map<uint64_t, struct uid_records> io_history; 88 // charger ON/OFF 89 charger_stat_t charger_stat; 90 // protects curr_io_stats, last_uid_io_stats, records and charger_stat 91 Mutex uidm_mutex; 92 // start time for IO records 93 uint64_t start_ts; 94 // true if UID_IO_STATS_PATH is accessible 95 const bool enable; 96 97 // reads from /proc/uid_io/stats 98 unordered_map<uint32_t, uid_info> get_uid_io_stats_locked(); 99 // flushes curr_io_stats to records 100 void add_records_locked(uint64_t curr_ts); 101 // updates curr_io_stats and set last_uid_io_stats 102 void update_curr_io_stats_locked(); 103 // writes io_history to protobuf 104 void update_uid_io_proto(unordered_map<int, StoragedProto>* protos); 105 106 public: 107 uid_monitor(); 108 // called by storaged main thread 109 void init(charger_stat_t stat); 110 // called by storaged -u 111 unordered_map<uint32_t, uid_info> get_uid_io_stats(); 112 // called by dumpsys 113 map<uint64_t, struct uid_records> dump( 114 double hours, uint64_t threshold, bool force_report); 115 // called by battery properties listener 116 void set_charger_state(charger_stat_t stat); 117 // called by storaged periodic_chore or dump with force_report 118 bool enabled() { return enable; }; 119 void report(unordered_map<int, StoragedProto>* protos); 120 // restores io_history from protobuf 121 void load_uid_io_proto(const UidIOUsage& proto); 122 void clear_user_history(userid_t user_id); 123 }; 124 125 #endif /* _STORAGED_UID_MONITOR_H_ */ 126