Home | History | Annotate | Download | only in include
      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