1 /* 2 * Copyright (C) 2010 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 #define LOG_TAG "IMountService" 18 19 #include <storage/IMountService.h> 20 #include <binder/Parcel.h> 21 22 namespace android { 23 24 enum { 25 TRANSACTION_registerListener = IBinder::FIRST_CALL_TRANSACTION, 26 TRANSACTION_unregisterListener, 27 TRANSACTION_isUsbMassStorageConnected, 28 TRANSACTION_setUsbMassStorageEnabled, 29 TRANSACTION_isUsbMassStorageEnabled, 30 TRANSACTION_mountVolume, 31 TRANSACTION_unmountVolume, 32 TRANSACTION_formatVolume, 33 TRANSACTION_getStorageUsers, 34 TRANSACTION_getVolumeState, 35 TRANSACTION_createSecureContainer, 36 TRANSACTION_finalizeSecureContainer, 37 TRANSACTION_destroySecureContainer, 38 TRANSACTION_mountSecureContainer, 39 TRANSACTION_unmountSecureContainer, 40 TRANSACTION_isSecureContainerMounted, 41 TRANSACTION_renameSecureContainer, 42 TRANSACTION_getSecureContainerPath, 43 TRANSACTION_getSecureContainerList, 44 TRANSACTION_shutdown, 45 TRANSACTION_finishMediaUpdate, 46 TRANSACTION_mountObb, 47 TRANSACTION_unmountObb, 48 TRANSACTION_isObbMounted, 49 TRANSACTION_getMountedObbPath, 50 TRANSACTION_isExternalStorageEmulated, 51 TRANSACTION_decryptStorage, 52 TRANSACTION_encryptStorage, 53 }; 54 55 class BpMountService: public BpInterface<IMountService> 56 { 57 public: BpMountService(const sp<IBinder> & impl)58 explicit BpMountService(const sp<IBinder>& impl) 59 : BpInterface<IMountService>(impl) 60 { 61 } 62 registerListener(const sp<IMountServiceListener> & listener)63 virtual void registerListener(const sp<IMountServiceListener>& listener) 64 { 65 Parcel data, reply; 66 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 67 data.writeStrongBinder(IInterface::asBinder(listener)); 68 if (remote()->transact(TRANSACTION_registerListener, data, &reply) != NO_ERROR) { 69 ALOGD("registerListener could not contact remote\n"); 70 return; 71 } 72 int32_t err = reply.readExceptionCode(); 73 if (err < 0) { 74 ALOGD("registerListener caught exception %d\n", err); 75 return; 76 } 77 } 78 unregisterListener(const sp<IMountServiceListener> & listener)79 virtual void unregisterListener(const sp<IMountServiceListener>& listener) 80 { 81 Parcel data, reply; 82 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 83 data.writeStrongBinder(IInterface::asBinder(listener)); 84 if (remote()->transact(TRANSACTION_unregisterListener, data, &reply) != NO_ERROR) { 85 ALOGD("unregisterListener could not contact remote\n"); 86 return; 87 } 88 int32_t err = reply.readExceptionCode(); 89 if (err < 0) { 90 ALOGD("unregisterListener caught exception %d\n", err); 91 return; 92 } 93 } 94 isUsbMassStorageConnected()95 virtual bool isUsbMassStorageConnected() 96 { 97 Parcel data, reply; 98 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 99 if (remote()->transact(TRANSACTION_isUsbMassStorageConnected, data, &reply) != NO_ERROR) { 100 ALOGD("isUsbMassStorageConnected could not contact remote\n"); 101 return false; 102 } 103 int32_t err = reply.readExceptionCode(); 104 if (err < 0) { 105 ALOGD("isUsbMassStorageConnected caught exception %d\n", err); 106 return false; 107 } 108 return reply.readInt32() != 0; 109 } 110 setUsbMassStorageEnabled(const bool enable)111 virtual void setUsbMassStorageEnabled(const bool enable) 112 { 113 Parcel data, reply; 114 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 115 data.writeInt32(enable != 0); 116 if (remote()->transact(TRANSACTION_setUsbMassStorageEnabled, data, &reply) != NO_ERROR) { 117 ALOGD("setUsbMassStorageEnabled could not contact remote\n"); 118 return; 119 } 120 int32_t err = reply.readExceptionCode(); 121 if (err < 0) { 122 ALOGD("setUsbMassStorageEnabled caught exception %d\n", err); 123 return; 124 } 125 } 126 isUsbMassStorageEnabled()127 virtual bool isUsbMassStorageEnabled() 128 { 129 Parcel data, reply; 130 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 131 if (remote()->transact(TRANSACTION_isUsbMassStorageEnabled, data, &reply) != NO_ERROR) { 132 ALOGD("isUsbMassStorageEnabled could not contact remote\n"); 133 return false; 134 } 135 int32_t err = reply.readExceptionCode(); 136 if (err < 0) { 137 ALOGD("isUsbMassStorageEnabled caught exception %d\n", err); 138 return false; 139 } 140 return reply.readInt32() != 0; 141 } 142 mountVolume(const String16 & mountPoint)143 int32_t mountVolume(const String16& mountPoint) 144 { 145 Parcel data, reply; 146 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 147 data.writeString16(mountPoint); 148 if (remote()->transact(TRANSACTION_mountVolume, data, &reply) != NO_ERROR) { 149 ALOGD("mountVolume could not contact remote\n"); 150 return -1; 151 } 152 int32_t err = reply.readExceptionCode(); 153 if (err < 0) { 154 ALOGD("mountVolume caught exception %d\n", err); 155 return err; 156 } 157 return reply.readInt32(); 158 } 159 unmountVolume(const String16 & mountPoint,const bool force,const bool removeEncryption)160 int32_t unmountVolume(const String16& mountPoint, const bool force, const bool removeEncryption) 161 { 162 Parcel data, reply; 163 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 164 data.writeString16(mountPoint); 165 data.writeInt32(force ? 1 : 0); 166 data.writeInt32(removeEncryption ? 1 : 0); 167 if (remote()->transact(TRANSACTION_unmountVolume, data, &reply) != NO_ERROR) { 168 ALOGD("unmountVolume could not contact remote\n"); 169 return -1; 170 } 171 int32_t err = reply.readExceptionCode(); 172 if (err < 0) { 173 ALOGD("unmountVolume caught exception %d\n", err); 174 return err; 175 } 176 return reply.readInt32(); 177 } 178 formatVolume(const String16 & mountPoint)179 int32_t formatVolume(const String16& mountPoint) 180 { 181 Parcel data, reply; 182 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 183 data.writeString16(mountPoint); 184 if (remote()->transact(TRANSACTION_formatVolume, data, &reply) != NO_ERROR) { 185 ALOGD("formatVolume could not contact remote\n"); 186 return -1; 187 } 188 int32_t err = reply.readExceptionCode(); 189 if (err < 0) { 190 ALOGD("formatVolume caught exception %d\n", err); 191 return err; 192 } 193 return reply.readInt32(); 194 } 195 getStorageUsers(const String16 & mountPoint,int32_t ** users)196 int32_t getStorageUsers(const String16& mountPoint, int32_t** users) 197 { 198 Parcel data, reply; 199 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 200 data.writeString16(mountPoint); 201 if (remote()->transact(TRANSACTION_getStorageUsers, data, &reply) != NO_ERROR) { 202 ALOGD("getStorageUsers could not contact remote\n"); 203 return -1; 204 } 205 int32_t err = reply.readExceptionCode(); 206 if (err < 0) { 207 ALOGD("getStorageUsers caught exception %d\n", err); 208 return err; 209 } 210 int32_t numUsersI = reply.readInt32(); 211 uint32_t numUsers; 212 if (numUsersI < 0) { 213 ALOGW("Number of users is negative: %d\n", numUsersI); 214 numUsers = 0; 215 } else { 216 numUsers = static_cast<uint32_t>(numUsersI); 217 } 218 *users = (int32_t*)malloc(sizeof(int32_t)*numUsers); 219 for (size_t i = 0; i < numUsers; i++) { 220 **users++ = reply.readInt32(); 221 } 222 return static_cast<int32_t>(numUsers); 223 } 224 getVolumeState(const String16 & mountPoint)225 int32_t getVolumeState(const String16& mountPoint) 226 { 227 Parcel data, reply; 228 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 229 data.writeString16(mountPoint); 230 if (remote()->transact(TRANSACTION_getVolumeState, data, &reply) != NO_ERROR) { 231 ALOGD("getVolumeState could not contact remote\n"); 232 return -1; 233 } 234 int32_t err = reply.readExceptionCode(); 235 if (err < 0) { 236 ALOGD("getVolumeState caught exception %d\n", err); 237 return err; 238 } 239 return reply.readInt32(); 240 } 241 createSecureContainer(const String16 & id,const int32_t sizeMb,const String16 & fstype,const String16 & key,const int32_t ownerUid)242 int32_t createSecureContainer(const String16& id, const int32_t sizeMb, const String16& fstype, 243 const String16& key, const int32_t ownerUid) 244 { 245 Parcel data, reply; 246 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 247 data.writeString16(id); 248 data.writeInt32(sizeMb); 249 data.writeString16(fstype); 250 data.writeString16(key); 251 data.writeInt32(ownerUid); 252 if (remote()->transact(TRANSACTION_createSecureContainer, data, &reply) != NO_ERROR) { 253 ALOGD("createSecureContainer could not contact remote\n"); 254 return -1; 255 } 256 int32_t err = reply.readExceptionCode(); 257 if (err < 0) { 258 ALOGD("createSecureContainer caught exception %d\n", err); 259 return err; 260 } 261 return reply.readInt32(); 262 } 263 finalizeSecureContainer(const String16 & id)264 int32_t finalizeSecureContainer(const String16& id) 265 { 266 Parcel data, reply; 267 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 268 data.writeString16(id); 269 if (remote()->transact(TRANSACTION_finalizeSecureContainer, data, &reply) != NO_ERROR) { 270 ALOGD("finalizeSecureContainer couldn't call remote\n"); 271 return -1; 272 } 273 int32_t err = reply.readExceptionCode(); 274 if (err < 0) { 275 ALOGD("finalizeSecureContainer caught exception %d\n", err); 276 return err; 277 } 278 return reply.readInt32(); 279 } 280 destroySecureContainer(const String16 & id)281 int32_t destroySecureContainer(const String16& id) 282 { 283 Parcel data, reply; 284 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 285 data.writeString16(id); 286 if (remote()->transact(TRANSACTION_destroySecureContainer, data, &reply) != NO_ERROR) { 287 ALOGD("destroySecureContainer couldn't call remote"); 288 return -1; 289 } 290 int32_t err = reply.readExceptionCode(); 291 if (err < 0) { 292 ALOGD("destroySecureContainer caught exception %d\n", err); 293 return err; 294 } 295 return reply.readInt32(); 296 } 297 mountSecureContainer(const String16 & id,const String16 & key,const int32_t ownerUid)298 int32_t mountSecureContainer(const String16& id, const String16& key, const int32_t ownerUid) 299 { 300 Parcel data, reply; 301 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 302 data.writeString16(id); 303 data.writeString16(key); 304 data.writeInt32(ownerUid); 305 // Assume read-only 306 data.writeInt32(1); 307 if (remote()->transact(TRANSACTION_mountSecureContainer, data, &reply) != NO_ERROR) { 308 ALOGD("mountSecureContainer couldn't call remote"); 309 return -1; 310 } 311 int32_t err = reply.readExceptionCode(); // What to do... 312 if (err < 0) { 313 ALOGD("mountSecureContainer caught exception %d\n", err); 314 return err; 315 } 316 return reply.readInt32(); 317 } 318 unmountSecureContainer(const String16 & id,const bool force)319 int32_t unmountSecureContainer(const String16& id, const bool force) 320 { 321 Parcel data, reply; 322 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 323 data.writeString16(id); 324 data.writeInt32(force ? 1 : 0); 325 if (remote()->transact(TRANSACTION_getSecureContainerPath, data, &reply) != NO_ERROR) { 326 ALOGD("unmountSecureContainer couldn't call remote"); 327 return -1; 328 } 329 int32_t err = reply.readExceptionCode(); // What to do... 330 if (err < 0) { 331 ALOGD("unmountSecureContainer caught exception %d\n", err); 332 return err; 333 } 334 return reply.readInt32(); 335 } 336 isSecureContainerMounted(const String16 & id)337 bool isSecureContainerMounted(const String16& id) 338 { 339 Parcel data, reply; 340 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 341 data.writeString16(id); 342 if (remote()->transact(TRANSACTION_isSecureContainerMounted, data, &reply) != NO_ERROR) { 343 ALOGD("isSecureContainerMounted couldn't call remote"); 344 return false; 345 } 346 int32_t err = reply.readExceptionCode(); // What to do... 347 if (err < 0) { 348 ALOGD("isSecureContainerMounted caught exception %d\n", err); 349 return false; 350 } 351 return reply.readInt32() != 0; 352 } 353 renameSecureContainer(const String16 & oldId,const String16 & newId)354 int32_t renameSecureContainer(const String16& oldId, const String16& newId) 355 { 356 Parcel data, reply; 357 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 358 data.writeString16(oldId); 359 data.writeString16(newId); 360 if (remote()->transact(TRANSACTION_renameSecureContainer, data, &reply) != NO_ERROR) { 361 ALOGD("renameSecureContainer couldn't call remote"); 362 return -1; 363 } 364 int32_t err = reply.readExceptionCode(); // What to do... 365 if (err < 0) { 366 ALOGD("renameSecureContainer caught exception %d\n", err); 367 return err; 368 } 369 return reply.readInt32(); 370 } 371 getSecureContainerPath(const String16 & id,String16 & path)372 bool getSecureContainerPath(const String16& id, String16& path) 373 { 374 Parcel data, reply; 375 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 376 data.writeString16(id); 377 if (remote()->transact(TRANSACTION_getSecureContainerPath, data, &reply) != NO_ERROR) { 378 ALOGD("getSecureContainerPath couldn't call remote"); 379 return false; 380 } 381 int32_t err = reply.readExceptionCode(); // What to do... 382 if (err < 0) { 383 ALOGD("getSecureContainerPath caught exception %d\n", err); 384 return false; 385 } 386 path = reply.readString16(); 387 return true; 388 } 389 getSecureContainerList(const String16 & id,String16 * & containers)390 int32_t getSecureContainerList(const String16& id, String16*& containers) 391 { 392 Parcel data, reply; 393 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 394 data.writeString16(id); 395 if (remote()->transact(TRANSACTION_getSecureContainerList, data, &reply) != NO_ERROR) { 396 ALOGD("getSecureContainerList couldn't call remote"); 397 return -1; 398 } 399 int32_t err = reply.readExceptionCode(); 400 if (err < 0) { 401 ALOGD("getSecureContainerList caught exception %d\n", err); 402 return err; 403 } 404 const int32_t numStrings = reply.readInt32(); 405 containers = new String16[numStrings]; 406 for (int i = 0; i < numStrings; i++) { 407 containers[i] = reply.readString16(); 408 } 409 return numStrings; 410 } 411 shutdown(const sp<IMountShutdownObserver> & observer)412 void shutdown(const sp<IMountShutdownObserver>& observer) 413 { 414 Parcel data, reply; 415 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 416 data.writeStrongBinder(IInterface::asBinder(observer)); 417 if (remote()->transact(TRANSACTION_shutdown, data, &reply) != NO_ERROR) { 418 ALOGD("shutdown could not contact remote\n"); 419 return; 420 } 421 int32_t err = reply.readExceptionCode(); 422 if (err < 0) { 423 ALOGD("shutdown caught exception %d\n", err); 424 return; 425 } 426 reply.readExceptionCode(); 427 } 428 finishMediaUpdate()429 void finishMediaUpdate() 430 { 431 Parcel data, reply; 432 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 433 if (remote()->transact(TRANSACTION_finishMediaUpdate, data, &reply) != NO_ERROR) { 434 ALOGD("finishMediaUpdate could not contact remote\n"); 435 return; 436 } 437 int32_t err = reply.readExceptionCode(); 438 if (err < 0) { 439 ALOGD("finishMediaUpdate caught exception %d\n", err); 440 return; 441 } 442 reply.readExceptionCode(); 443 } 444 mountObb(const String16 & rawPath,const String16 & canonicalPath,const String16 & key,const sp<IObbActionListener> & token,int32_t nonce,const sp<ObbInfo> & obbInfo)445 void mountObb(const String16& rawPath, const String16& canonicalPath, const String16& key, 446 const sp<IObbActionListener>& token, int32_t nonce, const sp<ObbInfo>& obbInfo) 447 { 448 Parcel data, reply; 449 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 450 data.writeString16(rawPath); 451 data.writeString16(canonicalPath); 452 data.writeString16(key); 453 data.writeStrongBinder(IInterface::asBinder(token)); 454 data.writeInt32(nonce); 455 obbInfo->writeToParcel(&data); 456 if (remote()->transact(TRANSACTION_mountObb, data, &reply) != NO_ERROR) { 457 ALOGD("mountObb could not contact remote\n"); 458 return; 459 } 460 int32_t err = reply.readExceptionCode(); 461 if (err < 0) { 462 ALOGD("mountObb caught exception %d\n", err); 463 return; 464 } 465 } 466 unmountObb(const String16 & filename,const bool force,const sp<IObbActionListener> & token,const int32_t nonce)467 void unmountObb(const String16& filename, const bool force, 468 const sp<IObbActionListener>& token, const int32_t nonce) 469 { 470 Parcel data, reply; 471 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 472 data.writeString16(filename); 473 data.writeInt32(force ? 1 : 0); 474 data.writeStrongBinder(IInterface::asBinder(token)); 475 data.writeInt32(nonce); 476 if (remote()->transact(TRANSACTION_unmountObb, data, &reply) != NO_ERROR) { 477 ALOGD("unmountObb could not contact remote\n"); 478 return; 479 } 480 int32_t err = reply.readExceptionCode(); 481 if (err < 0) { 482 ALOGD("unmountObb caught exception %d\n", err); 483 return; 484 } 485 } 486 isObbMounted(const String16 & filename)487 bool isObbMounted(const String16& filename) 488 { 489 Parcel data, reply; 490 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 491 data.writeString16(filename); 492 if (remote()->transact(TRANSACTION_isObbMounted, data, &reply) != NO_ERROR) { 493 ALOGD("isObbMounted could not contact remote\n"); 494 return false; 495 } 496 int32_t err = reply.readExceptionCode(); 497 if (err < 0) { 498 ALOGD("isObbMounted caught exception %d\n", err); 499 return false; 500 } 501 return reply.readInt32() != 0; 502 } 503 getMountedObbPath(const String16 & filename,String16 & path)504 bool getMountedObbPath(const String16& filename, String16& path) 505 { 506 Parcel data, reply; 507 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 508 data.writeString16(filename); 509 if (remote()->transact(TRANSACTION_getMountedObbPath, data, &reply) != NO_ERROR) { 510 ALOGD("getMountedObbPath could not contact remote\n"); 511 return false; 512 } 513 int32_t err = reply.readExceptionCode(); 514 if (err < 0) { 515 ALOGD("getMountedObbPath caught exception %d\n", err); 516 return false; 517 } 518 path = reply.readString16(); 519 return true; 520 } 521 decryptStorage(const String16 & password)522 int32_t decryptStorage(const String16& password) 523 { 524 Parcel data, reply; 525 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 526 data.writeString16(password); 527 if (remote()->transact(TRANSACTION_decryptStorage, data, &reply) != NO_ERROR) { 528 ALOGD("decryptStorage could not contact remote\n"); 529 return -1; 530 } 531 int32_t err = reply.readExceptionCode(); 532 if (err < 0) { 533 ALOGD("decryptStorage caught exception %d\n", err); 534 return err; 535 } 536 return reply.readInt32(); 537 } 538 encryptStorage(const String16 & password)539 int32_t encryptStorage(const String16& password) 540 { 541 Parcel data, reply; 542 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 543 data.writeString16(password); 544 if (remote()->transact(TRANSACTION_encryptStorage, data, &reply) != NO_ERROR) { 545 ALOGD("encryptStorage could not contact remote\n"); 546 return -1; 547 } 548 int32_t err = reply.readExceptionCode(); 549 if (err < 0) { 550 ALOGD("encryptStorage caught exception %d\n", err); 551 return err; 552 } 553 return reply.readInt32(); 554 } 555 }; 556 557 IMPLEMENT_META_INTERFACE(MountService, "android.os.storage.IStorageManager") 558 559 // ---------------------------------------------------------------------- 560 561 } 562