blob: a3352982a1d3661802cf2596e94a6810f31fa671 [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
Jin Qianbcd6e3b2016-12-28 15:43:51 -080017#include <stdint.h>
18
ynwang62cb3722016-06-17 14:30:48 -070019#include <vector>
20
21#include <binder/IBinder.h>
22#include <binder/IInterface.h>
23
24#include <binder/IPCThreadState.h>
25#include <binder/IServiceManager.h>
Jin Qiana2e5bd12017-01-24 16:23:13 -080026#include <binder/PermissionCache.h>
27#include <private/android_filesystem_config.h>
ynwang62cb3722016-06-17 14:30:48 -070028
29#include <storaged.h>
30#include <storaged_service.h>
31
32extern storaged_t storaged;
33
Jin Qianbcd6e3b2016-12-28 15:43:51 -080034std::vector<struct uid_info> BpStoraged::dump_uids(const char* /*option*/) {
35 Parcel data, reply;
36 data.writeInterfaceToken(IStoraged::getInterfaceDescriptor());
37
38 remote()->transact(DUMPUIDS, data, &reply);
39
40 uint32_t res_size = reply.readInt32();
41 std::vector<struct uid_info> res(res_size);
42 for (auto&& uid : res) {
43 uid.uid = reply.readInt32();
44 uid.name = reply.readCString();
45 reply.read(&uid.io, sizeof(uid.io));
46 }
47 return res;
48}
ynwang62cb3722016-06-17 14:30:48 -070049IMPLEMENT_META_INTERFACE(Storaged, "Storaged");
50
51status_t BnStoraged::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
ynwang62cb3722016-06-17 14:30:48 -070052 switch(code) {
Jin Qianbcd6e3b2016-12-28 15:43:51 -080053 case DUMPUIDS: {
Jin Qiana2e5bd12017-01-24 16:23:13 -080054 if (!data.checkInterface(this))
55 return BAD_TYPE;
Jin Qianbcd6e3b2016-12-28 15:43:51 -080056 std::vector<struct uid_info> res = dump_uids(NULL);
57 reply->writeInt32(res.size());
58 for (auto uid : res) {
59 reply->writeInt32(uid.uid);
60 reply->writeCString(uid.name.c_str());
61 reply->write(&uid.io, sizeof(uid.io));
62 }
63 return NO_ERROR;
64 }
65 break;
ynwang62cb3722016-06-17 14:30:48 -070066 default:
67 return BBinder::onTransact(code, data, reply, flags);
68 }
69}
Jin Qianbcd6e3b2016-12-28 15:43:51 -080070
Jin Qianbcd6e3b2016-12-28 15:43:51 -080071std::vector<struct uid_info> Storaged::dump_uids(const char* /* option */) {
72 std::vector<struct uid_info> uids_v;
73 std::unordered_map<uint32_t, struct uid_info> uids_m = storaged.get_uids();
74
75 for (const auto& it : uids_m) {
76 uids_v.push_back(it.second);
77 }
78 return uids_v;
79}
80
Jin Qian9cdfdd32017-01-31 17:33:20 -080081status_t Storaged::dump(int fd, const Vector<String16>& args) {
Jin Qiana2e5bd12017-01-24 16:23:13 -080082 IPCThreadState* self = IPCThreadState::self();
83 const int pid = self->getCallingPid();
84 const int uid = self->getCallingUid();
85 if ((uid != AID_SHELL) &&
86 !PermissionCache::checkPermission(
87 String16("android.permission.DUMP"), pid, uid)) {
88 return PERMISSION_DENIED;
89 }
90
Jin Qiandd41d6b2017-02-10 17:23:16 -080091 double hours = 0;
Jin Qiane5ea17c2017-02-10 10:50:03 -080092 int time_window = 0;
93 uint64_t threshold = 0;
Jin Qian1275b1b2017-02-06 14:02:50 -080094 bool force_report = false;
Jin Qian9cdfdd32017-01-31 17:33:20 -080095 for (size_t i = 0; i < args.size(); i++) {
96 const auto& arg = args[i];
97 if (arg == String16("--hours")) {
98 if (++i >= args.size())
99 break;
Jin Qiandd41d6b2017-02-10 17:23:16 -0800100 hours = stod(String16::std_string(args[i]));
Jin Qian9cdfdd32017-01-31 17:33:20 -0800101 continue;
102 }
Jin Qiane5ea17c2017-02-10 10:50:03 -0800103 if (arg == String16("--time_window")) {
104 if (++i >= args.size())
105 break;
106 time_window = stoi(String16::std_string(args[i]));
107 continue;
108 }
109 if (arg == String16("--threshold")) {
110 if (++i >= args.size())
111 break;
112 threshold = stoll(String16::std_string(args[i]));
113 continue;
114 }
Jin Qian1275b1b2017-02-06 14:02:50 -0800115 if (arg == String16("--force")) {
116 force_report = true;
117 continue;
118 }
Jin Qian9cdfdd32017-01-31 17:33:20 -0800119 }
120
Jin Qian81577752017-02-21 12:09:39 -0800121 uint64_t last_ts = 0;
122 const std::map<uint64_t, struct uid_records>& records =
Jin Qian1275b1b2017-02-06 14:02:50 -0800123 storaged.get_uid_records(hours, threshold, force_report);
Jin Qian5b962c62017-01-30 14:48:38 -0800124 for (const auto& it : records) {
Jin Qian81577752017-02-21 12:09:39 -0800125 if (last_ts != it.second.start_ts) {
126 dprintf(fd, "%llu", (unsigned long long)it.second.start_ts);
127 }
128 dprintf(fd, ",%llu\n", (unsigned long long)it.first);
129 last_ts = it.first;
130
131 for (const auto& record : it.second.entries) {
Jin Qian5b962c62017-01-30 14:48:38 -0800132 dprintf(fd, "%s %llu %llu %llu %llu %llu %llu %llu %llu\n",
133 record.name.c_str(),
134 (unsigned long long)record.ios.bytes[READ][FOREGROUND][CHARGER_OFF],
135 (unsigned long long)record.ios.bytes[WRITE][FOREGROUND][CHARGER_OFF],
136 (unsigned long long)record.ios.bytes[READ][BACKGROUND][CHARGER_OFF],
137 (unsigned long long)record.ios.bytes[WRITE][BACKGROUND][CHARGER_OFF],
138 (unsigned long long)record.ios.bytes[READ][FOREGROUND][CHARGER_ON],
139 (unsigned long long)record.ios.bytes[WRITE][FOREGROUND][CHARGER_ON],
140 (unsigned long long)record.ios.bytes[READ][BACKGROUND][CHARGER_ON],
141 (unsigned long long)record.ios.bytes[WRITE][BACKGROUND][CHARGER_ON]);
142 }
Jin Qiana2e5bd12017-01-24 16:23:13 -0800143 }
Jin Qiane5ea17c2017-02-10 10:50:03 -0800144
145 if (time_window) {
146 storaged.update_uid_io_interval(time_window);
147 }
148
Jin Qiana2e5bd12017-01-24 16:23:13 -0800149 return NO_ERROR;
150}
151
ynwang62cb3722016-06-17 14:30:48 -0700152sp<IStoraged> get_storaged_service() {
153 sp<IServiceManager> sm = defaultServiceManager();
154 if (sm == NULL) return NULL;
155
156 sp<IBinder> binder = sm->getService(String16("storaged"));
157 if (binder == NULL) return NULL;
158
159 sp<IStoraged> storaged = interface_cast<IStoraged>(binder);
160
161 return storaged;
Jin Qianbcd6e3b2016-12-28 15:43:51 -0800162}