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