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(listener->asBinder()); 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(listener->asBinder()); 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 const int32_t numUsers = reply.readInt32(); 211 *users = (int32_t*)malloc(sizeof(int32_t)*numUsers); 212 for (int i = 0; i < numUsers; i++) { 213 **users++ = reply.readInt32(); 214 } 215 return numUsers; 216 } 217 218 int32_t getVolumeState(const String16& mountPoint) 219 { 220 Parcel data, reply; 221 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 222 data.writeString16(mountPoint); 223 if (remote()->transact(TRANSACTION_getVolumeState, data, &reply) != NO_ERROR) { 224 ALOGD("getVolumeState could not contact remote\n"); 225 return -1; 226 } 227 int32_t err = reply.readExceptionCode(); 228 if (err < 0) { 229 ALOGD("getVolumeState caught exception %d\n", err); 230 return err; 231 } 232 return reply.readInt32(); 233 } 234 235 int32_t createSecureContainer(const String16& id, const int32_t sizeMb, const String16& fstype, 236 const String16& key, const int32_t ownerUid) 237 { 238 Parcel data, reply; 239 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 240 data.writeString16(id); 241 data.writeInt32(sizeMb); 242 data.writeString16(fstype); 243 data.writeString16(key); 244 data.writeInt32(ownerUid); 245 if (remote()->transact(TRANSACTION_createSecureContainer, data, &reply) != NO_ERROR) { 246 ALOGD("createSecureContainer could not contact remote\n"); 247 return -1; 248 } 249 int32_t err = reply.readExceptionCode(); 250 if (err < 0) { 251 ALOGD("createSecureContainer caught exception %d\n", err); 252 return err; 253 } 254 return reply.readInt32(); 255 } 256 257 int32_t finalizeSecureContainer(const String16& id) 258 { 259 Parcel data, reply; 260 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 261 data.writeString16(id); 262 if (remote()->transact(TRANSACTION_finalizeSecureContainer, data, &reply) != NO_ERROR) { 263 ALOGD("finalizeSecureContainer couldn't call remote\n"); 264 return -1; 265 } 266 int32_t err = reply.readExceptionCode(); 267 if (err < 0) { 268 ALOGD("finalizeSecureContainer caught exception %d\n", err); 269 return err; 270 } 271 return reply.readInt32(); 272 } 273 274 int32_t destroySecureContainer(const String16& id) 275 { 276 Parcel data, reply; 277 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 278 data.writeString16(id); 279 if (remote()->transact(TRANSACTION_destroySecureContainer, data, &reply) != NO_ERROR) { 280 ALOGD("destroySecureContainer couldn't call remote"); 281 return -1; 282 } 283 int32_t err = reply.readExceptionCode(); 284 if (err < 0) { 285 ALOGD("destroySecureContainer caught exception %d\n", err); 286 return err; 287 } 288 return reply.readInt32(); 289 } 290 291 int32_t mountSecureContainer(const String16& id, const String16& key, const int32_t ownerUid) 292 { 293 Parcel data, reply; 294 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 295 data.writeString16(id); 296 data.writeString16(key); 297 data.writeInt32(ownerUid); 298 // Assume read-only 299 data.writeInt32(1); 300 if (remote()->transact(TRANSACTION_mountSecureContainer, data, &reply) != NO_ERROR) { 301 ALOGD("mountSecureContainer couldn't call remote"); 302 return -1; 303 } 304 int32_t err = reply.readExceptionCode(); // What to do... 305 if (err < 0) { 306 ALOGD("mountSecureContainer caught exception %d\n", err); 307 return err; 308 } 309 return reply.readInt32(); 310 } 311 312 int32_t unmountSecureContainer(const String16& id, const bool force) 313 { 314 Parcel data, reply; 315 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 316 data.writeString16(id); 317 data.writeInt32(force ? 1 : 0); 318 if (remote()->transact(TRANSACTION_getSecureContainerPath, data, &reply) != NO_ERROR) { 319 ALOGD("unmountSecureContainer couldn't call remote"); 320 return -1; 321 } 322 int32_t err = reply.readExceptionCode(); // What to do... 323 if (err < 0) { 324 ALOGD("unmountSecureContainer caught exception %d\n", err); 325 return err; 326 } 327 return reply.readInt32(); 328 } 329 330 bool isSecureContainerMounted(const String16& id) 331 { 332 Parcel data, reply; 333 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 334 data.writeString16(id); 335 if (remote()->transact(TRANSACTION_isSecureContainerMounted, data, &reply) != NO_ERROR) { 336 ALOGD("isSecureContainerMounted couldn't call remote"); 337 return false; 338 } 339 int32_t err = reply.readExceptionCode(); // What to do... 340 if (err < 0) { 341 ALOGD("isSecureContainerMounted caught exception %d\n", err); 342 return false; 343 } 344 return reply.readInt32() != 0; 345 } 346 347 int32_t renameSecureContainer(const String16& oldId, const String16& newId) 348 { 349 Parcel data, reply; 350 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 351 data.writeString16(oldId); 352 data.writeString16(newId); 353 if (remote()->transact(TRANSACTION_renameSecureContainer, data, &reply) != NO_ERROR) { 354 ALOGD("renameSecureContainer couldn't call remote"); 355 return -1; 356 } 357 int32_t err = reply.readExceptionCode(); // What to do... 358 if (err < 0) { 359 ALOGD("renameSecureContainer caught exception %d\n", err); 360 return err; 361 } 362 return reply.readInt32(); 363 } 364 365 bool getSecureContainerPath(const String16& id, String16& path) 366 { 367 Parcel data, reply; 368 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 369 data.writeString16(id); 370 if (remote()->transact(TRANSACTION_getSecureContainerPath, data, &reply) != NO_ERROR) { 371 ALOGD("getSecureContainerPath couldn't call remote"); 372 return false; 373 } 374 int32_t err = reply.readExceptionCode(); // What to do... 375 if (err < 0) { 376 ALOGD("getSecureContainerPath caught exception %d\n", err); 377 return false; 378 } 379 path = reply.readString16(); 380 return true; 381 } 382 383 int32_t getSecureContainerList(const String16& id, String16*& containers) 384 { 385 Parcel data, reply; 386 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 387 data.writeString16(id); 388 if (remote()->transact(TRANSACTION_getSecureContainerList, data, &reply) != NO_ERROR) { 389 ALOGD("getSecureContainerList couldn't call remote"); 390 return -1; 391 } 392 int32_t err = reply.readExceptionCode(); 393 if (err < 0) { 394 ALOGD("getSecureContainerList caught exception %d\n", err); 395 return err; 396 } 397 const int32_t numStrings = reply.readInt32(); 398 containers = new String16[numStrings]; 399 for (int i = 0; i < numStrings; i++) { 400 containers[i] = reply.readString16(); 401 } 402 return numStrings; 403 } 404 405 void shutdown(const sp<IMountShutdownObserver>& observer) 406 { 407 Parcel data, reply; 408 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 409 data.writeStrongBinder(observer->asBinder()); 410 if (remote()->transact(TRANSACTION_shutdown, data, &reply) != NO_ERROR) { 411 ALOGD("shutdown could not contact remote\n"); 412 return; 413 } 414 int32_t err = reply.readExceptionCode(); 415 if (err < 0) { 416 ALOGD("shutdown caught exception %d\n", err); 417 return; 418 } 419 reply.readExceptionCode(); 420 } 421 422 void finishMediaUpdate() 423 { 424 Parcel data, reply; 425 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 426 if (remote()->transact(TRANSACTION_finishMediaUpdate, data, &reply) != NO_ERROR) { 427 ALOGD("finishMediaUpdate could not contact remote\n"); 428 return; 429 } 430 int32_t err = reply.readExceptionCode(); 431 if (err < 0) { 432 ALOGD("finishMediaUpdate caught exception %d\n", err); 433 return; 434 } 435 reply.readExceptionCode(); 436 } 437 438 void mountObb(const String16& rawPath, const String16& canonicalPath, const String16& key, 439 const sp<IObbActionListener>& token, int32_t nonce) 440 { 441 Parcel data, reply; 442 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 443 data.writeString16(rawPath); 444 data.writeString16(canonicalPath); 445 data.writeString16(key); 446 data.writeStrongBinder(token->asBinder()); 447 data.writeInt32(nonce); 448 if (remote()->transact(TRANSACTION_mountObb, data, &reply) != NO_ERROR) { 449 ALOGD("mountObb could not contact remote\n"); 450 return; 451 } 452 int32_t err = reply.readExceptionCode(); 453 if (err < 0) { 454 ALOGD("mountObb caught exception %d\n", err); 455 return; 456 } 457 } 458 459 void unmountObb(const String16& filename, const bool force, 460 const sp<IObbActionListener>& token, const int32_t nonce) 461 { 462 Parcel data, reply; 463 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 464 data.writeString16(filename); 465 data.writeInt32(force ? 1 : 0); 466 data.writeStrongBinder(token->asBinder()); 467 data.writeInt32(nonce); 468 if (remote()->transact(TRANSACTION_unmountObb, data, &reply) != NO_ERROR) { 469 ALOGD("unmountObb could not contact remote\n"); 470 return; 471 } 472 int32_t err = reply.readExceptionCode(); 473 if (err < 0) { 474 ALOGD("unmountObb caught exception %d\n", err); 475 return; 476 } 477 } 478 479 bool isObbMounted(const String16& filename) 480 { 481 Parcel data, reply; 482 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 483 data.writeString16(filename); 484 if (remote()->transact(TRANSACTION_isObbMounted, data, &reply) != NO_ERROR) { 485 ALOGD("isObbMounted could not contact remote\n"); 486 return false; 487 } 488 int32_t err = reply.readExceptionCode(); 489 if (err < 0) { 490 ALOGD("isObbMounted caught exception %d\n", err); 491 return false; 492 } 493 return reply.readInt32() != 0; 494 } 495 496 bool getMountedObbPath(const String16& filename, String16& path) 497 { 498 Parcel data, reply; 499 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 500 data.writeString16(filename); 501 if (remote()->transact(TRANSACTION_getMountedObbPath, data, &reply) != NO_ERROR) { 502 ALOGD("getMountedObbPath could not contact remote\n"); 503 return false; 504 } 505 int32_t err = reply.readExceptionCode(); 506 if (err < 0) { 507 ALOGD("getMountedObbPath caught exception %d\n", err); 508 return false; 509 } 510 path = reply.readString16(); 511 return true; 512 } 513 514 int32_t decryptStorage(const String16& password) 515 { 516 Parcel data, reply; 517 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 518 data.writeString16(password); 519 if (remote()->transact(TRANSACTION_decryptStorage, data, &reply) != NO_ERROR) { 520 ALOGD("decryptStorage could not contact remote\n"); 521 return -1; 522 } 523 int32_t err = reply.readExceptionCode(); 524 if (err < 0) { 525 ALOGD("decryptStorage caught exception %d\n", err); 526 return err; 527 } 528 return reply.readInt32(); 529 } 530 531 int32_t encryptStorage(const String16& password) 532 { 533 Parcel data, reply; 534 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 535 data.writeString16(password); 536 if (remote()->transact(TRANSACTION_encryptStorage, data, &reply) != NO_ERROR) { 537 ALOGD("encryptStorage could not contact remote\n"); 538 return -1; 539 } 540 int32_t err = reply.readExceptionCode(); 541 if (err < 0) { 542 ALOGD("encryptStorage caught exception %d\n", err); 543 return err; 544 } 545 return reply.readInt32(); 546 } 547 }; 548 549 IMPLEMENT_META_INTERFACE(MountService, "IMountService"); 550 551 // ---------------------------------------------------------------------- 552 553 }; 554