blob: 66354314e2c52ae521e538b1083dbef9c9479bc0 [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 Qian9cdfdd32017-01-31 17:33:20 -080091 int hours = 0;
92 for (size_t i = 0; i < args.size(); i++) {
93 const auto& arg = args[i];
94 if (arg == String16("--hours")) {
95 if (++i >= args.size())
96 break;
97 hours = stoi(String16::std_string(args[i]));
98 continue;
99 }
100 }
101
Jin Qian5b962c62017-01-30 14:48:38 -0800102 const std::map<uint64_t, std::vector<struct uid_record>>& records =
103 storaged.get_uid_records(hours);
104 for (const auto& it : records) {
105 dprintf(fd, "%llu\n", (unsigned long long)it.first);
106 for (const auto& record : it.second) {
107 dprintf(fd, "%s %llu %llu %llu %llu %llu %llu %llu %llu\n",
108 record.name.c_str(),
109 (unsigned long long)record.ios.bytes[READ][FOREGROUND][CHARGER_OFF],
110 (unsigned long long)record.ios.bytes[WRITE][FOREGROUND][CHARGER_OFF],
111 (unsigned long long)record.ios.bytes[READ][BACKGROUND][CHARGER_OFF],
112 (unsigned long long)record.ios.bytes[WRITE][BACKGROUND][CHARGER_OFF],
113 (unsigned long long)record.ios.bytes[READ][FOREGROUND][CHARGER_ON],
114 (unsigned long long)record.ios.bytes[WRITE][FOREGROUND][CHARGER_ON],
115 (unsigned long long)record.ios.bytes[READ][BACKGROUND][CHARGER_ON],
116 (unsigned long long)record.ios.bytes[WRITE][BACKGROUND][CHARGER_ON]);
117 }
Jin Qiana2e5bd12017-01-24 16:23:13 -0800118 }
119 return NO_ERROR;
120}
121
ynwang62cb3722016-06-17 14:30:48 -0700122sp<IStoraged> get_storaged_service() {
123 sp<IServiceManager> sm = defaultServiceManager();
124 if (sm == NULL) return NULL;
125
126 sp<IBinder> binder = sm->getService(String16("storaged"));
127 if (binder == NULL) return NULL;
128
129 sp<IStoraged> storaged = interface_cast<IStoraged>(binder);
130
131 return storaged;
Jin Qianbcd6e3b2016-12-28 15:43:51 -0800132}