1bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian/*
2bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * Copyright (C) 2016 The Android Open Source Project
3bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian *
4bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * Licensed under the Apache License, Version 2.0 (the "License");
5bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * you may not use this file except in compliance with the License.
6bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * You may obtain a copy of the License at
7bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian *
8bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian *      http://www.apache.org/licenses/LICENSE-2.0
9bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian *
10bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * Unless required by applicable law or agreed to in writing, software
11bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * distributed under the License is distributed on an "AS IS" BASIS,
12bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * See the License for the specific language governing permissions and
14bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian * limitations under the License.
15bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian */
16bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
17bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#define LOG_TAG "storaged"
18bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
19bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <stdint.h>
20bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <time.h>
21bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
22bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <string>
23bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <unordered_map>
24bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
259c54268dce4c82f066e24dfc40803192f537e35fJin Qian#include <android/content/pm/IPackageManagerNative.h>
26bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <android-base/file.h>
27bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <android-base/logging.h>
28bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <android-base/macros.h>
299b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian#include <android-base/parseint.h>
30e83a6107c7b5c4e5bc4cca56012025de301212e7Jin Qian#include <android-base/strings.h>
31bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <android-base/stringprintf.h>
329c54268dce4c82f066e24dfc40803192f537e35fJin Qian#include <binder/IServiceManager.h>
33bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include <log/log_event_list.h>
34bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
35bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include "storaged.h"
36bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian#include "storaged_uid_monitor.h"
37bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
38bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qianusing namespace android;
39bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qianusing namespace android::base;
409c54268dce4c82f066e24dfc40803192f537e35fJin Qianusing namespace android::content::pm;
41bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
429c54268dce4c82f066e24dfc40803192f537e35fJin Qianstatic bool refresh_uid_names;
43bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
445b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianstd::unordered_map<uint32_t, struct uid_info> uid_monitor::get_uid_io_stats()
45bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian{
465b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    std::unique_ptr<lock_t> lock(new lock_t(&um_lock));
475b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    return get_uid_io_stats_locked();
485b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian};
49bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
509c54268dce4c82f066e24dfc40803192f537e35fJin Qianstatic void get_uid_names(const vector<int>& uids, const vector<std::string*>& uid_names)
519c54268dce4c82f066e24dfc40803192f537e35fJin Qian{
529c54268dce4c82f066e24dfc40803192f537e35fJin Qian    sp<IServiceManager> sm = defaultServiceManager();
539c54268dce4c82f066e24dfc40803192f537e35fJin Qian    if (sm == NULL) {
549c54268dce4c82f066e24dfc40803192f537e35fJin Qian        LOG_TO(SYSTEM, ERROR) << "defaultServiceManager failed";
559c54268dce4c82f066e24dfc40803192f537e35fJin Qian        return;
569c54268dce4c82f066e24dfc40803192f537e35fJin Qian    }
579c54268dce4c82f066e24dfc40803192f537e35fJin Qian
589c54268dce4c82f066e24dfc40803192f537e35fJin Qian    sp<IBinder> binder = sm->getService(String16("package_native"));
599c54268dce4c82f066e24dfc40803192f537e35fJin Qian    if (binder == NULL) {
609c54268dce4c82f066e24dfc40803192f537e35fJin Qian        LOG_TO(SYSTEM, ERROR) << "getService package_native failed";
619c54268dce4c82f066e24dfc40803192f537e35fJin Qian        return;
629c54268dce4c82f066e24dfc40803192f537e35fJin Qian    }
639c54268dce4c82f066e24dfc40803192f537e35fJin Qian
649c54268dce4c82f066e24dfc40803192f537e35fJin Qian    sp<IPackageManagerNative> package_mgr = interface_cast<IPackageManagerNative>(binder);
659c54268dce4c82f066e24dfc40803192f537e35fJin Qian    std::vector<std::string> names;
669c54268dce4c82f066e24dfc40803192f537e35fJin Qian    binder::Status status = package_mgr->getNamesForUids(uids, &names);
679c54268dce4c82f066e24dfc40803192f537e35fJin Qian    if (!status.isOk()) {
689c54268dce4c82f066e24dfc40803192f537e35fJin Qian        LOG_TO(SYSTEM, ERROR) << "package_native::getNamesForUids failed: "
699c54268dce4c82f066e24dfc40803192f537e35fJin Qian                              << status.exceptionMessage();
709c54268dce4c82f066e24dfc40803192f537e35fJin Qian        return;
719c54268dce4c82f066e24dfc40803192f537e35fJin Qian    }
729c54268dce4c82f066e24dfc40803192f537e35fJin Qian
739c54268dce4c82f066e24dfc40803192f537e35fJin Qian    for (uint32_t i = 0; i < uid_names.size(); i++) {
749c54268dce4c82f066e24dfc40803192f537e35fJin Qian        if (!names[i].empty()) {
759c54268dce4c82f066e24dfc40803192f537e35fJin Qian            *uid_names[i] = names[i];
769c54268dce4c82f066e24dfc40803192f537e35fJin Qian        }
779c54268dce4c82f066e24dfc40803192f537e35fJin Qian    }
789c54268dce4c82f066e24dfc40803192f537e35fJin Qian
799c54268dce4c82f066e24dfc40803192f537e35fJin Qian    refresh_uid_names = false;
809c54268dce4c82f066e24dfc40803192f537e35fJin Qian}
819c54268dce4c82f066e24dfc40803192f537e35fJin Qian
825b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianstd::unordered_map<uint32_t, struct uid_info> uid_monitor::get_uid_io_stats_locked()
83bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian{
845b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    std::unordered_map<uint32_t, struct uid_info> uid_io_stats;
85bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian    std::string buffer;
869b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian    if (!ReadFileToString(UID_IO_STATS_PATH, &buffer)) {
87bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian        PLOG_TO(SYSTEM, ERROR) << UID_IO_STATS_PATH << ": ReadFileToString failed";
885b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian        return uid_io_stats;
89bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian    }
90bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
919b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian    std::vector<std::string> io_stats = Split(buffer, "\n");
92bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian    struct uid_info u;
939c54268dce4c82f066e24dfc40803192f537e35fJin Qian    vector<int> uids;
949c54268dce4c82f066e24dfc40803192f537e35fJin Qian    vector<std::string*> uid_names;
95bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
96e83a6107c7b5c4e5bc4cca56012025de301212e7Jin Qian    for (uint32_t i = 0; i < io_stats.size(); i++) {
97e83a6107c7b5c4e5bc4cca56012025de301212e7Jin Qian        if (io_stats[i].empty()) {
98e83a6107c7b5c4e5bc4cca56012025de301212e7Jin Qian            continue;
99e83a6107c7b5c4e5bc4cca56012025de301212e7Jin Qian        }
1009b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian        std::vector<std::string> fields = Split(io_stats[i], " ");
1019b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian        if (fields.size() < 11 ||
1029b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian            !ParseUint(fields[0],  &u.uid) ||
1039b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian            !ParseUint(fields[1],  &u.io[FOREGROUND].rchar) ||
1049b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian            !ParseUint(fields[2],  &u.io[FOREGROUND].wchar) ||
1059b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian            !ParseUint(fields[3],  &u.io[FOREGROUND].read_bytes) ||
1069b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian            !ParseUint(fields[4],  &u.io[FOREGROUND].write_bytes) ||
1079b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian            !ParseUint(fields[5],  &u.io[BACKGROUND].rchar) ||
1089b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian            !ParseUint(fields[6],  &u.io[BACKGROUND].wchar) ||
1099b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian            !ParseUint(fields[7],  &u.io[BACKGROUND].read_bytes) ||
1109b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian            !ParseUint(fields[8],  &u.io[BACKGROUND].write_bytes) ||
1119b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian            !ParseUint(fields[9],  &u.io[FOREGROUND].fsync) ||
1129b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian            !ParseUint(fields[10], &u.io[BACKGROUND].fsync)) {
1139b1aeae7306cfd19e0c4704db5807edf8c0c14b7Jin Qian            LOG_TO(SYSTEM, WARNING) << "Invalid I/O stats: \""
114e83a6107c7b5c4e5bc4cca56012025de301212e7Jin Qian                                    << io_stats[i] << "\"";
115e83a6107c7b5c4e5bc4cca56012025de301212e7Jin Qian            continue;
116e83a6107c7b5c4e5bc4cca56012025de301212e7Jin Qian        }
117bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
1189c54268dce4c82f066e24dfc40803192f537e35fJin Qian        uid_io_stats[u.uid] = u;
1199c54268dce4c82f066e24dfc40803192f537e35fJin Qian        uid_io_stats[u.uid].name = std::to_string(u.uid);
1209c54268dce4c82f066e24dfc40803192f537e35fJin Qian        uids.push_back(u.uid);
1219c54268dce4c82f066e24dfc40803192f537e35fJin Qian        uid_names.push_back(&uid_io_stats[u.uid].name);
1225b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian        if (last_uid_io_stats.find(u.uid) == last_uid_io_stats.end()) {
1239c54268dce4c82f066e24dfc40803192f537e35fJin Qian            refresh_uid_names = true;
124bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian        } else {
1259c54268dce4c82f066e24dfc40803192f537e35fJin Qian            uid_io_stats[u.uid].name = last_uid_io_stats[u.uid].name;
126bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian        }
127bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian    }
128bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
1299c54268dce4c82f066e24dfc40803192f537e35fJin Qian    if (!uids.empty() && refresh_uid_names) {
1309c54268dce4c82f066e24dfc40803192f537e35fJin Qian        get_uid_names(uids, uid_names);
131bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian    }
132bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
1335b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    return uid_io_stats;
134bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian}
135bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
1365b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianstatic const int MAX_UID_RECORDS_SIZE = 1000 * 48; // 1000 uids in 48 hours
137a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian
1385b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianstatic inline int records_size(
1398157775d791c124fcd84cdbeb7a751226bcb285bJin Qian    const std::map<uint64_t, struct uid_records>& curr_records)
140a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian{
1415b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    int count = 0;
1428157775d791c124fcd84cdbeb7a751226bcb285bJin Qian    for (auto const& it : curr_records) {
1438157775d791c124fcd84cdbeb7a751226bcb285bJin Qian        count += it.second.entries.size();
1445b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    }
1455b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    return count;
146a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian}
147a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian
1485b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianstatic struct uid_io_usage zero_io_usage;
1499cdfdd3ff9481318a1631bd5584bfb527756d4d4Jin Qian
1505b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianvoid uid_monitor::add_records_locked(uint64_t curr_ts)
1515b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian{
1525b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    // remove records more than 5 days old
1535b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    if (curr_ts > 5 * DAY_TO_SEC) {
1545b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian        auto it = records.lower_bound(curr_ts - 5 * DAY_TO_SEC);
1555b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian        records.erase(records.begin(), it);
1569cdfdd3ff9481318a1631bd5584bfb527756d4d4Jin Qian    }
1579cdfdd3ff9481318a1631bd5584bfb527756d4d4Jin Qian
1588157775d791c124fcd84cdbeb7a751226bcb285bJin Qian    struct uid_records new_records;
1595b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    for (const auto& p : curr_io_stats) {
1605b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian        struct uid_record record = {};
1615b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian        record.name = p.first;
1625b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian        record.ios = p.second;
1635b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian        if (memcmp(&record.ios, &zero_io_usage, sizeof(struct uid_io_usage))) {
1648157775d791c124fcd84cdbeb7a751226bcb285bJin Qian            new_records.entries.push_back(record);
1655b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian        }
1669cdfdd3ff9481318a1631bd5584bfb527756d4d4Jin Qian    }
1679cdfdd3ff9481318a1631bd5584bfb527756d4d4Jin Qian
1685b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    curr_io_stats.clear();
1698157775d791c124fcd84cdbeb7a751226bcb285bJin Qian    new_records.start_ts = start_ts;
1708157775d791c124fcd84cdbeb7a751226bcb285bJin Qian    start_ts = curr_ts;
171a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian
1728157775d791c124fcd84cdbeb7a751226bcb285bJin Qian    if (new_records.entries.empty())
1735b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian      return;
1745b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian
1755b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    // make some room for new records
1765b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    int overflow = records_size(records) +
1778157775d791c124fcd84cdbeb7a751226bcb285bJin Qian        new_records.entries.size() - MAX_UID_RECORDS_SIZE;
1785b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    while (overflow > 0 && records.size() > 0) {
1798157775d791c124fcd84cdbeb7a751226bcb285bJin Qian        auto del_it = records.begin();
1808157775d791c124fcd84cdbeb7a751226bcb285bJin Qian        overflow -= del_it->second.entries.size();
1815b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian        records.erase(records.begin());
1825b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    }
1835b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian
1848157775d791c124fcd84cdbeb7a751226bcb285bJin Qian    records[curr_ts] = new_records;
185a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian}
186a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian
1878157775d791c124fcd84cdbeb7a751226bcb285bJin Qianstd::map<uint64_t, struct uid_records> uid_monitor::dump(
188dd41d6b17115f5592f184b17351383c1b06d6336Jin Qian    double hours, uint64_t threshold, bool force_report)
189bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian{
1901275b1b6aaf417243ff3be17a400a21e26c42f39Jin Qian    if (force_report) {
1911275b1b6aaf417243ff3be17a400a21e26c42f39Jin Qian        report();
1921275b1b6aaf417243ff3be17a400a21e26c42f39Jin Qian    }
1931275b1b6aaf417243ff3be17a400a21e26c42f39Jin Qian
1945b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    std::unique_ptr<lock_t> lock(new lock_t(&um_lock));
195bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
1968157775d791c124fcd84cdbeb7a751226bcb285bJin Qian    std::map<uint64_t, struct uid_records> dump_records;
1975b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    uint64_t first_ts = 0;
1985b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian
1995b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    if (hours != 0) {
200dd41d6b17115f5592f184b17351383c1b06d6336Jin Qian        first_ts = time(NULL) - hours * HOUR_TO_SEC;
201bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian    }
202bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
203e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian    for (auto it = records.lower_bound(first_ts); it != records.end(); ++it) {
2048157775d791c124fcd84cdbeb7a751226bcb285bJin Qian        const std::vector<struct uid_record>& recs = it->second.entries;
2058157775d791c124fcd84cdbeb7a751226bcb285bJin Qian        struct uid_records filtered;
206e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian
207e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian        for (const auto& rec : recs) {
208e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian            if (rec.ios.bytes[READ][FOREGROUND][CHARGER_ON] +
209e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian                rec.ios.bytes[READ][FOREGROUND][CHARGER_OFF] +
210e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian                rec.ios.bytes[READ][BACKGROUND][CHARGER_ON] +
211e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian                rec.ios.bytes[READ][BACKGROUND][CHARGER_OFF] +
212e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian                rec.ios.bytes[WRITE][FOREGROUND][CHARGER_ON] +
213e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian                rec.ios.bytes[WRITE][FOREGROUND][CHARGER_OFF] +
214e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian                rec.ios.bytes[WRITE][BACKGROUND][CHARGER_ON] +
215e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian                rec.ios.bytes[WRITE][BACKGROUND][CHARGER_OFF] > threshold) {
2168157775d791c124fcd84cdbeb7a751226bcb285bJin Qian                filtered.entries.push_back(rec);
217e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian            }
218e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian        }
2198157775d791c124fcd84cdbeb7a751226bcb285bJin Qian
2208157775d791c124fcd84cdbeb7a751226bcb285bJin Qian        if (filtered.entries.empty())
2218157775d791c124fcd84cdbeb7a751226bcb285bJin Qian            continue;
2228157775d791c124fcd84cdbeb7a751226bcb285bJin Qian
2238157775d791c124fcd84cdbeb7a751226bcb285bJin Qian        filtered.start_ts = it->second.start_ts;
224e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian        dump_records.insert(
2258157775d791c124fcd84cdbeb7a751226bcb285bJin Qian            std::pair<uint64_t, struct uid_records>(it->first, filtered));
226e5ea17c84024badac9498bd61d1c07f253d75cacJin Qian    }
2275b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian
2285b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    return dump_records;
2295b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian}
230bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
2315b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianvoid uid_monitor::update_curr_io_stats_locked()
2325b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian{
2335b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    std::unordered_map<uint32_t, struct uid_info> uid_io_stats =
2345b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian        get_uid_io_stats_locked();
2355b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    if (uid_io_stats.empty()) {
236bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian        return;
237bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian    }
238bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
2395b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    for (const auto& it : uid_io_stats) {
240bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian        const struct uid_info& uid = it.second;
2415b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian
2425b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian        if (curr_io_stats.find(uid.name) == curr_io_stats.end()) {
2435b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian          curr_io_stats[uid.name] = {};
2449cdfdd3ff9481318a1631bd5584bfb527756d4d4Jin Qian        }
2459cdfdd3ff9481318a1631bd5584bfb527756d4d4Jin Qian
2465b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian        struct uid_io_usage& usage = curr_io_stats[uid.name];
247baff640d5d0a1abd95458f08017fe0e8babb8103Jin Qian        int64_t fg_rd_delta = uid.io[FOREGROUND].read_bytes -
2485b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian            last_uid_io_stats[uid.uid].io[FOREGROUND].read_bytes;
249baff640d5d0a1abd95458f08017fe0e8babb8103Jin Qian        int64_t bg_rd_delta = uid.io[BACKGROUND].read_bytes -
2505b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian            last_uid_io_stats[uid.uid].io[BACKGROUND].read_bytes;
251baff640d5d0a1abd95458f08017fe0e8babb8103Jin Qian        int64_t fg_wr_delta = uid.io[FOREGROUND].write_bytes -
2525b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian            last_uid_io_stats[uid.uid].io[FOREGROUND].write_bytes;
253baff640d5d0a1abd95458f08017fe0e8babb8103Jin Qian        int64_t bg_wr_delta = uid.io[BACKGROUND].write_bytes -
254baff640d5d0a1abd95458f08017fe0e8babb8103Jin Qian            last_uid_io_stats[uid.uid].io[BACKGROUND].write_bytes;
255baff640d5d0a1abd95458f08017fe0e8babb8103Jin Qian
256baff640d5d0a1abd95458f08017fe0e8babb8103Jin Qian        usage.bytes[READ][FOREGROUND][charger_stat] +=
257ccae2b5779e01e885bd7c85e314a2f8f523c4b94Jin Qian            (fg_rd_delta < 0) ? 0 : fg_rd_delta;
258baff640d5d0a1abd95458f08017fe0e8babb8103Jin Qian        usage.bytes[READ][BACKGROUND][charger_stat] +=
259ccae2b5779e01e885bd7c85e314a2f8f523c4b94Jin Qian            (bg_rd_delta < 0) ? 0 : bg_rd_delta;
260baff640d5d0a1abd95458f08017fe0e8babb8103Jin Qian        usage.bytes[WRITE][FOREGROUND][charger_stat] +=
261ccae2b5779e01e885bd7c85e314a2f8f523c4b94Jin Qian            (fg_wr_delta < 0) ? 0 : fg_wr_delta;
2625b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian        usage.bytes[WRITE][BACKGROUND][charger_stat] +=
263ccae2b5779e01e885bd7c85e314a2f8f523c4b94Jin Qian            (bg_wr_delta < 0) ? 0 : bg_wr_delta;
264bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian    }
265bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
2665b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    last_uid_io_stats = uid_io_stats;
267bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian}
268bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
2695b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianvoid uid_monitor::report()
2705b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian{
2715b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    std::unique_ptr<lock_t> lock(new lock_t(&um_lock));
2725b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian
2735b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    update_curr_io_stats_locked();
2745b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    add_records_locked(time(NULL));
2755b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian}
2765b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian
2775b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianvoid uid_monitor::set_charger_state(charger_stat_t stat)
278bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian{
2795b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    std::unique_ptr<lock_t> lock(new lock_t(&um_lock));
280bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian
2815b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    if (charger_stat == stat) {
282bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian        return;
283bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian    }
284a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian
2855b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    update_curr_io_stats_locked();
2865b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    charger_stat = stat;
2875b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian}
2885b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian
2895b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianvoid uid_monitor::init(charger_stat_t stat)
2905b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian{
2915b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    charger_stat = stat;
2928157775d791c124fcd84cdbeb7a751226bcb285bJin Qian    start_ts = time(NULL);
2935b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    last_uid_io_stats = get_uid_io_stats();
2945b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian}
2955b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian
2965b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qianuid_monitor::uid_monitor()
2975b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian{
2985b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    sem_init(&um_lock, 0, 1);
299a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian}
300a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian
301a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qianuid_monitor::~uid_monitor()
302a2e5bd1347fe2e70d6eb0b54b5b077cdf14cabcfJin Qian{
3035b962c6dbd305946ece05ffbd81d29c2ea211673Jin Qian    sem_destroy(&um_lock);
304bcd6e3b9d92b2eea3b054372c9adf00a1e6235bcJin Qian}
305