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 package android.os.storage; 18 19 import android.os.Binder; 20 import android.os.IBinder; 21 import android.os.IInterface; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 import android.os.RemoteException; 25 import android.os.storage.StorageVolume; 26 27 /** 28 * WARNING! Update IMountService.h and IMountService.cpp if you change this 29 * file. In particular, the ordering of the methods below must match the 30 * _TRANSACTION enum in IMountService.cpp 31 * 32 * @hide - Applications should use android.os.storage.StorageManager to access 33 * storage functions. 34 */ 35 public interface IMountService extends IInterface { 36 /** Local-side IPC implementation stub class. */ 37 public static abstract class Stub extends Binder implements IMountService { 38 private static class Proxy implements IMountService { 39 private final IBinder mRemote; 40 41 Proxy(IBinder remote) { 42 mRemote = remote; 43 } 44 45 public IBinder asBinder() { 46 return mRemote; 47 } 48 49 public String getInterfaceDescriptor() { 50 return DESCRIPTOR; 51 } 52 53 /** 54 * Registers an IMountServiceListener for receiving async 55 * notifications. 56 */ 57 public void registerListener(IMountServiceListener listener) throws RemoteException { 58 Parcel _data = Parcel.obtain(); 59 Parcel _reply = Parcel.obtain(); 60 try { 61 _data.writeInterfaceToken(DESCRIPTOR); 62 _data.writeStrongBinder((listener != null ? listener.asBinder() : null)); 63 mRemote.transact(Stub.TRANSACTION_registerListener, _data, _reply, 0); 64 _reply.readException(); 65 } finally { 66 _reply.recycle(); 67 _data.recycle(); 68 } 69 } 70 71 /** 72 * Unregisters an IMountServiceListener 73 */ 74 public void unregisterListener(IMountServiceListener listener) throws RemoteException { 75 Parcel _data = Parcel.obtain(); 76 Parcel _reply = Parcel.obtain(); 77 try { 78 _data.writeInterfaceToken(DESCRIPTOR); 79 _data.writeStrongBinder((listener != null ? listener.asBinder() : null)); 80 mRemote.transact(Stub.TRANSACTION_unregisterListener, _data, _reply, 0); 81 _reply.readException(); 82 } finally { 83 _reply.recycle(); 84 _data.recycle(); 85 } 86 } 87 88 /** 89 * Returns true if a USB mass storage host is connected 90 */ 91 public boolean isUsbMassStorageConnected() throws RemoteException { 92 Parcel _data = Parcel.obtain(); 93 Parcel _reply = Parcel.obtain(); 94 boolean _result; 95 try { 96 _data.writeInterfaceToken(DESCRIPTOR); 97 mRemote.transact(Stub.TRANSACTION_isUsbMassStorageConnected, _data, _reply, 0); 98 _reply.readException(); 99 _result = 0 != _reply.readInt(); 100 } finally { 101 _reply.recycle(); 102 _data.recycle(); 103 } 104 return _result; 105 } 106 107 /** 108 * Enables / disables USB mass storage. The caller should check 109 * actual status of enabling/disabling USB mass storage via 110 * StorageEventListener. 111 */ 112 public void setUsbMassStorageEnabled(boolean enable) throws RemoteException { 113 Parcel _data = Parcel.obtain(); 114 Parcel _reply = Parcel.obtain(); 115 try { 116 _data.writeInterfaceToken(DESCRIPTOR); 117 _data.writeInt((enable ? 1 : 0)); 118 mRemote.transact(Stub.TRANSACTION_setUsbMassStorageEnabled, _data, _reply, 0); 119 _reply.readException(); 120 } finally { 121 _reply.recycle(); 122 _data.recycle(); 123 } 124 } 125 126 /** 127 * Returns true if a USB mass storage host is enabled (media is 128 * shared) 129 */ 130 public boolean isUsbMassStorageEnabled() throws RemoteException { 131 Parcel _data = Parcel.obtain(); 132 Parcel _reply = Parcel.obtain(); 133 boolean _result; 134 try { 135 _data.writeInterfaceToken(DESCRIPTOR); 136 mRemote.transact(Stub.TRANSACTION_isUsbMassStorageEnabled, _data, _reply, 0); 137 _reply.readException(); 138 _result = 0 != _reply.readInt(); 139 } finally { 140 _reply.recycle(); 141 _data.recycle(); 142 } 143 return _result; 144 } 145 146 /** 147 * Mount external storage at given mount point. Returns an int 148 * consistent with MountServiceResultCode 149 */ 150 public int mountVolume(String mountPoint) throws RemoteException { 151 Parcel _data = Parcel.obtain(); 152 Parcel _reply = Parcel.obtain(); 153 int _result; 154 try { 155 _data.writeInterfaceToken(DESCRIPTOR); 156 _data.writeString(mountPoint); 157 mRemote.transact(Stub.TRANSACTION_mountVolume, _data, _reply, 0); 158 _reply.readException(); 159 _result = _reply.readInt(); 160 } finally { 161 _reply.recycle(); 162 _data.recycle(); 163 } 164 return _result; 165 } 166 167 /** 168 * Safely unmount external storage at given mount point. The unmount 169 * is an asynchronous operation. Applications should register 170 * StorageEventListener for storage related status changes. 171 */ 172 public void unmountVolume(String mountPoint, boolean force, boolean removeEncryption) 173 throws RemoteException { 174 Parcel _data = Parcel.obtain(); 175 Parcel _reply = Parcel.obtain(); 176 try { 177 _data.writeInterfaceToken(DESCRIPTOR); 178 _data.writeString(mountPoint); 179 _data.writeInt((force ? 1 : 0)); 180 _data.writeInt((removeEncryption ? 1 : 0)); 181 mRemote.transact(Stub.TRANSACTION_unmountVolume, _data, _reply, 0); 182 _reply.readException(); 183 } finally { 184 _reply.recycle(); 185 _data.recycle(); 186 } 187 } 188 189 /** 190 * Format external storage given a mount point. Returns an int 191 * consistent with MountServiceResultCode 192 */ 193 public int formatVolume(String mountPoint) throws RemoteException { 194 Parcel _data = Parcel.obtain(); 195 Parcel _reply = Parcel.obtain(); 196 int _result; 197 try { 198 _data.writeInterfaceToken(DESCRIPTOR); 199 _data.writeString(mountPoint); 200 mRemote.transact(Stub.TRANSACTION_formatVolume, _data, _reply, 0); 201 _reply.readException(); 202 _result = _reply.readInt(); 203 } finally { 204 _reply.recycle(); 205 _data.recycle(); 206 } 207 return _result; 208 } 209 210 /** 211 * Returns an array of pids with open files on the specified path. 212 */ 213 public int[] getStorageUsers(String path) throws RemoteException { 214 Parcel _data = Parcel.obtain(); 215 Parcel _reply = Parcel.obtain(); 216 int[] _result; 217 try { 218 _data.writeInterfaceToken(DESCRIPTOR); 219 _data.writeString(path); 220 mRemote.transact(Stub.TRANSACTION_getStorageUsers, _data, _reply, 0); 221 _reply.readException(); 222 _result = _reply.createIntArray(); 223 } finally { 224 _reply.recycle(); 225 _data.recycle(); 226 } 227 return _result; 228 } 229 230 /** 231 * Gets the state of a volume via its mountpoint. 232 */ 233 public String getVolumeState(String mountPoint) throws RemoteException { 234 Parcel _data = Parcel.obtain(); 235 Parcel _reply = Parcel.obtain(); 236 String _result; 237 try { 238 _data.writeInterfaceToken(DESCRIPTOR); 239 _data.writeString(mountPoint); 240 mRemote.transact(Stub.TRANSACTION_getVolumeState, _data, _reply, 0); 241 _reply.readException(); 242 _result = _reply.readString(); 243 } finally { 244 _reply.recycle(); 245 _data.recycle(); 246 } 247 return _result; 248 } 249 250 /* 251 * Creates a secure container with the specified parameters. Returns 252 * an int consistent with MountServiceResultCode 253 */ 254 public int createSecureContainer(String id, int sizeMb, String fstype, String key, 255 int ownerUid, boolean external) throws RemoteException { 256 Parcel _data = Parcel.obtain(); 257 Parcel _reply = Parcel.obtain(); 258 int _result; 259 try { 260 _data.writeInterfaceToken(DESCRIPTOR); 261 _data.writeString(id); 262 _data.writeInt(sizeMb); 263 _data.writeString(fstype); 264 _data.writeString(key); 265 _data.writeInt(ownerUid); 266 _data.writeInt(external ? 1 : 0); 267 mRemote.transact(Stub.TRANSACTION_createSecureContainer, _data, _reply, 0); 268 _reply.readException(); 269 _result = _reply.readInt(); 270 } finally { 271 _reply.recycle(); 272 _data.recycle(); 273 } 274 return _result; 275 } 276 277 /* 278 * Destroy a secure container, and free up all resources associated 279 * with it. NOTE: Ensure all references are released prior to 280 * deleting. Returns an int consistent with MountServiceResultCode 281 */ 282 public int destroySecureContainer(String id, boolean force) throws RemoteException { 283 Parcel _data = Parcel.obtain(); 284 Parcel _reply = Parcel.obtain(); 285 int _result; 286 try { 287 _data.writeInterfaceToken(DESCRIPTOR); 288 _data.writeString(id); 289 _data.writeInt((force ? 1 : 0)); 290 mRemote.transact(Stub.TRANSACTION_destroySecureContainer, _data, _reply, 0); 291 _reply.readException(); 292 _result = _reply.readInt(); 293 } finally { 294 _reply.recycle(); 295 _data.recycle(); 296 } 297 return _result; 298 } 299 300 /* 301 * Finalize a container which has just been created and populated. 302 * After finalization, the container is immutable. Returns an int 303 * consistent with MountServiceResultCode 304 */ 305 public int finalizeSecureContainer(String id) throws RemoteException { 306 Parcel _data = Parcel.obtain(); 307 Parcel _reply = Parcel.obtain(); 308 int _result; 309 try { 310 _data.writeInterfaceToken(DESCRIPTOR); 311 _data.writeString(id); 312 mRemote.transact(Stub.TRANSACTION_finalizeSecureContainer, _data, _reply, 0); 313 _reply.readException(); 314 _result = _reply.readInt(); 315 } finally { 316 _reply.recycle(); 317 _data.recycle(); 318 } 319 return _result; 320 } 321 322 /* 323 * Mount a secure container with the specified key and owner UID. 324 * Returns an int consistent with MountServiceResultCode 325 */ 326 public int mountSecureContainer(String id, String key, int ownerUid) 327 throws RemoteException { 328 Parcel _data = Parcel.obtain(); 329 Parcel _reply = Parcel.obtain(); 330 int _result; 331 try { 332 _data.writeInterfaceToken(DESCRIPTOR); 333 _data.writeString(id); 334 _data.writeString(key); 335 _data.writeInt(ownerUid); 336 mRemote.transact(Stub.TRANSACTION_mountSecureContainer, _data, _reply, 0); 337 _reply.readException(); 338 _result = _reply.readInt(); 339 } finally { 340 _reply.recycle(); 341 _data.recycle(); 342 } 343 return _result; 344 } 345 346 /* 347 * Unount a secure container. Returns an int consistent with 348 * MountServiceResultCode 349 */ 350 public int unmountSecureContainer(String id, boolean force) throws RemoteException { 351 Parcel _data = Parcel.obtain(); 352 Parcel _reply = Parcel.obtain(); 353 int _result; 354 try { 355 _data.writeInterfaceToken(DESCRIPTOR); 356 _data.writeString(id); 357 _data.writeInt((force ? 1 : 0)); 358 mRemote.transact(Stub.TRANSACTION_unmountSecureContainer, _data, _reply, 0); 359 _reply.readException(); 360 _result = _reply.readInt(); 361 } finally { 362 _reply.recycle(); 363 _data.recycle(); 364 } 365 return _result; 366 } 367 368 /* 369 * Returns true if the specified container is mounted 370 */ 371 public boolean isSecureContainerMounted(String id) throws RemoteException { 372 Parcel _data = Parcel.obtain(); 373 Parcel _reply = Parcel.obtain(); 374 boolean _result; 375 try { 376 _data.writeInterfaceToken(DESCRIPTOR); 377 _data.writeString(id); 378 mRemote.transact(Stub.TRANSACTION_isSecureContainerMounted, _data, _reply, 0); 379 _reply.readException(); 380 _result = 0 != _reply.readInt(); 381 } finally { 382 _reply.recycle(); 383 _data.recycle(); 384 } 385 return _result; 386 } 387 388 /* 389 * Rename an unmounted secure container. Returns an int consistent 390 * with MountServiceResultCode 391 */ 392 public int renameSecureContainer(String oldId, String newId) throws RemoteException { 393 Parcel _data = Parcel.obtain(); 394 Parcel _reply = Parcel.obtain(); 395 int _result; 396 try { 397 _data.writeInterfaceToken(DESCRIPTOR); 398 _data.writeString(oldId); 399 _data.writeString(newId); 400 mRemote.transact(Stub.TRANSACTION_renameSecureContainer, _data, _reply, 0); 401 _reply.readException(); 402 _result = _reply.readInt(); 403 } finally { 404 _reply.recycle(); 405 _data.recycle(); 406 } 407 return _result; 408 } 409 410 /* 411 * Returns the filesystem path of a mounted secure container. 412 */ 413 public String getSecureContainerPath(String id) throws RemoteException { 414 Parcel _data = Parcel.obtain(); 415 Parcel _reply = Parcel.obtain(); 416 String _result; 417 try { 418 _data.writeInterfaceToken(DESCRIPTOR); 419 _data.writeString(id); 420 mRemote.transact(Stub.TRANSACTION_getSecureContainerPath, _data, _reply, 0); 421 _reply.readException(); 422 _result = _reply.readString(); 423 } finally { 424 _reply.recycle(); 425 _data.recycle(); 426 } 427 return _result; 428 } 429 430 /** 431 * Gets an Array of currently known secure container IDs 432 */ 433 public String[] getSecureContainerList() throws RemoteException { 434 Parcel _data = Parcel.obtain(); 435 Parcel _reply = Parcel.obtain(); 436 String[] _result; 437 try { 438 _data.writeInterfaceToken(DESCRIPTOR); 439 mRemote.transact(Stub.TRANSACTION_getSecureContainerList, _data, _reply, 0); 440 _reply.readException(); 441 _result = _reply.createStringArray(); 442 } finally { 443 _reply.recycle(); 444 _data.recycle(); 445 } 446 return _result; 447 } 448 449 /** 450 * Shuts down the MountService and gracefully unmounts all external 451 * media. Invokes call back once the shutdown is complete. 452 */ 453 public void shutdown(IMountShutdownObserver observer) 454 throws RemoteException { 455 Parcel _data = Parcel.obtain(); 456 Parcel _reply = Parcel.obtain(); 457 try { 458 _data.writeInterfaceToken(DESCRIPTOR); 459 _data.writeStrongBinder((observer != null ? observer.asBinder() : null)); 460 mRemote.transact(Stub.TRANSACTION_shutdown, _data, _reply, 0); 461 _reply.readException(); 462 } finally { 463 _reply.recycle(); 464 _data.recycle(); 465 } 466 } 467 468 /** 469 * Call into MountService by PackageManager to notify that its done 470 * processing the media status update request. 471 */ 472 public void finishMediaUpdate() throws RemoteException { 473 Parcel _data = Parcel.obtain(); 474 Parcel _reply = Parcel.obtain(); 475 try { 476 _data.writeInterfaceToken(DESCRIPTOR); 477 mRemote.transact(Stub.TRANSACTION_finishMediaUpdate, _data, _reply, 0); 478 _reply.readException(); 479 } finally { 480 _reply.recycle(); 481 _data.recycle(); 482 } 483 } 484 485 /** 486 * Mounts an Opaque Binary Blob (OBB) with the specified decryption 487 * key and only allows the calling process's UID access to the 488 * contents. MountService will call back to the supplied 489 * IObbActionListener to inform it of the terminal state of the 490 * call. 491 */ 492 public void mountObb(String rawPath, String canonicalPath, String key, 493 IObbActionListener token, int nonce) throws RemoteException { 494 Parcel _data = Parcel.obtain(); 495 Parcel _reply = Parcel.obtain(); 496 try { 497 _data.writeInterfaceToken(DESCRIPTOR); 498 _data.writeString(rawPath); 499 _data.writeString(canonicalPath); 500 _data.writeString(key); 501 _data.writeStrongBinder((token != null ? token.asBinder() : null)); 502 _data.writeInt(nonce); 503 mRemote.transact(Stub.TRANSACTION_mountObb, _data, _reply, 0); 504 _reply.readException(); 505 } finally { 506 _reply.recycle(); 507 _data.recycle(); 508 } 509 } 510 511 /** 512 * Unmounts an Opaque Binary Blob (OBB). When the force flag is 513 * specified, any program using it will be forcibly killed to 514 * unmount the image. MountService will call back to the supplied 515 * IObbActionListener to inform it of the terminal state of the 516 * call. 517 */ 518 public void unmountObb( 519 String rawPath, boolean force, IObbActionListener token, int nonce) 520 throws RemoteException { 521 Parcel _data = Parcel.obtain(); 522 Parcel _reply = Parcel.obtain(); 523 try { 524 _data.writeInterfaceToken(DESCRIPTOR); 525 _data.writeString(rawPath); 526 _data.writeInt((force ? 1 : 0)); 527 _data.writeStrongBinder((token != null ? token.asBinder() : null)); 528 _data.writeInt(nonce); 529 mRemote.transact(Stub.TRANSACTION_unmountObb, _data, _reply, 0); 530 _reply.readException(); 531 } finally { 532 _reply.recycle(); 533 _data.recycle(); 534 } 535 } 536 537 /** 538 * Checks whether the specified Opaque Binary Blob (OBB) is mounted 539 * somewhere. 540 */ 541 public boolean isObbMounted(String rawPath) throws RemoteException { 542 Parcel _data = Parcel.obtain(); 543 Parcel _reply = Parcel.obtain(); 544 boolean _result; 545 try { 546 _data.writeInterfaceToken(DESCRIPTOR); 547 _data.writeString(rawPath); 548 mRemote.transact(Stub.TRANSACTION_isObbMounted, _data, _reply, 0); 549 _reply.readException(); 550 _result = 0 != _reply.readInt(); 551 } finally { 552 _reply.recycle(); 553 _data.recycle(); 554 } 555 return _result; 556 } 557 558 /** 559 * Gets the path to the mounted Opaque Binary Blob (OBB). 560 */ 561 public String getMountedObbPath(String rawPath) throws RemoteException { 562 Parcel _data = Parcel.obtain(); 563 Parcel _reply = Parcel.obtain(); 564 String _result; 565 try { 566 _data.writeInterfaceToken(DESCRIPTOR); 567 _data.writeString(rawPath); 568 mRemote.transact(Stub.TRANSACTION_getMountedObbPath, _data, _reply, 0); 569 _reply.readException(); 570 _result = _reply.readString(); 571 } finally { 572 _reply.recycle(); 573 _data.recycle(); 574 } 575 return _result; 576 } 577 578 /** 579 * Returns whether the external storage is emulated. 580 */ 581 public boolean isExternalStorageEmulated() throws RemoteException { 582 Parcel _data = Parcel.obtain(); 583 Parcel _reply = Parcel.obtain(); 584 boolean _result; 585 try { 586 _data.writeInterfaceToken(DESCRIPTOR); 587 mRemote.transact(Stub.TRANSACTION_isExternalStorageEmulated, _data, _reply, 0); 588 _reply.readException(); 589 _result = 0 != _reply.readInt(); 590 } finally { 591 _reply.recycle(); 592 _data.recycle(); 593 } 594 return _result; 595 } 596 597 public int getEncryptionState() throws RemoteException { 598 Parcel _data = Parcel.obtain(); 599 Parcel _reply = Parcel.obtain(); 600 int _result; 601 try { 602 _data.writeInterfaceToken(DESCRIPTOR); 603 mRemote.transact(Stub.TRANSACTION_getEncryptionState, _data, _reply, 0); 604 _reply.readException(); 605 _result = _reply.readInt(); 606 } finally { 607 _reply.recycle(); 608 _data.recycle(); 609 } 610 return _result; 611 } 612 613 public int decryptStorage(String password) throws RemoteException { 614 Parcel _data = Parcel.obtain(); 615 Parcel _reply = Parcel.obtain(); 616 int _result; 617 try { 618 _data.writeInterfaceToken(DESCRIPTOR); 619 _data.writeString(password); 620 mRemote.transact(Stub.TRANSACTION_decryptStorage, _data, _reply, 0); 621 _reply.readException(); 622 _result = _reply.readInt(); 623 } finally { 624 _reply.recycle(); 625 _data.recycle(); 626 } 627 return _result; 628 } 629 630 public int encryptStorage(String password) throws RemoteException { 631 Parcel _data = Parcel.obtain(); 632 Parcel _reply = Parcel.obtain(); 633 int _result; 634 try { 635 _data.writeInterfaceToken(DESCRIPTOR); 636 _data.writeString(password); 637 mRemote.transact(Stub.TRANSACTION_encryptStorage, _data, _reply, 0); 638 _reply.readException(); 639 _result = _reply.readInt(); 640 } finally { 641 _reply.recycle(); 642 _data.recycle(); 643 } 644 return _result; 645 } 646 647 public int changeEncryptionPassword(String password) throws RemoteException { 648 Parcel _data = Parcel.obtain(); 649 Parcel _reply = Parcel.obtain(); 650 int _result; 651 try { 652 _data.writeInterfaceToken(DESCRIPTOR); 653 _data.writeString(password); 654 mRemote.transact(Stub.TRANSACTION_changeEncryptionPassword, _data, _reply, 0); 655 _reply.readException(); 656 _result = _reply.readInt(); 657 } finally { 658 _reply.recycle(); 659 _data.recycle(); 660 } 661 return _result; 662 } 663 664 @Override 665 public int verifyEncryptionPassword(String password) throws RemoteException { 666 Parcel _data = Parcel.obtain(); 667 Parcel _reply = Parcel.obtain(); 668 int _result; 669 try { 670 _data.writeInterfaceToken(DESCRIPTOR); 671 _data.writeString(password); 672 mRemote.transact(Stub.TRANSACTION_verifyEncryptionPassword, _data, _reply, 0); 673 _reply.readException(); 674 _result = _reply.readInt(); 675 } finally { 676 _reply.recycle(); 677 _data.recycle(); 678 } 679 return _result; 680 } 681 682 public StorageVolume[] getVolumeList() throws RemoteException { 683 Parcel _data = Parcel.obtain(); 684 Parcel _reply = Parcel.obtain(); 685 StorageVolume[] _result; 686 try { 687 _data.writeInterfaceToken(DESCRIPTOR); 688 mRemote.transact(Stub.TRANSACTION_getVolumeList, _data, _reply, 0); 689 _reply.readException(); 690 _result = _reply.createTypedArray(StorageVolume.CREATOR); 691 } finally { 692 _reply.recycle(); 693 _data.recycle(); 694 } 695 return _result; 696 } 697 698 /* 699 * Returns the filesystem path of a mounted secure container. 700 */ 701 public String getSecureContainerFilesystemPath(String id) throws RemoteException { 702 Parcel _data = Parcel.obtain(); 703 Parcel _reply = Parcel.obtain(); 704 String _result; 705 try { 706 _data.writeInterfaceToken(DESCRIPTOR); 707 _data.writeString(id); 708 mRemote.transact(Stub.TRANSACTION_getSecureContainerFilesystemPath, _data, _reply, 0); 709 _reply.readException(); 710 _result = _reply.readString(); 711 } finally { 712 _reply.recycle(); 713 _data.recycle(); 714 } 715 return _result; 716 } 717 718 /** 719 * Fix permissions in a container which has just been created and 720 * populated. Returns an int consistent with MountServiceResultCode 721 */ 722 public int fixPermissionsSecureContainer(String id, int gid, String filename) 723 throws RemoteException { 724 Parcel _data = Parcel.obtain(); 725 Parcel _reply = Parcel.obtain(); 726 int _result; 727 try { 728 _data.writeInterfaceToken(DESCRIPTOR); 729 _data.writeString(id); 730 _data.writeInt(gid); 731 _data.writeString(filename); 732 mRemote.transact(Stub.TRANSACTION_fixPermissionsSecureContainer, _data, _reply, 0); 733 _reply.readException(); 734 _result = _reply.readInt(); 735 } finally { 736 _reply.recycle(); 737 _data.recycle(); 738 } 739 return _result; 740 741 } 742 } 743 744 private static final String DESCRIPTOR = "IMountService"; 745 746 static final int TRANSACTION_registerListener = IBinder.FIRST_CALL_TRANSACTION + 0; 747 748 static final int TRANSACTION_unregisterListener = IBinder.FIRST_CALL_TRANSACTION + 1; 749 750 static final int TRANSACTION_isUsbMassStorageConnected = IBinder.FIRST_CALL_TRANSACTION + 2; 751 752 static final int TRANSACTION_setUsbMassStorageEnabled = IBinder.FIRST_CALL_TRANSACTION + 3; 753 754 static final int TRANSACTION_isUsbMassStorageEnabled = IBinder.FIRST_CALL_TRANSACTION + 4; 755 756 static final int TRANSACTION_mountVolume = IBinder.FIRST_CALL_TRANSACTION + 5; 757 758 static final int TRANSACTION_unmountVolume = IBinder.FIRST_CALL_TRANSACTION + 6; 759 760 static final int TRANSACTION_formatVolume = IBinder.FIRST_CALL_TRANSACTION + 7; 761 762 static final int TRANSACTION_getStorageUsers = IBinder.FIRST_CALL_TRANSACTION + 8; 763 764 static final int TRANSACTION_getVolumeState = IBinder.FIRST_CALL_TRANSACTION + 9; 765 766 static final int TRANSACTION_createSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 10; 767 768 static final int TRANSACTION_finalizeSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 11; 769 770 static final int TRANSACTION_destroySecureContainer = IBinder.FIRST_CALL_TRANSACTION + 12; 771 772 static final int TRANSACTION_mountSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 13; 773 774 static final int TRANSACTION_unmountSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 14; 775 776 static final int TRANSACTION_isSecureContainerMounted = IBinder.FIRST_CALL_TRANSACTION + 15; 777 778 static final int TRANSACTION_renameSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 16; 779 780 static final int TRANSACTION_getSecureContainerPath = IBinder.FIRST_CALL_TRANSACTION + 17; 781 782 static final int TRANSACTION_getSecureContainerList = IBinder.FIRST_CALL_TRANSACTION + 18; 783 784 static final int TRANSACTION_shutdown = IBinder.FIRST_CALL_TRANSACTION + 19; 785 786 static final int TRANSACTION_finishMediaUpdate = IBinder.FIRST_CALL_TRANSACTION + 20; 787 788 static final int TRANSACTION_mountObb = IBinder.FIRST_CALL_TRANSACTION + 21; 789 790 static final int TRANSACTION_unmountObb = IBinder.FIRST_CALL_TRANSACTION + 22; 791 792 static final int TRANSACTION_isObbMounted = IBinder.FIRST_CALL_TRANSACTION + 23; 793 794 static final int TRANSACTION_getMountedObbPath = IBinder.FIRST_CALL_TRANSACTION + 24; 795 796 static final int TRANSACTION_isExternalStorageEmulated = IBinder.FIRST_CALL_TRANSACTION + 25; 797 798 static final int TRANSACTION_decryptStorage = IBinder.FIRST_CALL_TRANSACTION + 26; 799 800 static final int TRANSACTION_encryptStorage = IBinder.FIRST_CALL_TRANSACTION + 27; 801 802 static final int TRANSACTION_changeEncryptionPassword = IBinder.FIRST_CALL_TRANSACTION + 28; 803 804 static final int TRANSACTION_getVolumeList = IBinder.FIRST_CALL_TRANSACTION + 29; 805 806 static final int TRANSACTION_getSecureContainerFilesystemPath = IBinder.FIRST_CALL_TRANSACTION + 30; 807 808 static final int TRANSACTION_getEncryptionState = IBinder.FIRST_CALL_TRANSACTION + 31; 809 810 static final int TRANSACTION_verifyEncryptionPassword = IBinder.FIRST_CALL_TRANSACTION + 32; 811 812 static final int TRANSACTION_fixPermissionsSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 33; 813 814 /** 815 * Cast an IBinder object into an IMountService interface, generating a 816 * proxy if needed. 817 */ 818 public static IMountService asInterface(IBinder obj) { 819 if (obj == null) { 820 return null; 821 } 822 IInterface iin = obj.queryLocalInterface(DESCRIPTOR); 823 if (iin != null && iin instanceof IMountService) { 824 return (IMountService) iin; 825 } 826 return new IMountService.Stub.Proxy(obj); 827 } 828 829 /** Construct the stub at attach it to the interface. */ 830 public Stub() { 831 attachInterface(this, DESCRIPTOR); 832 } 833 834 public IBinder asBinder() { 835 return this; 836 } 837 838 @Override 839 public boolean onTransact(int code, Parcel data, Parcel reply, 840 int flags) throws RemoteException { 841 switch (code) { 842 case INTERFACE_TRANSACTION: { 843 reply.writeString(DESCRIPTOR); 844 return true; 845 } 846 case TRANSACTION_registerListener: { 847 data.enforceInterface(DESCRIPTOR); 848 IMountServiceListener listener; 849 listener = IMountServiceListener.Stub.asInterface(data.readStrongBinder()); 850 registerListener(listener); 851 reply.writeNoException(); 852 return true; 853 } 854 case TRANSACTION_unregisterListener: { 855 data.enforceInterface(DESCRIPTOR); 856 IMountServiceListener listener; 857 listener = IMountServiceListener.Stub.asInterface(data.readStrongBinder()); 858 unregisterListener(listener); 859 reply.writeNoException(); 860 return true; 861 } 862 case TRANSACTION_isUsbMassStorageConnected: { 863 data.enforceInterface(DESCRIPTOR); 864 boolean result = isUsbMassStorageConnected(); 865 reply.writeNoException(); 866 reply.writeInt((result ? 1 : 0)); 867 return true; 868 } 869 case TRANSACTION_setUsbMassStorageEnabled: { 870 data.enforceInterface(DESCRIPTOR); 871 boolean enable; 872 enable = 0 != data.readInt(); 873 setUsbMassStorageEnabled(enable); 874 reply.writeNoException(); 875 return true; 876 } 877 case TRANSACTION_isUsbMassStorageEnabled: { 878 data.enforceInterface(DESCRIPTOR); 879 boolean result = isUsbMassStorageEnabled(); 880 reply.writeNoException(); 881 reply.writeInt((result ? 1 : 0)); 882 return true; 883 } 884 case TRANSACTION_mountVolume: { 885 data.enforceInterface(DESCRIPTOR); 886 String mountPoint; 887 mountPoint = data.readString(); 888 int resultCode = mountVolume(mountPoint); 889 reply.writeNoException(); 890 reply.writeInt(resultCode); 891 return true; 892 } 893 case TRANSACTION_unmountVolume: { 894 data.enforceInterface(DESCRIPTOR); 895 String mountPoint; 896 mountPoint = data.readString(); 897 boolean force = 0 != data.readInt(); 898 boolean removeEncrypt = 0 != data.readInt(); 899 unmountVolume(mountPoint, force, removeEncrypt); 900 reply.writeNoException(); 901 return true; 902 } 903 case TRANSACTION_formatVolume: { 904 data.enforceInterface(DESCRIPTOR); 905 String mountPoint; 906 mountPoint = data.readString(); 907 int result = formatVolume(mountPoint); 908 reply.writeNoException(); 909 reply.writeInt(result); 910 return true; 911 } 912 case TRANSACTION_getStorageUsers: { 913 data.enforceInterface(DESCRIPTOR); 914 String path; 915 path = data.readString(); 916 int[] pids = getStorageUsers(path); 917 reply.writeNoException(); 918 reply.writeIntArray(pids); 919 return true; 920 } 921 case TRANSACTION_getVolumeState: { 922 data.enforceInterface(DESCRIPTOR); 923 String mountPoint; 924 mountPoint = data.readString(); 925 String state = getVolumeState(mountPoint); 926 reply.writeNoException(); 927 reply.writeString(state); 928 return true; 929 } 930 case TRANSACTION_createSecureContainer: { 931 data.enforceInterface(DESCRIPTOR); 932 String id; 933 id = data.readString(); 934 int sizeMb; 935 sizeMb = data.readInt(); 936 String fstype; 937 fstype = data.readString(); 938 String key; 939 key = data.readString(); 940 int ownerUid; 941 ownerUid = data.readInt(); 942 boolean external; 943 external = 0 != data.readInt(); 944 int resultCode = createSecureContainer(id, sizeMb, fstype, key, ownerUid, 945 external); 946 reply.writeNoException(); 947 reply.writeInt(resultCode); 948 return true; 949 } 950 case TRANSACTION_finalizeSecureContainer: { 951 data.enforceInterface(DESCRIPTOR); 952 String id; 953 id = data.readString(); 954 int resultCode = finalizeSecureContainer(id); 955 reply.writeNoException(); 956 reply.writeInt(resultCode); 957 return true; 958 } 959 case TRANSACTION_destroySecureContainer: { 960 data.enforceInterface(DESCRIPTOR); 961 String id; 962 id = data.readString(); 963 boolean force; 964 force = 0 != data.readInt(); 965 int resultCode = destroySecureContainer(id, force); 966 reply.writeNoException(); 967 reply.writeInt(resultCode); 968 return true; 969 } 970 case TRANSACTION_mountSecureContainer: { 971 data.enforceInterface(DESCRIPTOR); 972 String id; 973 id = data.readString(); 974 String key; 975 key = data.readString(); 976 int ownerUid; 977 ownerUid = data.readInt(); 978 int resultCode = mountSecureContainer(id, key, ownerUid); 979 reply.writeNoException(); 980 reply.writeInt(resultCode); 981 return true; 982 } 983 case TRANSACTION_unmountSecureContainer: { 984 data.enforceInterface(DESCRIPTOR); 985 String id; 986 id = data.readString(); 987 boolean force; 988 force = 0 != data.readInt(); 989 int resultCode = unmountSecureContainer(id, force); 990 reply.writeNoException(); 991 reply.writeInt(resultCode); 992 return true; 993 } 994 case TRANSACTION_isSecureContainerMounted: { 995 data.enforceInterface(DESCRIPTOR); 996 String id; 997 id = data.readString(); 998 boolean status = isSecureContainerMounted(id); 999 reply.writeNoException(); 1000 reply.writeInt((status ? 1 : 0)); 1001 return true; 1002 } 1003 case TRANSACTION_renameSecureContainer: { 1004 data.enforceInterface(DESCRIPTOR); 1005 String oldId; 1006 oldId = data.readString(); 1007 String newId; 1008 newId = data.readString(); 1009 int resultCode = renameSecureContainer(oldId, newId); 1010 reply.writeNoException(); 1011 reply.writeInt(resultCode); 1012 return true; 1013 } 1014 case TRANSACTION_getSecureContainerPath: { 1015 data.enforceInterface(DESCRIPTOR); 1016 String id; 1017 id = data.readString(); 1018 String path = getSecureContainerPath(id); 1019 reply.writeNoException(); 1020 reply.writeString(path); 1021 return true; 1022 } 1023 case TRANSACTION_getSecureContainerList: { 1024 data.enforceInterface(DESCRIPTOR); 1025 String[] ids = getSecureContainerList(); 1026 reply.writeNoException(); 1027 reply.writeStringArray(ids); 1028 return true; 1029 } 1030 case TRANSACTION_shutdown: { 1031 data.enforceInterface(DESCRIPTOR); 1032 IMountShutdownObserver observer; 1033 observer = IMountShutdownObserver.Stub.asInterface(data 1034 .readStrongBinder()); 1035 shutdown(observer); 1036 reply.writeNoException(); 1037 return true; 1038 } 1039 case TRANSACTION_finishMediaUpdate: { 1040 data.enforceInterface(DESCRIPTOR); 1041 finishMediaUpdate(); 1042 reply.writeNoException(); 1043 return true; 1044 } 1045 case TRANSACTION_mountObb: { 1046 data.enforceInterface(DESCRIPTOR); 1047 final String rawPath = data.readString(); 1048 final String canonicalPath = data.readString(); 1049 final String key = data.readString(); 1050 IObbActionListener observer; 1051 observer = IObbActionListener.Stub.asInterface(data.readStrongBinder()); 1052 int nonce; 1053 nonce = data.readInt(); 1054 mountObb(rawPath, canonicalPath, key, observer, nonce); 1055 reply.writeNoException(); 1056 return true; 1057 } 1058 case TRANSACTION_unmountObb: { 1059 data.enforceInterface(DESCRIPTOR); 1060 String filename; 1061 filename = data.readString(); 1062 boolean force; 1063 force = 0 != data.readInt(); 1064 IObbActionListener observer; 1065 observer = IObbActionListener.Stub.asInterface(data.readStrongBinder()); 1066 int nonce; 1067 nonce = data.readInt(); 1068 unmountObb(filename, force, observer, nonce); 1069 reply.writeNoException(); 1070 return true; 1071 } 1072 case TRANSACTION_isObbMounted: { 1073 data.enforceInterface(DESCRIPTOR); 1074 String filename; 1075 filename = data.readString(); 1076 boolean status = isObbMounted(filename); 1077 reply.writeNoException(); 1078 reply.writeInt((status ? 1 : 0)); 1079 return true; 1080 } 1081 case TRANSACTION_getMountedObbPath: { 1082 data.enforceInterface(DESCRIPTOR); 1083 String filename; 1084 filename = data.readString(); 1085 String mountedPath = getMountedObbPath(filename); 1086 reply.writeNoException(); 1087 reply.writeString(mountedPath); 1088 return true; 1089 } 1090 case TRANSACTION_isExternalStorageEmulated: { 1091 data.enforceInterface(DESCRIPTOR); 1092 boolean emulated = isExternalStorageEmulated(); 1093 reply.writeNoException(); 1094 reply.writeInt(emulated ? 1 : 0); 1095 return true; 1096 } 1097 case TRANSACTION_decryptStorage: { 1098 data.enforceInterface(DESCRIPTOR); 1099 String password = data.readString(); 1100 int result = decryptStorage(password); 1101 reply.writeNoException(); 1102 reply.writeInt(result); 1103 return true; 1104 } 1105 case TRANSACTION_encryptStorage: { 1106 data.enforceInterface(DESCRIPTOR); 1107 String password = data.readString(); 1108 int result = encryptStorage(password); 1109 reply.writeNoException(); 1110 reply.writeInt(result); 1111 return true; 1112 } 1113 case TRANSACTION_changeEncryptionPassword: { 1114 data.enforceInterface(DESCRIPTOR); 1115 String password = data.readString(); 1116 int result = changeEncryptionPassword(password); 1117 reply.writeNoException(); 1118 reply.writeInt(result); 1119 return true; 1120 } 1121 case TRANSACTION_getVolumeList: { 1122 data.enforceInterface(DESCRIPTOR); 1123 StorageVolume[] result = getVolumeList(); 1124 reply.writeNoException(); 1125 reply.writeTypedArray(result, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 1126 return true; 1127 } 1128 case TRANSACTION_getSecureContainerFilesystemPath: { 1129 data.enforceInterface(DESCRIPTOR); 1130 String id; 1131 id = data.readString(); 1132 String path = getSecureContainerFilesystemPath(id); 1133 reply.writeNoException(); 1134 reply.writeString(path); 1135 return true; 1136 } 1137 case TRANSACTION_getEncryptionState: { 1138 data.enforceInterface(DESCRIPTOR); 1139 int result = getEncryptionState(); 1140 reply.writeNoException(); 1141 reply.writeInt(result); 1142 return true; 1143 } 1144 case TRANSACTION_fixPermissionsSecureContainer: { 1145 data.enforceInterface(DESCRIPTOR); 1146 String id; 1147 id = data.readString(); 1148 int gid; 1149 gid = data.readInt(); 1150 String filename; 1151 filename = data.readString(); 1152 int resultCode = fixPermissionsSecureContainer(id, gid, filename); 1153 reply.writeNoException(); 1154 reply.writeInt(resultCode); 1155 return true; 1156 } 1157 } 1158 return super.onTransact(code, data, reply, flags); 1159 } 1160 } 1161 1162 /* 1163 * Creates a secure container with the specified parameters. Returns an int 1164 * consistent with MountServiceResultCode 1165 */ 1166 public int createSecureContainer(String id, int sizeMb, String fstype, String key, 1167 int ownerUid, boolean external) throws RemoteException; 1168 1169 /* 1170 * Destroy a secure container, and free up all resources associated with it. 1171 * NOTE: Ensure all references are released prior to deleting. Returns an 1172 * int consistent with MountServiceResultCode 1173 */ 1174 public int destroySecureContainer(String id, boolean force) throws RemoteException; 1175 1176 /* 1177 * Finalize a container which has just been created and populated. After 1178 * finalization, the container is immutable. Returns an int consistent with 1179 * MountServiceResultCode 1180 */ 1181 public int finalizeSecureContainer(String id) throws RemoteException; 1182 1183 /** 1184 * Call into MountService by PackageManager to notify that its done 1185 * processing the media status update request. 1186 */ 1187 public void finishMediaUpdate() throws RemoteException; 1188 1189 /** 1190 * Format external storage given a mount point. Returns an int consistent 1191 * with MountServiceResultCode 1192 */ 1193 public int formatVolume(String mountPoint) throws RemoteException; 1194 1195 /** 1196 * Gets the path to the mounted Opaque Binary Blob (OBB). 1197 */ 1198 public String getMountedObbPath(String rawPath) throws RemoteException; 1199 1200 /** 1201 * Gets an Array of currently known secure container IDs 1202 */ 1203 public String[] getSecureContainerList() throws RemoteException; 1204 1205 /* 1206 * Returns the filesystem path of a mounted secure container. 1207 */ 1208 public String getSecureContainerPath(String id) throws RemoteException; 1209 1210 /** 1211 * Returns an array of pids with open files on the specified path. 1212 */ 1213 public int[] getStorageUsers(String path) throws RemoteException; 1214 1215 /** 1216 * Gets the state of a volume via its mountpoint. 1217 */ 1218 public String getVolumeState(String mountPoint) throws RemoteException; 1219 1220 /** 1221 * Checks whether the specified Opaque Binary Blob (OBB) is mounted 1222 * somewhere. 1223 */ 1224 public boolean isObbMounted(String rawPath) throws RemoteException; 1225 1226 /* 1227 * Returns true if the specified container is mounted 1228 */ 1229 public boolean isSecureContainerMounted(String id) throws RemoteException; 1230 1231 /** 1232 * Returns true if a USB mass storage host is connected 1233 */ 1234 public boolean isUsbMassStorageConnected() throws RemoteException; 1235 1236 /** 1237 * Returns true if a USB mass storage host is enabled (media is shared) 1238 */ 1239 public boolean isUsbMassStorageEnabled() throws RemoteException; 1240 1241 /** 1242 * Mounts an Opaque Binary Blob (OBB) with the specified decryption key and 1243 * only allows the calling process's UID access to the contents. 1244 * MountService will call back to the supplied IObbActionListener to inform 1245 * it of the terminal state of the call. 1246 */ 1247 public void mountObb(String rawPath, String canonicalPath, String key, 1248 IObbActionListener token, int nonce) throws RemoteException; 1249 1250 /* 1251 * Mount a secure container with the specified key and owner UID. Returns an 1252 * int consistent with MountServiceResultCode 1253 */ 1254 public int mountSecureContainer(String id, String key, int ownerUid) throws RemoteException; 1255 1256 /** 1257 * Mount external storage at given mount point. Returns an int consistent 1258 * with MountServiceResultCode 1259 */ 1260 public int mountVolume(String mountPoint) throws RemoteException; 1261 1262 /** 1263 * Registers an IMountServiceListener for receiving async notifications. 1264 */ 1265 public void registerListener(IMountServiceListener listener) throws RemoteException; 1266 1267 /* 1268 * Rename an unmounted secure container. Returns an int consistent with 1269 * MountServiceResultCode 1270 */ 1271 public int renameSecureContainer(String oldId, String newId) throws RemoteException; 1272 1273 /** 1274 * Enables / disables USB mass storage. The caller should check actual 1275 * status of enabling/disabling USB mass storage via StorageEventListener. 1276 */ 1277 public void setUsbMassStorageEnabled(boolean enable) throws RemoteException; 1278 1279 /** 1280 * Shuts down the MountService and gracefully unmounts all external media. 1281 * Invokes call back once the shutdown is complete. 1282 */ 1283 public void shutdown(IMountShutdownObserver observer) throws RemoteException; 1284 1285 /** 1286 * Unmounts an Opaque Binary Blob (OBB). When the force flag is specified, 1287 * any program using it will be forcibly killed to unmount the image. 1288 * MountService will call back to the supplied IObbActionListener to inform 1289 * it of the terminal state of the call. 1290 */ 1291 public void unmountObb(String rawPath, boolean force, IObbActionListener token, int nonce) 1292 throws RemoteException; 1293 1294 /* 1295 * Unount a secure container. Returns an int consistent with 1296 * MountServiceResultCode 1297 */ 1298 public int unmountSecureContainer(String id, boolean force) throws RemoteException; 1299 1300 /** 1301 * Safely unmount external storage at given mount point. The unmount is an 1302 * asynchronous operation. Applications should register StorageEventListener 1303 * for storage related status changes. 1304 * @param mountPoint the mount point 1305 * @param force whether or not to forcefully unmount it (e.g. even if programs are using this 1306 * data currently) 1307 * @param removeEncryption whether or not encryption mapping should be removed from the volume. 1308 * This value implies {@code force}. 1309 */ 1310 public void unmountVolume(String mountPoint, boolean force, boolean removeEncryption) 1311 throws RemoteException; 1312 1313 /** 1314 * Unregisters an IMountServiceListener 1315 */ 1316 public void unregisterListener(IMountServiceListener listener) throws RemoteException; 1317 1318 /** 1319 * Returns whether or not the external storage is emulated. 1320 */ 1321 public boolean isExternalStorageEmulated() throws RemoteException; 1322 1323 /** The volume is not encrypted. */ 1324 static final int ENCRYPTION_STATE_NONE = 1; 1325 /** The volume has been encrypted succesfully. */ 1326 static final int ENCRYPTION_STATE_OK = 0; 1327 /** The volume is in a bad state. */ 1328 static final int ENCRYPTION_STATE_ERROR_UNKNOWN = -1; 1329 /** The volume is in a bad state - partially encrypted. Data is likely irrecoverable. */ 1330 static final int ENCRYPTION_STATE_ERROR_INCOMPLETE = -2; 1331 1332 /** 1333 * Determines the encryption state of the volume. 1334 * @return a numerical value. See {@code ENCRYPTION_STATE_*} for possible values. 1335 */ 1336 public int getEncryptionState() throws RemoteException; 1337 1338 /** 1339 * Decrypts any encrypted volumes. 1340 */ 1341 public int decryptStorage(String password) throws RemoteException; 1342 1343 /** 1344 * Encrypts storage. 1345 */ 1346 public int encryptStorage(String password) throws RemoteException; 1347 1348 /** 1349 * Changes the encryption password. 1350 */ 1351 public int changeEncryptionPassword(String password) throws RemoteException; 1352 1353 /** 1354 * Verify the encryption password against the stored volume. This method 1355 * may only be called by the system process. 1356 */ 1357 public int verifyEncryptionPassword(String password) throws RemoteException; 1358 1359 /** 1360 * Returns list of all mountable volumes. 1361 */ 1362 public StorageVolume[] getVolumeList() throws RemoteException; 1363 1364 /** 1365 * Gets the path on the filesystem for the ASEC container itself. 1366 * 1367 * @param cid ASEC container ID 1368 * @return path to filesystem or {@code null} if it's not found 1369 * @throws RemoteException 1370 */ 1371 public String getSecureContainerFilesystemPath(String cid) throws RemoteException; 1372 1373 /* 1374 * Fix permissions in a container which has just been created and populated. 1375 * Returns an int consistent with MountServiceResultCode 1376 */ 1377 public int fixPermissionsSecureContainer(String id, int gid, String filename) 1378 throws RemoteException; 1379 } 1380