blob: 467616724a2b705cf6b205a3d7f13c17936a79ca [file] [log] [blame]
Kalesh Singh3265ebe2021-03-27 03:31:54 -04001/*
2 * Copyright (C) 2021 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#include "MemtrackProxy.h"
18
19#include <android-base/logging.h>
20#include <android/binder_manager.h>
21#include <private/android_filesystem_config.h>
22
23using ::android::hardware::hidl_vec;
24using ::android::hardware::Return;
25
26namespace aidl {
27namespace android {
28namespace hardware {
29namespace memtrack {
30
31// Check Memtrack Flags
32static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::SMAPS_ACCOUNTED) ==
33 static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_SMAPS_ACCOUNTED));
34static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::SMAPS_UNACCOUNTED) ==
35 static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_SMAPS_UNACCOUNTED));
36static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::SHARED) ==
37 static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_SHARED));
38static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::SHARED_PSS) ==
39 static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_SHARED_PSS));
40static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::PRIVATE) ==
41 static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_PRIVATE));
42static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::SYSTEM) ==
43 static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_SYSTEM));
44static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::DEDICATED) ==
45 static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_DEDICATED));
46static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::NONSECURE) ==
47 static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_NONSECURE));
48static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackFlag::SECURE) ==
49 static_cast<uint32_t>(V1_aidl::MemtrackRecord::FLAG_SECURE));
50
51// Check Memtrack Types
52static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackType::OTHER) ==
53 static_cast<uint32_t>(V1_aidl::MemtrackType::OTHER));
54static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackType::GL) ==
55 static_cast<uint32_t>(V1_aidl::MemtrackType::GL));
56static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackType::GRAPHICS) ==
57 static_cast<uint32_t>(V1_aidl::MemtrackType::GRAPHICS));
58static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackType::MULTIMEDIA) ==
59 static_cast<uint32_t>(V1_aidl::MemtrackType::MULTIMEDIA));
60static_assert(static_cast<uint32_t>(V1_0_hidl::MemtrackType::CAMERA) ==
61 static_cast<uint32_t>(V1_aidl::MemtrackType::CAMERA));
62
63__attribute__((warn_unused_result)) bool translate(const V1_0_hidl::MemtrackRecord& in,
64 V1_aidl::MemtrackRecord* out) {
65 // Convert uint64_t to int64_t (long in AIDL). AIDL doesn't support unsigned types.
66 if (in.sizeInBytes > std::numeric_limits<int64_t>::max() || in.sizeInBytes < 0) {
67 return false;
68 }
69 out->sizeInBytes = static_cast<int64_t>(in.sizeInBytes);
70
71 // It's ok to just assign directly, since this is a bitmap.
72 out->flags = in.flags;
73 return true;
74}
75
76sp<V1_0_hidl::IMemtrack> MemtrackProxy::MemtrackHidlInstance() {
77 return V1_0_hidl::IMemtrack::getService();
78}
79
80std::shared_ptr<V1_aidl::IMemtrack> MemtrackProxy::MemtrackAidlInstance() {
81 const auto instance = std::string() + V1_aidl::IMemtrack::descriptor + "/default";
82 bool declared = AServiceManager_isDeclared(instance.c_str());
83 if (!declared) {
84 return nullptr;
85 }
86 ndk::SpAIBinder memtrack_binder =
87 ndk::SpAIBinder(AServiceManager_waitForService(instance.c_str()));
88 return V1_aidl::IMemtrack::fromBinder(memtrack_binder);
89}
90
91bool MemtrackProxy::CheckUid(uid_t calling_uid) {
92 // Allow AID_SHELL for adb shell dumpsys meminfo
93 return calling_uid == AID_SYSTEM || calling_uid == AID_ROOT || calling_uid == AID_SHELL;
94}
95
96bool MemtrackProxy::CheckPid(pid_t calling_pid, pid_t request_pid) {
97 return calling_pid == request_pid;
98}
99
100MemtrackProxy::MemtrackProxy()
101 : memtrack_hidl_instance_(MemtrackProxy::MemtrackHidlInstance()),
102 memtrack_aidl_instance_(MemtrackProxy::MemtrackAidlInstance()) {}
103
104ndk::ScopedAStatus MemtrackProxy::getMemory(int pid, MemtrackType type,
105 std::vector<MemtrackRecord>* _aidl_return) {
106 if (pid < 0) {
107 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
108 }
109
110 if (!MemtrackProxy::CheckPid(AIBinder_getCallingPid(), pid) &&
111 !MemtrackProxy::CheckUid(AIBinder_getCallingUid())) {
112 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
113 EX_SECURITY,
114 "Only AID_ROOT, AID_SYSTEM and AID_SHELL can request getMemory() for PIDs other "
115 "than the calling PID");
116 }
117
118 if (type != MemtrackType::OTHER && type != MemtrackType::GL && type != MemtrackType::GRAPHICS &&
119 type != MemtrackType::MULTIMEDIA && type != MemtrackType::CAMERA) {
120 return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
121 }
122
123 _aidl_return->clear();
124
Kalesh Singh161495e2021-04-08 19:56:01 -0400125 if (memtrack_aidl_instance_) {
Kalesh Singh3265ebe2021-03-27 03:31:54 -0400126 return memtrack_aidl_instance_->getMemory(pid, type, _aidl_return);
Kalesh Singh161495e2021-04-08 19:56:01 -0400127 } else if (memtrack_hidl_instance_) {
Kalesh Singh3265ebe2021-03-27 03:31:54 -0400128 ndk::ScopedAStatus aidl_status;
129
130 Return<void> ret = memtrack_hidl_instance_->getMemory(
131 pid, static_cast<V1_0_hidl::MemtrackType>(type),
132 [&_aidl_return, &aidl_status](V1_0_hidl::MemtrackStatus status,
133 hidl_vec<V1_0_hidl::MemtrackRecord> records) {
134 switch (status) {
135 case V1_0_hidl::MemtrackStatus::SUCCESS:
136 aidl_status = ndk::ScopedAStatus::ok();
137 break;
138 case V1_0_hidl::MemtrackStatus::MEMORY_TRACKING_NOT_SUPPORTED:
139 [[fallthrough]];
140 case V1_0_hidl::MemtrackStatus::TYPE_NOT_SUPPORTED:
141 [[fallthrough]];
142 default:
143 aidl_status =
144 ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
145 return;
146 }
147
148 _aidl_return->resize(records.size());
149 for (size_t i = 0; i < records.size(); i++) {
150 if (!translate(records[i], &(*_aidl_return)[i])) {
151 aidl_status = ndk::ScopedAStatus::fromExceptionCodeWithMessage(
152 EX_SERVICE_SPECIFIC,
153 "Failed to convert HIDL MemtrackRecord to AIDL");
154 return;
155 }
156 }
157 });
158
159 // Check HIDL return
160 if (!ret.isOk()) {
161 const char* err_msg = "HIDL Memtrack::getMemory() failed";
162 aidl_status =
163 ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_SERVICE_SPECIFIC, err_msg);
164 LOG(ERROR) << err_msg << ": " << ret.description();
165 }
166
167 return aidl_status;
168 }
169
170 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_NULL_POINTER,
171 "Memtrack HAL service not available");
172}
173
174ndk::ScopedAStatus MemtrackProxy::getGpuDeviceInfo(std::vector<DeviceInfo>* _aidl_return) {
175 if (!MemtrackProxy::CheckUid(AIBinder_getCallingUid())) {
176 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_SECURITY,
177 "Only AID_ROOT, AID_SYSTEM and AID_SHELL can request getGpuDeviceInfo()");
178 }
179
180 _aidl_return->clear();
181
182 if (memtrack_aidl_instance_ ||
183 (memtrack_aidl_instance_ = MemtrackProxy::MemtrackAidlInstance())) {
184 return memtrack_aidl_instance_->getGpuDeviceInfo(_aidl_return);
185 }
186
187 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_NULL_POINTER,
188 "Memtrack HAL service not available");
189}
190
191} // namespace memtrack
192} // namespace hardware
193} // namespace android
194} // namespace aidl