1 // Copyright 2019 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #include "host-common/address_space_device.h"
15 #include "host-common/AddressSpaceService.h"
16 #include "host-common/address_space_graphics.h"
17 #ifndef AEMU_MIN
18 #include "host-common/address_space_host_media.h"
19 #endif
20 #include "host-common/address_space_host_memory_allocator.h"
21 #include "host-common/address_space_shared_slots_host_memory_allocator.h"
22 #include "host-common/vm_operations.h"
23
24 #include "base/Lock.h"
25
26 #include <map>
27 #include <unordered_map>
28 #include <memory>
29
30 using android::base::AutoLock;
31 using android::base::Lock;
32 using android::base::Stream;
33 using android::emulation::asg::AddressSpaceGraphicsContext;
34
35 using namespace android::emulation;
36
37 #define AS_DEVICE_DEBUG 0
38
39 #if AS_DEVICE_DEBUG
40 #define AS_DEVICE_DPRINT(fmt,...) fprintf(stderr, "%s:%d " fmt "\n", __func__, __LINE__, ##__VA_ARGS__);
41 #else
42 #define AS_DEVICE_DPRINT(fmt,...)
43 #endif
44
45 const QAndroidVmOperations* sVmOps = nullptr;
46
47 namespace {
48
49 class AddressSpaceDeviceState {
50 public:
51 AddressSpaceDeviceState() = default;
52 ~AddressSpaceDeviceState() = default;
53
genHandle()54 uint32_t genHandle() {
55 AutoLock lock(mContextsLock);
56
57 auto res = mHandleIndex;
58
59 if (!res) {
60 ++res;
61 mHandleIndex += 2;
62 } else {
63 ++mHandleIndex;
64 }
65
66 AS_DEVICE_DPRINT("new handle: %u", res);
67 return res;
68 }
69
destroyHandle(uint32_t handle)70 void destroyHandle(uint32_t handle) {
71 AS_DEVICE_DPRINT("erase handle: %u", handle);
72 AutoLock lock(mContextsLock);
73 mContexts.erase(handle);
74 }
75
tellPingInfo(uint32_t handle,uint64_t gpa)76 void tellPingInfo(uint32_t handle, uint64_t gpa) {
77 AutoLock lock(mContextsLock);
78 auto& contextDesc = mContexts[handle];
79 contextDesc.pingInfo =
80 (AddressSpaceDevicePingInfo*)
81 sVmOps->physicalMemoryGetAddr(gpa);
82 contextDesc.pingInfoGpa = gpa;
83 AS_DEVICE_DPRINT("Ping info: gpa 0x%llx @ %p\n", (unsigned long long)gpa,
84 contextDesc.pingInfo);
85 }
86
ping(uint32_t handle)87 void ping(uint32_t handle) {
88 AutoLock lock(mContextsLock);
89 auto& contextDesc = mContexts[handle];
90 AddressSpaceDevicePingInfo* pingInfo = contextDesc.pingInfo;
91
92 const uint64_t phys_addr = pingInfo->phys_addr;
93
94 AS_DEVICE_DPRINT(
95 "handle %u data 0x%llx -> %p size %llu meta 0x%llx\n", handle,
96 (unsigned long long)phys_addr,
97 sVmOps->physicalMemoryGetAddr(phys_addr),
98 (unsigned long long)pingInfo->size, (unsigned long long)pingInfo->metadata);
99
100 AddressSpaceDeviceContext *device_context = contextDesc.device_context.get();
101 if (device_context) {
102 device_context->perform(pingInfo);
103 } else {
104 // The first ioctl establishes the device type
105 const AddressSpaceDeviceType device_type =
106 static_cast<AddressSpaceDeviceType>(pingInfo->metadata);
107
108 contextDesc.device_context = buildAddressSpaceDeviceContext(device_type, phys_addr, false);
109 pingInfo->metadata = contextDesc.device_context ? 0 : -1;
110 }
111 }
112
pingAtHva(uint32_t handle,AddressSpaceDevicePingInfo * pingInfo)113 void pingAtHva(uint32_t handle, AddressSpaceDevicePingInfo* pingInfo) {
114 AutoLock lock(mContextsLock);
115 auto& contextDesc = mContexts[handle];
116
117 const uint64_t phys_addr = pingInfo->phys_addr;
118
119 AS_DEVICE_DPRINT(
120 "handle %u data 0x%llx -> %p size %llu meta 0x%llx\n", handle,
121 (unsigned long long)phys_addr,
122 sVmOps->physicalMemoryGetAddr(phys_addr),
123 (unsigned long long)pingInfo->size, (unsigned long long)pingInfo->metadata);
124
125 AddressSpaceDeviceContext *device_context = contextDesc.device_context.get();
126 if (device_context) {
127 device_context->perform(pingInfo);
128 } else {
129 // The first ioctl establishes the device type
130 const AddressSpaceDeviceType device_type =
131 static_cast<AddressSpaceDeviceType>(pingInfo->metadata);
132
133 contextDesc.device_context = buildAddressSpaceDeviceContext(device_type, phys_addr, false);
134 pingInfo->metadata = contextDesc.device_context ? 0 : -1;
135 }
136 }
137
registerDeallocationCallback(uint64_t gpa,void * context,address_space_device_deallocation_callback_t func)138 void registerDeallocationCallback(uint64_t gpa, void* context, address_space_device_deallocation_callback_t func) {
139 AutoLock lock(mContextsLock);
140 auto& currentCallbacks = mDeallocationCallbacks[gpa];
141
142 DeallocationCallbackEntry entry = {
143 context,
144 func,
145 };
146
147 currentCallbacks.push_back(entry);
148 }
149
runDeallocationCallbacks(uint64_t gpa)150 void runDeallocationCallbacks(uint64_t gpa) {
151 AutoLock lock(mContextsLock);
152
153 auto it = mDeallocationCallbacks.find(gpa);
154 if (it == mDeallocationCallbacks.end()) return;
155
156 auto& callbacks = it->second;
157
158 for (auto& entry: callbacks) {
159 entry.func(entry.context, gpa);
160 }
161
162 mDeallocationCallbacks.erase(gpa);
163 }
164
handleToContext(uint32_t handle)165 AddressSpaceDeviceContext* handleToContext(uint32_t handle) {
166 AutoLock lock(mContextsLock);
167 if (mContexts.find(handle) == mContexts.end()) return nullptr;
168
169 auto& contextDesc = mContexts[handle];
170 return contextDesc.device_context.get();
171 }
172
hostmemRegister(uint64_t hva,uint64_t size,uint32_t register_fixed,uint64_t fixed_id)173 uint64_t hostmemRegister(uint64_t hva, uint64_t size, uint32_t register_fixed, uint64_t fixed_id) {
174 return sVmOps->hostmemRegister(hva, size, register_fixed, fixed_id);
175 }
176
hostmemUnregister(uint64_t id)177 void hostmemUnregister(uint64_t id) {
178 sVmOps->hostmemUnregister(id);
179 }
180
save(Stream * stream) const181 void save(Stream* stream) const {
182 // Pre-save
183 for (const auto &kv : mContexts) {
184 const AddressSpaceContextDescription &desc = kv.second;
185 const AddressSpaceDeviceContext *device_context = desc.device_context.get();
186 if (device_context) {
187 device_context->preSave();
188 }
189 }
190
191 AddressSpaceGraphicsContext::globalStatePreSave();
192
193 // Save
194 AddressSpaceSharedSlotsHostMemoryAllocatorContext::globalStateSave(stream);
195 AddressSpaceGraphicsContext::globalStateSave(stream);
196
197 stream->putBe32(mHandleIndex);
198 stream->putBe32(mContexts.size());
199
200 for (const auto &kv : mContexts) {
201 const uint32_t handle = kv.first;
202 const AddressSpaceContextDescription &desc = kv.second;
203 const AddressSpaceDeviceContext *device_context = desc.device_context.get();
204
205 stream->putBe32(handle);
206 stream->putBe64(desc.pingInfoGpa);
207
208 if (device_context) {
209 stream->putByte(1);
210 stream->putBe32(device_context->getDeviceType());
211 device_context->save(stream);
212 } else {
213 stream->putByte(0);
214 }
215 }
216
217 // Post save
218
219 AddressSpaceGraphicsContext::globalStatePostSave();
220
221 for (const auto &kv : mContexts) {
222 const AddressSpaceContextDescription &desc = kv.second;
223 const AddressSpaceDeviceContext *device_context = desc.device_context.get();
224 if (device_context) {
225 device_context->postSave();
226 }
227 }
228 }
229
load(Stream * stream)230 bool load(Stream* stream) {
231 // First destroy all contexts, because
232 // this can be done while an emulator is running
233 clear();
234
235 if (!AddressSpaceSharedSlotsHostMemoryAllocatorContext::globalStateLoad(
236 stream,
237 get_address_space_device_control_ops(),
238 get_address_space_device_hw_funcs())) {
239 return false;
240 }
241
242 asg::AddressSpaceGraphicsContext::init(get_address_space_device_control_ops());
243
244 if (!AddressSpaceGraphicsContext::globalStateLoad(
245 stream)) {
246 return false;
247 }
248
249 const uint32_t handleIndex = stream->getBe32();
250 const size_t size = stream->getBe32();
251
252 Contexts contexts;
253 for (size_t i = 0; i < size; ++i) {
254 const uint32_t handle = stream->getBe32();
255 const uint64_t pingInfoGpa = stream->getBe64();
256
257 std::unique_ptr<AddressSpaceDeviceContext> context;
258 switch (stream->getByte()) {
259 case 0:
260 break;
261
262 case 1: {
263 const auto device_type =
264 static_cast<AddressSpaceDeviceType>(stream->getBe32());
265 context = buildAddressSpaceDeviceContext(device_type, pingInfoGpa, true);
266 if (!context || !context->load(stream)) {
267 return false;
268 }
269 }
270 break;
271
272 default:
273 return false;
274 }
275
276 auto &desc = contexts[handle];
277 desc.pingInfoGpa = pingInfoGpa;
278 if (desc.pingInfoGpa == ~0ULL) {
279 fprintf(stderr, "%s: warning: restoring hva-only ping\n", __func__);
280 } else {
281 desc.pingInfo = (AddressSpaceDevicePingInfo*)
282 sVmOps->physicalMemoryGetAddr(pingInfoGpa);
283 }
284 desc.device_context = std::move(context);
285 }
286
287 {
288 AutoLock lock(mContextsLock);
289 mHandleIndex = handleIndex;
290 mContexts = std::move(contexts);
291 }
292
293 return true;
294 }
295
clear()296 void clear() {
297 AutoLock lock(mContextsLock);
298 mContexts.clear();
299 AddressSpaceSharedSlotsHostMemoryAllocatorContext::globalStateClear();
300 auto it = mMemoryMappings.begin();
301 std::vector<std::pair<uint64_t, uint64_t>> gpasSizesToErase;
302 for (auto it: mMemoryMappings) {
303 auto gpa = it.first;
304 auto size = it.second.second;
305 gpasSizesToErase.push_back({gpa, size});
306 }
307 for (const auto& gpaSize : gpasSizesToErase) {
308 removeMemoryMappingLocked(gpaSize.first, gpaSize.second);
309 }
310 mMemoryMappings.clear();
311 }
312
addMemoryMapping(uint64_t gpa,void * ptr,uint64_t size)313 bool addMemoryMapping(uint64_t gpa, void *ptr, uint64_t size) {
314 AutoLock lock(mMemoryMappingsLock);
315 return addMemoryMappingLocked(gpa, ptr, size);
316 }
317
removeMemoryMapping(uint64_t gpa,uint64_t size)318 bool removeMemoryMapping(uint64_t gpa, uint64_t size) {
319 AutoLock lock(mMemoryMappingsLock);
320 return removeMemoryMappingLocked(gpa, size);
321 }
322
getHostPtr(uint64_t gpa) const323 void *getHostPtr(uint64_t gpa) const {
324 AutoLock lock(mMemoryMappingsLock);
325 return getHostPtrLocked(gpa);
326 }
327
328 private:
329 mutable Lock mContextsLock;
330 uint32_t mHandleIndex = 1;
331 typedef std::unordered_map<uint32_t, AddressSpaceContextDescription> Contexts;
332 Contexts mContexts;
333
334 std::unique_ptr<AddressSpaceDeviceContext>
buildAddressSpaceDeviceContext(const AddressSpaceDeviceType device_type,const uint64_t phys_addr,bool fromSnapshot)335 buildAddressSpaceDeviceContext(const AddressSpaceDeviceType device_type,
336 const uint64_t phys_addr,
337 bool fromSnapshot) {
338 typedef std::unique_ptr<AddressSpaceDeviceContext> DeviceContextPtr;
339
340 switch (device_type) {
341 case AddressSpaceDeviceType::Graphics:
342 asg::AddressSpaceGraphicsContext::init(get_address_space_device_control_ops());
343 return DeviceContextPtr(new asg::AddressSpaceGraphicsContext(false /* not virtio */, fromSnapshot));
344 #ifndef AEMU_MIN
345 case AddressSpaceDeviceType::Media:
346 AS_DEVICE_DPRINT("allocating media context");
347 return DeviceContextPtr(new AddressSpaceHostMediaContext(phys_addr, get_address_space_device_control_ops(), fromSnapshot));
348 #endif
349 case AddressSpaceDeviceType::Sensors:
350 return nullptr;
351 case AddressSpaceDeviceType::Power:
352 return nullptr;
353 case AddressSpaceDeviceType::GenericPipe:
354 return nullptr;
355 case AddressSpaceDeviceType::HostMemoryAllocator:
356 return DeviceContextPtr(new AddressSpaceHostMemoryAllocatorContext(
357 get_address_space_device_control_ops()));
358 case AddressSpaceDeviceType::SharedSlotsHostMemoryAllocator:
359 return DeviceContextPtr(new AddressSpaceSharedSlotsHostMemoryAllocatorContext(
360 get_address_space_device_control_ops(),
361 get_address_space_device_hw_funcs()));
362
363 case AddressSpaceDeviceType::VirtioGpuGraphics:
364 asg::AddressSpaceGraphicsContext::init(get_address_space_device_control_ops());
365 return DeviceContextPtr(new asg::AddressSpaceGraphicsContext(true /* is virtio */, fromSnapshot));
366
367 default:
368 AS_DEVICE_DPRINT("Bad device type");
369 return nullptr;
370 }
371 }
372
addMemoryMappingLocked(uint64_t gpa,void * ptr,uint64_t size)373 bool addMemoryMappingLocked(uint64_t gpa, void *ptr, uint64_t size) {
374 if (mMemoryMappings.insert({gpa, {ptr, size}}).second) {
375 sVmOps->mapUserBackedRam(gpa, ptr, size);
376 return true;
377 } else {
378 fprintf(stderr, "%s: failed: hva %p -> gpa [0x%llx 0x%llx]\n", __func__,
379 ptr,
380 (unsigned long long)gpa,
381 (unsigned long long)size);
382 return false;
383 }
384 }
385
removeMemoryMappingLocked(uint64_t gpa,uint64_t size)386 bool removeMemoryMappingLocked(uint64_t gpa, uint64_t size) {
387 if (mMemoryMappings.erase(gpa) > 0) {
388 sVmOps->unmapUserBackedRam(gpa, size);
389 return true;
390 } else {
391 fprintf(stderr, "%s: failed: gpa [0x%llx 0x%llx]\n", __func__,
392 (unsigned long long)gpa,
393 (unsigned long long)size);
394 *(uint32_t*)(123) = 12;
395 return false;
396 }
397 }
398
getHostPtrLocked(uint64_t gpa) const399 void *getHostPtrLocked(uint64_t gpa) const {
400 auto i = mMemoryMappings.lower_bound(gpa); // i->first >= gpa (or i==end)
401 if ((i != mMemoryMappings.end()) && (i->first == gpa)) {
402 return i->second.first; // gpa is exactly the beginning of the range
403 } else if (i == mMemoryMappings.begin()) {
404 return nullptr; // can't '--i', see below
405 } else {
406 --i;
407
408 if ((i->first + i->second.second) > gpa) {
409 // move the host ptr by +(gpa-base)
410 return static_cast<char *>(i->second.first) + (gpa - i->first);
411 } else {
412 return nullptr; // the range does not cover gpa
413 }
414 }
415 }
416
417 mutable Lock mMemoryMappingsLock;
418 std::map<uint64_t, std::pair<void *, uint64_t>> mMemoryMappings; // do not save/load
419
420 struct DeallocationCallbackEntry {
421 void* context;
422 address_space_device_deallocation_callback_t func;
423 };
424
425 std::map<uint64_t, std::vector<DeallocationCallbackEntry>> mDeallocationCallbacks; // do not save/load, users re-register on load
426 };
427
sAddressSpaceDeviceState()428 static AddressSpaceDeviceState* sAddressSpaceDeviceState() {
429 static AddressSpaceDeviceState* s = new AddressSpaceDeviceState;
430 return s;
431 }
432
sAddressSpaceDeviceGenHandle()433 static uint32_t sAddressSpaceDeviceGenHandle() {
434 return sAddressSpaceDeviceState()->genHandle();
435 }
436
sAddressSpaceDeviceDestroyHandle(uint32_t handle)437 static void sAddressSpaceDeviceDestroyHandle(uint32_t handle) {
438 sAddressSpaceDeviceState()->destroyHandle(handle);
439 }
440
sAddressSpaceDeviceTellPingInfo(uint32_t handle,uint64_t gpa)441 static void sAddressSpaceDeviceTellPingInfo(uint32_t handle, uint64_t gpa) {
442 sAddressSpaceDeviceState()->tellPingInfo(handle, gpa);
443 }
444
sAddressSpaceDevicePing(uint32_t handle)445 static void sAddressSpaceDevicePing(uint32_t handle) {
446 sAddressSpaceDeviceState()->ping(handle);
447 }
448
sAddressSpaceDeviceAddMemoryMapping(uint64_t gpa,void * ptr,uint64_t size)449 int sAddressSpaceDeviceAddMemoryMapping(uint64_t gpa, void *ptr, uint64_t size) {
450 return sAddressSpaceDeviceState()->addMemoryMapping(gpa, ptr, size) ? 1 : 0;
451 }
452
sAddressSpaceDeviceRemoveMemoryMapping(uint64_t gpa,void * ptr,uint64_t size)453 int sAddressSpaceDeviceRemoveMemoryMapping(uint64_t gpa, void *ptr, uint64_t size) {
454 (void)ptr; // TODO(lfy): remove arg
455 return sAddressSpaceDeviceState()->removeMemoryMapping(gpa, size) ? 1 : 0;
456 }
457
sAddressSpaceDeviceGetHostPtr(uint64_t gpa)458 void* sAddressSpaceDeviceGetHostPtr(uint64_t gpa) {
459 return sAddressSpaceDeviceState()->getHostPtr(gpa);
460 }
461
sAddressSpaceHandleToContext(uint32_t handle)462 static void* sAddressSpaceHandleToContext(uint32_t handle) {
463 return (void*)(sAddressSpaceDeviceState()->handleToContext(handle));
464 }
465
sAddressSpaceDeviceClear()466 static void sAddressSpaceDeviceClear() {
467 sAddressSpaceDeviceState()->clear();
468 }
469
sAddressSpaceDeviceHostmemRegister(uint64_t hva,uint64_t size,uint32_t register_fixed,uint64_t fixed_id)470 static uint64_t sAddressSpaceDeviceHostmemRegister(uint64_t hva, uint64_t size, uint32_t register_fixed, uint64_t fixed_id) {
471 return sAddressSpaceDeviceState()->hostmemRegister(hva, size, register_fixed, fixed_id);
472 }
473
sAddressSpaceDeviceHostmemUnregister(uint64_t id)474 static void sAddressSpaceDeviceHostmemUnregister(uint64_t id) {
475 sAddressSpaceDeviceState()->hostmemUnregister(id);
476 }
477
sAddressSpaceDevicePingAtHva(uint32_t handle,void * hva)478 static void sAddressSpaceDevicePingAtHva(uint32_t handle, void* hva) {
479 sAddressSpaceDeviceState()->pingAtHva(
480 handle, (AddressSpaceDevicePingInfo*)hva);
481 }
482
sAddressSpaceDeviceRegisterDeallocationCallback(void * context,uint64_t gpa,address_space_device_deallocation_callback_t func)483 static void sAddressSpaceDeviceRegisterDeallocationCallback(
484 void* context, uint64_t gpa, address_space_device_deallocation_callback_t func) {
485 sAddressSpaceDeviceState()->registerDeallocationCallback(gpa, context, func);
486 }
487
sAddressSpaceDeviceRunDeallocationCallbacks(uint64_t gpa)488 static void sAddressSpaceDeviceRunDeallocationCallbacks(uint64_t gpa) {
489 sAddressSpaceDeviceState()->runDeallocationCallbacks(gpa);
490 }
491
sAddressSpaceDeviceControlGetHwFuncs()492 static const struct AddressSpaceHwFuncs* sAddressSpaceDeviceControlGetHwFuncs() {
493 return get_address_space_device_hw_funcs();
494 }
495
496
497 } // namespace
498
499 extern "C" {
500
501 static struct address_space_device_control_ops sAddressSpaceDeviceOps = {
502 &sAddressSpaceDeviceGenHandle, // gen_handle
503 &sAddressSpaceDeviceDestroyHandle, // destroy_handle
504 &sAddressSpaceDeviceTellPingInfo, // tell_ping_info
505 &sAddressSpaceDevicePing, // ping
506 &sAddressSpaceDeviceAddMemoryMapping, // add_memory_mapping
507 &sAddressSpaceDeviceRemoveMemoryMapping, // remove_memory_mapping
508 &sAddressSpaceDeviceGetHostPtr, // get_host_ptr
509 &sAddressSpaceHandleToContext, // handle_to_context
510 &sAddressSpaceDeviceClear, // clear
511 &sAddressSpaceDeviceHostmemRegister, // hostmem register
512 &sAddressSpaceDeviceHostmemUnregister, // hostmem unregister
513 &sAddressSpaceDevicePingAtHva, // ping_at_hva
514 &sAddressSpaceDeviceRegisterDeallocationCallback, // register_deallocation_callback
515 &sAddressSpaceDeviceRunDeallocationCallbacks, // run_deallocation_callbacks
516 &sAddressSpaceDeviceControlGetHwFuncs, // control_get_hw_funcs
517 };
518
get_address_space_device_control_ops(void)519 struct address_space_device_control_ops* get_address_space_device_control_ops(void) {
520 return &sAddressSpaceDeviceOps;
521 }
522
523 static const struct AddressSpaceHwFuncs* sAddressSpaceHwFuncs = nullptr;
524
address_space_set_hw_funcs(const AddressSpaceHwFuncs * hwFuncs)525 const struct AddressSpaceHwFuncs* address_space_set_hw_funcs(
526 const AddressSpaceHwFuncs* hwFuncs) {
527 const AddressSpaceHwFuncs* result = sAddressSpaceHwFuncs;
528 sAddressSpaceHwFuncs = hwFuncs;
529 return result;
530 }
531
get_address_space_device_hw_funcs(void)532 const struct AddressSpaceHwFuncs* get_address_space_device_hw_funcs(void) {
533 return sAddressSpaceHwFuncs;
534 }
535
address_space_set_vm_operations(const QAndroidVmOperations * vmops)536 void address_space_set_vm_operations(const QAndroidVmOperations* vmops) {
537 sVmOps = vmops;
538 }
539
540 } // extern "C"
541
542 namespace android {
543 namespace emulation {
544
goldfish_address_space_set_vm_operations(const QAndroidVmOperations * vmops)545 void goldfish_address_space_set_vm_operations(const QAndroidVmOperations* vmops) {
546 sVmOps = vmops;
547 }
548
goldfish_address_space_get_vm_operations()549 const QAndroidVmOperations* goldfish_address_space_get_vm_operations() {
550 return sVmOps;
551 }
552
goldfish_address_space_memory_state_load(android::base::Stream * stream)553 int goldfish_address_space_memory_state_load(android::base::Stream *stream) {
554 return sAddressSpaceDeviceState()->load(stream) ? 0 : 1;
555 }
556
goldfish_address_space_memory_state_save(android::base::Stream * stream)557 int goldfish_address_space_memory_state_save(android::base::Stream *stream) {
558 sAddressSpaceDeviceState()->save(stream);
559 return 0;
560 }
561
562 } // namespace emulation
563 } // namespace android
564