blob: 17ea25b829e016c49e3da316db92fefab23ff16a [file] [log] [blame]
ynwang62cb3722016-06-17 14:30:48 -07001/*
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
Yang Jin3906c892017-06-22 15:18:21 -070017#include <inttypes.h>
Jin Qianbcd6e3b2016-12-28 15:43:51 -080018#include <stdint.h>
19
ynwang62cb3722016-06-17 14:30:48 -070020#include <vector>
21
Jin Qian9b1aeae2017-03-14 11:20:02 -070022#include <android-base/parseint.h>
23#include <android-base/parsedouble.h>
ynwang62cb3722016-06-17 14:30:48 -070024#include <binder/IBinder.h>
25#include <binder/IInterface.h>
26
27#include <binder/IPCThreadState.h>
28#include <binder/IServiceManager.h>
Jin Qiana2e5bd12017-01-24 16:23:13 -080029#include <binder/PermissionCache.h>
30#include <private/android_filesystem_config.h>
ynwang62cb3722016-06-17 14:30:48 -070031
32#include <storaged.h>
Jin Qian6df3bc62017-10-18 17:52:14 -070033#include <storaged_utils.h>
ynwang62cb3722016-06-17 14:30:48 -070034#include <storaged_service.h>
35
Jin Qiand691d6e2017-09-28 16:02:22 -070036using namespace std;
Jin Qian9b1aeae2017-03-14 11:20:02 -070037using namespace android::base;
38
Jin Qianb049d182017-10-12 17:02:17 -070039extern sp<storaged_t> storaged_sp;
ynwang62cb3722016-06-17 14:30:48 -070040
Jin Qianb049d182017-10-12 17:02:17 -070041status_t StoragedService::start() {
42 return BinderService<StoragedService>::publish();
Jin Qianbcd6e3b2016-12-28 15:43:51 -080043}
Jin Qiand691d6e2017-09-28 16:02:22 -070044
Jin Qian6df3bc62017-10-18 17:52:14 -070045void StoragedService::dumpUidRecords(int fd, const vector<uid_record>& entries) {
46 map<string, io_usage> merged_entries = merge_io_usage(entries);
47 for (const auto& rec : merged_entries) {
48 dprintf(fd, "%s %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64
49 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
50 rec.first.c_str(),
51 rec.second.bytes[READ][FOREGROUND][CHARGER_OFF],
52 rec.second.bytes[WRITE][FOREGROUND][CHARGER_OFF],
53 rec.second.bytes[READ][BACKGROUND][CHARGER_OFF],
54 rec.second.bytes[WRITE][BACKGROUND][CHARGER_OFF],
55 rec.second.bytes[READ][FOREGROUND][CHARGER_ON],
56 rec.second.bytes[WRITE][FOREGROUND][CHARGER_ON],
57 rec.second.bytes[READ][BACKGROUND][CHARGER_ON],
58 rec.second.bytes[WRITE][BACKGROUND][CHARGER_ON]);
59 }
60}
61
62void StoragedService::dumpUidRecordsDebug(int fd, const vector<uid_record>& entries) {
63 for (const auto& record : entries) {
64 const io_usage& uid_usage = record.ios.uid_ios;
65 dprintf(fd, "%s_%d %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64
66 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
67 record.name.c_str(), record.ios.user_id,
68 uid_usage.bytes[READ][FOREGROUND][CHARGER_OFF],
69 uid_usage.bytes[WRITE][FOREGROUND][CHARGER_OFF],
70 uid_usage.bytes[READ][BACKGROUND][CHARGER_OFF],
71 uid_usage.bytes[WRITE][BACKGROUND][CHARGER_OFF],
72 uid_usage.bytes[READ][FOREGROUND][CHARGER_ON],
73 uid_usage.bytes[WRITE][FOREGROUND][CHARGER_ON],
74 uid_usage.bytes[READ][BACKGROUND][CHARGER_ON],
75 uid_usage.bytes[WRITE][BACKGROUND][CHARGER_ON]);
76
77 for (const auto& task_it : record.ios.task_ios) {
78 const io_usage& task_usage = task_it.second;
79 const string& comm = task_it.first;
80 dprintf(fd, "-> %s %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64
81 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
82 comm.c_str(),
83 task_usage.bytes[READ][FOREGROUND][CHARGER_OFF],
84 task_usage.bytes[WRITE][FOREGROUND][CHARGER_OFF],
85 task_usage.bytes[READ][BACKGROUND][CHARGER_OFF],
86 task_usage.bytes[WRITE][BACKGROUND][CHARGER_OFF],
87 task_usage.bytes[READ][FOREGROUND][CHARGER_ON],
88 task_usage.bytes[WRITE][FOREGROUND][CHARGER_ON],
89 task_usage.bytes[READ][BACKGROUND][CHARGER_ON],
90 task_usage.bytes[WRITE][BACKGROUND][CHARGER_ON]);
91 }
92 }
93}
94
Jin Qianb049d182017-10-12 17:02:17 -070095status_t StoragedService::dump(int fd, const Vector<String16>& args) {
Jin Qiana2e5bd12017-01-24 16:23:13 -080096 IPCThreadState* self = IPCThreadState::self();
97 const int pid = self->getCallingPid();
98 const int uid = self->getCallingUid();
99 if ((uid != AID_SHELL) &&
100 !PermissionCache::checkPermission(
101 String16("android.permission.DUMP"), pid, uid)) {
102 return PERMISSION_DENIED;
103 }
104
Jin Qiandd41d6b2017-02-10 17:23:16 -0800105 double hours = 0;
Jin Qiane5ea17c2017-02-10 10:50:03 -0800106 int time_window = 0;
107 uint64_t threshold = 0;
Jin Qian1275b1b2017-02-06 14:02:50 -0800108 bool force_report = false;
Yang Jin3906c892017-06-22 15:18:21 -0700109 bool debug = false;
Jin Qian9cdfdd32017-01-31 17:33:20 -0800110 for (size_t i = 0; i < args.size(); i++) {
111 const auto& arg = args[i];
112 if (arg == String16("--hours")) {
113 if (++i >= args.size())
114 break;
Jin Qian9b1aeae2017-03-14 11:20:02 -0700115 if(!ParseDouble(String8(args[i]).c_str(), &hours))
116 return BAD_VALUE;
Jin Qian9cdfdd32017-01-31 17:33:20 -0800117 continue;
118 }
Jin Qiane5ea17c2017-02-10 10:50:03 -0800119 if (arg == String16("--time_window")) {
120 if (++i >= args.size())
121 break;
Jin Qian9b1aeae2017-03-14 11:20:02 -0700122 if(!ParseInt(String8(args[i]).c_str(), &time_window))
123 return BAD_VALUE;
Jin Qiane5ea17c2017-02-10 10:50:03 -0800124 continue;
125 }
126 if (arg == String16("--threshold")) {
127 if (++i >= args.size())
128 break;
Jin Qian9b1aeae2017-03-14 11:20:02 -0700129 if(!ParseUint(String8(args[i]).c_str(), &threshold))
130 return BAD_VALUE;
Jin Qiane5ea17c2017-02-10 10:50:03 -0800131 continue;
132 }
Jin Qian1275b1b2017-02-06 14:02:50 -0800133 if (arg == String16("--force")) {
134 force_report = true;
135 continue;
136 }
Yang Jin3906c892017-06-22 15:18:21 -0700137 if (arg == String16("--debug")) {
138 debug = true;
139 continue;
140 }
Jin Qian9cdfdd32017-01-31 17:33:20 -0800141 }
142
Jin Qian81577752017-02-21 12:09:39 -0800143 uint64_t last_ts = 0;
Jin Qian6df3bc62017-10-18 17:52:14 -0700144 map<uint64_t, struct uid_records> records =
Jin Qianb049d182017-10-12 17:02:17 -0700145 storaged_sp->get_uid_records(hours, threshold, force_report);
Jin Qian5b962c62017-01-30 14:48:38 -0800146 for (const auto& it : records) {
Jin Qian81577752017-02-21 12:09:39 -0800147 if (last_ts != it.second.start_ts) {
Yang Jin3906c892017-06-22 15:18:21 -0700148 dprintf(fd, "%" PRIu64, it.second.start_ts);
Jin Qian81577752017-02-21 12:09:39 -0800149 }
Yang Jin3906c892017-06-22 15:18:21 -0700150 dprintf(fd, ",%" PRIu64 "\n", it.first);
Jin Qian81577752017-02-21 12:09:39 -0800151 last_ts = it.first;
152
Jin Qian6df3bc62017-10-18 17:52:14 -0700153 if (!debug) {
154 dumpUidRecords(fd, it.second.entries);
155 } else {
156 dumpUidRecordsDebug(fd, it.second.entries);
Jin Qian5b962c62017-01-30 14:48:38 -0800157 }
Jin Qiana2e5bd12017-01-24 16:23:13 -0800158 }
Jin Qiane5ea17c2017-02-10 10:50:03 -0800159
160 if (time_window) {
Jin Qianb049d182017-10-12 17:02:17 -0700161 storaged_sp->update_uid_io_interval(time_window);
Jin Qiane5ea17c2017-02-10 10:50:03 -0800162 }
163
Jin Qiana2e5bd12017-01-24 16:23:13 -0800164 return NO_ERROR;
165}
166
Jin Qianb049d182017-10-12 17:02:17 -0700167binder::Status StoragedService::onUserStarted(int32_t userId) {
Jin Qian6df3bc62017-10-18 17:52:14 -0700168 storaged_sp->add_user_ce(userId);
Jin Qianb049d182017-10-12 17:02:17 -0700169 return binder::Status::ok();
170}
171
172binder::Status StoragedService::onUserStopped(int32_t userId) {
Jin Qian6df3bc62017-10-18 17:52:14 -0700173 storaged_sp->remove_user_ce(userId);
Jin Qianb049d182017-10-12 17:02:17 -0700174 return binder::Status::ok();
175}
176
Michael Wachenschwanz37b912b2017-12-14 18:20:26 -0800177binder::Status StoragedService::getRecentPerf(int32_t* _aidl_return) {
178 uint32_t recent_perf = storaged_sp->get_recent_perf();
179 if (recent_perf > INT32_MAX) {
180 *_aidl_return = INT32_MAX;
181 } else {
182 *_aidl_return = static_cast<int32_t>(recent_perf);
183 }
184 return binder::Status::ok();
185}
186
Jin Qianb049d182017-10-12 17:02:17 -0700187status_t StoragedPrivateService::start() {
188 return BinderService<StoragedPrivateService>::publish();
189}
190
191binder::Status StoragedPrivateService::dumpUids(
192 vector<::android::os::storaged::UidInfo>* _aidl_return) {
193 unordered_map<uint32_t, uid_info> uids_m = storaged_sp->get_uids();
194
195 for (const auto& it : uids_m) {
196 UidInfo uinfo;
197 uinfo.uid = it.second.uid;
198 uinfo.name = it.second.name;
199 uinfo.tasks = it.second.tasks;
200 memcpy(&uinfo.io, &it.second.io, sizeof(uinfo.io));
201 _aidl_return->push_back(uinfo);
202 }
203 return binder::Status::ok();
204}
205
206binder::Status StoragedPrivateService::dumpPerfHistory(
207 vector<int32_t>* _aidl_return) {
208 *_aidl_return = storaged_sp->get_perf_history();
209 return binder::Status::ok();
210}
211
212sp<IStoragedPrivate> get_storaged_pri_service() {
ynwang62cb3722016-06-17 14:30:48 -0700213 sp<IServiceManager> sm = defaultServiceManager();
214 if (sm == NULL) return NULL;
215
Jin Qianb049d182017-10-12 17:02:17 -0700216 sp<IBinder> binder = sm->getService(String16("storaged_pri"));
ynwang62cb3722016-06-17 14:30:48 -0700217 if (binder == NULL) return NULL;
218
Jin Qianb049d182017-10-12 17:02:17 -0700219 return interface_cast<IStoragedPrivate>(binder);
Jin Qianbcd6e3b2016-12-28 15:43:51 -0800220}