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: 58 BpMountService(const sp<IBinder>& impl) 59 : BpInterface<IMountService>(impl) 60 { 61 } 62 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 445 void mountObb(const String16& rawPath, const String16& canonicalPath, const String16& key, 446 const sp<IObbActionListener>& token, int32_t nonce) 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 if (remote()->transact(TRANSACTION_mountObb, data, &reply) != NO_ERROR) { 456 ALOGD("mountObb could not contact remote\n"); 457 return; 458 } 459 int32_t err = reply.readExceptionCode(); 460 if (err < 0) { 461 ALOGD("mountObb caught exception %d\n", err); 462 return; 463 } 464 } 465 466 void unmountObb(const String16& filename, const bool force, 467 const sp<IObbActionListener>& token, const int32_t nonce) 468 { 469 Parcel data, reply; 470 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 471 data.writeString16(filename); 472 data.writeInt32(force ? 1 : 0); 473 data.writeStrongBinder(IInterface::asBinder(token)); 474 data.writeInt32(nonce); 475 if (remote()->transact(TRANSACTION_unmountObb, data, &reply) != NO_ERROR) { 476 ALOGD("unmountObb could not contact remote\n"); 477 return; 478 } 479 int32_t err = reply.readExceptionCode(); 480 if (err < 0) { 481 ALOGD("unmountObb caught exception %d\n", err); 482 return; 483 } 484 } 485 486 bool isObbMounted(const String16& filename) 487 { 488 Parcel data, reply; 489 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 490 data.writeString16(filename); 491 if (remote()->transact(TRANSACTION_isObbMounted, data, &reply) != NO_ERROR) { 492 ALOGD("isObbMounted could not contact remote\n"); 493 return false; 494 } 495 int32_t err = reply.readExceptionCode(); 496 if (err < 0) { 497 ALOGD("isObbMounted caught exception %d\n", err); 498 return false; 499 } 500 return reply.readInt32() != 0; 501 } 502 503 bool getMountedObbPath(const String16& filename, String16& path) 504 { 505 Parcel data, reply; 506 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 507 data.writeString16(filename); 508 if (remote()->transact(TRANSACTION_getMountedObbPath, data, &reply) != NO_ERROR) { 509 ALOGD("getMountedObbPath could not contact remote\n"); 510 return false; 511 } 512 int32_t err = reply.readExceptionCode(); 513 if (err < 0) { 514 ALOGD("getMountedObbPath caught exception %d\n", err); 515 return false; 516 } 517 path = reply.readString16(); 518 return true; 519 } 520 521 int32_t decryptStorage(const String16& password) 522 { 523 Parcel data, reply; 524 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 525 data.writeString16(password); 526 if (remote()->transact(TRANSACTION_decryptStorage, data, &reply) != NO_ERROR) { 527 ALOGD("decryptStorage could not contact remote\n"); 528 return -1; 529 } 530 int32_t err = reply.readExceptionCode(); 531 if (err < 0) { 532 ALOGD("decryptStorage caught exception %d\n", err); 533 return err; 534 } 535 return reply.readInt32(); 536 } 537 538 int32_t encryptStorage(const String16& password) 539 { 540 Parcel data, reply; 541 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 542 data.writeString16(password); 543 if (remote()->transact(TRANSACTION_encryptStorage, data, &reply) != NO_ERROR) { 544 ALOGD("encryptStorage could not contact remote\n"); 545 return -1; 546 } 547 int32_t err = reply.readExceptionCode(); 548 if (err < 0) { 549 ALOGD("encryptStorage caught exception %d\n", err); 550 return err; 551 } 552 return reply.readInt32(); 553 } 554 }; 555 556 IMPLEMENT_META_INTERFACE(MountService, "IMountService") 557 558 // ---------------------------------------------------------------------- 559 560 } 561