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