1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "IMountService"
18 
19 #include <storage/IMountService.h>
20 #include <binder/Parcel.h>
21 
22 namespace android {
23 
24 enum {
25     TRANSACTION_registerListener = IBinder::FIRST_CALL_TRANSACTION,
26     TRANSACTION_unregisterListener,
27     TRANSACTION_isUsbMassStorageConnected,
28     TRANSACTION_setUsbMassStorageEnabled,
29     TRANSACTION_isUsbMassStorageEnabled,
30     TRANSACTION_mountVolume,
31     TRANSACTION_unmountVolume,
32     TRANSACTION_formatVolume,
33     TRANSACTION_getStorageUsers,
34     TRANSACTION_getVolumeState,
35     TRANSACTION_createSecureContainer,
36     TRANSACTION_finalizeSecureContainer,
37     TRANSACTION_destroySecureContainer,
38     TRANSACTION_mountSecureContainer,
39     TRANSACTION_unmountSecureContainer,
40     TRANSACTION_isSecureContainerMounted,
41     TRANSACTION_renameSecureContainer,
42     TRANSACTION_getSecureContainerPath,
43     TRANSACTION_getSecureContainerList,
44     TRANSACTION_shutdown,
45     TRANSACTION_finishMediaUpdate,
46     TRANSACTION_mountObb,
47     TRANSACTION_unmountObb,
48     TRANSACTION_isObbMounted,
49     TRANSACTION_getMountedObbPath,
50     TRANSACTION_isExternalStorageEmulated,
51     TRANSACTION_decryptStorage,
52     TRANSACTION_encryptStorage,
53 };
54 
55 class BpMountService: public BpInterface<IMountService>
56 {
57 public:
BpMountService(const sp<IBinder> & impl)58     explicit BpMountService(const sp<IBinder>& impl)
59         : BpInterface<IMountService>(impl)
60     {
61     }
62 
registerListener(const sp<IMountServiceListener> & listener)63     virtual void registerListener(const sp<IMountServiceListener>& listener)
64     {
65         Parcel data, reply;
66         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
67         data.writeStrongBinder(IInterface::asBinder(listener));
68         if (remote()->transact(TRANSACTION_registerListener, data, &reply) != NO_ERROR) {
69             ALOGD("registerListener could not contact remote\n");
70             return;
71         }
72         int32_t err = reply.readExceptionCode();
73         if (err < 0) {
74             ALOGD("registerListener caught exception %d\n", err);
75             return;
76         }
77     }
78 
unregisterListener(const sp<IMountServiceListener> & listener)79     virtual void unregisterListener(const sp<IMountServiceListener>& listener)
80     {
81         Parcel data, reply;
82         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
83         data.writeStrongBinder(IInterface::asBinder(listener));
84         if (remote()->transact(TRANSACTION_unregisterListener, data, &reply) != NO_ERROR) {
85             ALOGD("unregisterListener could not contact remote\n");
86             return;
87         }
88         int32_t err = reply.readExceptionCode();
89         if (err < 0) {
90             ALOGD("unregisterListener caught exception %d\n", err);
91             return;
92         }
93     }
94 
isUsbMassStorageConnected()95     virtual bool isUsbMassStorageConnected()
96     {
97         Parcel data, reply;
98         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
99         if (remote()->transact(TRANSACTION_isUsbMassStorageConnected, data, &reply) != NO_ERROR) {
100             ALOGD("isUsbMassStorageConnected could not contact remote\n");
101             return false;
102         }
103         int32_t err = reply.readExceptionCode();
104         if (err < 0) {
105             ALOGD("isUsbMassStorageConnected caught exception %d\n", err);
106             return false;
107         }
108         return reply.readInt32() != 0;
109     }
110 
setUsbMassStorageEnabled(const bool enable)111     virtual void setUsbMassStorageEnabled(const bool enable)
112     {
113         Parcel data, reply;
114         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
115         data.writeInt32(enable != 0);
116         if (remote()->transact(TRANSACTION_setUsbMassStorageEnabled, data, &reply) != NO_ERROR) {
117             ALOGD("setUsbMassStorageEnabled could not contact remote\n");
118             return;
119         }
120         int32_t err = reply.readExceptionCode();
121         if (err < 0) {
122             ALOGD("setUsbMassStorageEnabled caught exception %d\n", err);
123             return;
124         }
125     }
126 
isUsbMassStorageEnabled()127     virtual bool isUsbMassStorageEnabled()
128     {
129         Parcel data, reply;
130         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
131         if (remote()->transact(TRANSACTION_isUsbMassStorageEnabled, data, &reply) != NO_ERROR) {
132             ALOGD("isUsbMassStorageEnabled could not contact remote\n");
133             return false;
134         }
135         int32_t err = reply.readExceptionCode();
136         if (err < 0) {
137             ALOGD("isUsbMassStorageEnabled caught exception %d\n", err);
138             return false;
139         }
140         return reply.readInt32() != 0;
141     }
142 
mountVolume(const String16 & mountPoint)143     int32_t mountVolume(const String16& mountPoint)
144     {
145         Parcel data, reply;
146         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
147         data.writeString16(mountPoint);
148         if (remote()->transact(TRANSACTION_mountVolume, data, &reply) != NO_ERROR) {
149             ALOGD("mountVolume could not contact remote\n");
150             return -1;
151         }
152         int32_t err = reply.readExceptionCode();
153         if (err < 0) {
154             ALOGD("mountVolume caught exception %d\n", err);
155             return err;
156         }
157         return reply.readInt32();
158     }
159 
unmountVolume(const String16 & mountPoint,const bool force,const bool removeEncryption)160     int32_t unmountVolume(const String16& mountPoint, const bool force, const bool removeEncryption)
161     {
162         Parcel data, reply;
163         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
164         data.writeString16(mountPoint);
165         data.writeInt32(force ? 1 : 0);
166         data.writeInt32(removeEncryption ? 1 : 0);
167         if (remote()->transact(TRANSACTION_unmountVolume, data, &reply) != NO_ERROR) {
168             ALOGD("unmountVolume could not contact remote\n");
169             return -1;
170         }
171         int32_t err = reply.readExceptionCode();
172         if (err < 0) {
173             ALOGD("unmountVolume caught exception %d\n", err);
174             return err;
175         }
176         return reply.readInt32();
177     }
178 
formatVolume(const String16 & mountPoint)179     int32_t formatVolume(const String16& mountPoint)
180     {
181         Parcel data, reply;
182         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
183         data.writeString16(mountPoint);
184         if (remote()->transact(TRANSACTION_formatVolume, data, &reply) != NO_ERROR) {
185             ALOGD("formatVolume could not contact remote\n");
186             return -1;
187         }
188         int32_t err = reply.readExceptionCode();
189         if (err < 0) {
190             ALOGD("formatVolume caught exception %d\n", err);
191             return err;
192         }
193         return reply.readInt32();
194     }
195 
getStorageUsers(const String16 & mountPoint,int32_t ** users)196     int32_t getStorageUsers(const String16& mountPoint, int32_t** users)
197     {
198         Parcel data, reply;
199         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
200         data.writeString16(mountPoint);
201         if (remote()->transact(TRANSACTION_getStorageUsers, data, &reply) != NO_ERROR) {
202             ALOGD("getStorageUsers could not contact remote\n");
203             return -1;
204         }
205         int32_t err = reply.readExceptionCode();
206         if (err < 0) {
207             ALOGD("getStorageUsers caught exception %d\n", err);
208             return err;
209         }
210         int32_t numUsersI = reply.readInt32();
211         uint32_t numUsers;
212         if (numUsersI < 0) {
213             ALOGW("Number of users is negative: %d\n", numUsersI);
214             numUsers = 0;
215         } else {
216             numUsers = static_cast<uint32_t>(numUsersI);
217         }
218         *users = (int32_t*)malloc(sizeof(int32_t)*numUsers);
219         for (size_t i = 0; i < numUsers; i++) {
220             **users++ = reply.readInt32();
221         }
222         return static_cast<int32_t>(numUsers);
223     }
224 
getVolumeState(const String16 & mountPoint)225     int32_t getVolumeState(const String16& mountPoint)
226     {
227         Parcel data, reply;
228         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
229         data.writeString16(mountPoint);
230         if (remote()->transact(TRANSACTION_getVolumeState, data, &reply) != NO_ERROR) {
231             ALOGD("getVolumeState could not contact remote\n");
232             return -1;
233         }
234         int32_t err = reply.readExceptionCode();
235         if (err < 0) {
236             ALOGD("getVolumeState caught exception %d\n", err);
237             return err;
238         }
239         return reply.readInt32();
240     }
241 
createSecureContainer(const String16 & id,const int32_t sizeMb,const String16 & fstype,const String16 & key,const int32_t ownerUid)242     int32_t createSecureContainer(const String16& id, const int32_t sizeMb, const String16& fstype,
243             const String16& key, const int32_t ownerUid)
244     {
245         Parcel data, reply;
246         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
247         data.writeString16(id);
248         data.writeInt32(sizeMb);
249         data.writeString16(fstype);
250         data.writeString16(key);
251         data.writeInt32(ownerUid);
252         if (remote()->transact(TRANSACTION_createSecureContainer, data, &reply) != NO_ERROR) {
253             ALOGD("createSecureContainer could not contact remote\n");
254             return -1;
255         }
256         int32_t err = reply.readExceptionCode();
257         if (err < 0) {
258             ALOGD("createSecureContainer caught exception %d\n", err);
259             return err;
260         }
261         return reply.readInt32();
262     }
263 
finalizeSecureContainer(const String16 & id)264     int32_t finalizeSecureContainer(const String16& id)
265     {
266         Parcel data, reply;
267         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
268         data.writeString16(id);
269         if (remote()->transact(TRANSACTION_finalizeSecureContainer, data, &reply) != NO_ERROR) {
270             ALOGD("finalizeSecureContainer couldn't call remote\n");
271             return -1;
272         }
273         int32_t err = reply.readExceptionCode();
274         if (err < 0) {
275             ALOGD("finalizeSecureContainer caught exception %d\n", err);
276             return err;
277         }
278         return reply.readInt32();
279     }
280 
destroySecureContainer(const String16 & id)281     int32_t destroySecureContainer(const String16& id)
282     {
283         Parcel data, reply;
284         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
285         data.writeString16(id);
286         if (remote()->transact(TRANSACTION_destroySecureContainer, data, &reply) != NO_ERROR) {
287             ALOGD("destroySecureContainer couldn't call remote");
288             return -1;
289         }
290         int32_t err = reply.readExceptionCode();
291         if (err < 0) {
292             ALOGD("destroySecureContainer caught exception %d\n", err);
293             return err;
294         }
295         return reply.readInt32();
296     }
297 
mountSecureContainer(const String16 & id,const String16 & key,const int32_t ownerUid)298     int32_t mountSecureContainer(const String16& id, const String16& key, const int32_t ownerUid)
299     {
300         Parcel data, reply;
301         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
302         data.writeString16(id);
303         data.writeString16(key);
304         data.writeInt32(ownerUid);
305         // Assume read-only
306         data.writeInt32(1);
307         if (remote()->transact(TRANSACTION_mountSecureContainer, data, &reply) != NO_ERROR) {
308             ALOGD("mountSecureContainer couldn't call remote");
309             return -1;
310         }
311         int32_t err = reply.readExceptionCode(); // What to do...
312         if (err < 0) {
313             ALOGD("mountSecureContainer caught exception %d\n", err);
314             return err;
315         }
316         return reply.readInt32();
317     }
318 
unmountSecureContainer(const String16 & id,const bool force)319     int32_t unmountSecureContainer(const String16& id, const bool force)
320     {
321         Parcel data, reply;
322         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
323         data.writeString16(id);
324         data.writeInt32(force ? 1 : 0);
325         if (remote()->transact(TRANSACTION_getSecureContainerPath, data, &reply) != NO_ERROR) {
326             ALOGD("unmountSecureContainer couldn't call remote");
327             return -1;
328         }
329         int32_t err = reply.readExceptionCode(); // What to do...
330         if (err < 0) {
331             ALOGD("unmountSecureContainer caught exception %d\n", err);
332             return err;
333         }
334         return reply.readInt32();
335     }
336 
isSecureContainerMounted(const String16 & id)337     bool isSecureContainerMounted(const String16& id)
338     {
339         Parcel data, reply;
340         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
341         data.writeString16(id);
342         if (remote()->transact(TRANSACTION_isSecureContainerMounted, data, &reply) != NO_ERROR) {
343             ALOGD("isSecureContainerMounted couldn't call remote");
344             return false;
345         }
346         int32_t err = reply.readExceptionCode(); // What to do...
347         if (err < 0) {
348             ALOGD("isSecureContainerMounted caught exception %d\n", err);
349             return false;
350         }
351         return reply.readInt32() != 0;
352     }
353 
renameSecureContainer(const String16 & oldId,const String16 & newId)354     int32_t renameSecureContainer(const String16& oldId, const String16& newId)
355     {
356         Parcel data, reply;
357         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
358         data.writeString16(oldId);
359         data.writeString16(newId);
360         if (remote()->transact(TRANSACTION_renameSecureContainer, data, &reply) != NO_ERROR) {
361             ALOGD("renameSecureContainer couldn't call remote");
362             return -1;
363         }
364         int32_t err = reply.readExceptionCode(); // What to do...
365         if (err < 0) {
366             ALOGD("renameSecureContainer caught exception %d\n", err);
367             return err;
368         }
369         return reply.readInt32();
370     }
371 
getSecureContainerPath(const String16 & id,String16 & path)372     bool getSecureContainerPath(const String16& id, String16& path)
373     {
374         Parcel data, reply;
375         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
376         data.writeString16(id);
377         if (remote()->transact(TRANSACTION_getSecureContainerPath, data, &reply) != NO_ERROR) {
378             ALOGD("getSecureContainerPath couldn't call remote");
379             return false;
380         }
381         int32_t err = reply.readExceptionCode(); // What to do...
382         if (err < 0) {
383             ALOGD("getSecureContainerPath caught exception %d\n", err);
384             return false;
385         }
386         path = reply.readString16();
387         return true;
388     }
389 
getSecureContainerList(const String16 & id,String16 * & containers)390     int32_t getSecureContainerList(const String16& id, String16*& containers)
391     {
392         Parcel data, reply;
393         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
394         data.writeString16(id);
395         if (remote()->transact(TRANSACTION_getSecureContainerList, data, &reply) != NO_ERROR) {
396             ALOGD("getSecureContainerList couldn't call remote");
397             return -1;
398         }
399         int32_t err = reply.readExceptionCode();
400         if (err < 0) {
401             ALOGD("getSecureContainerList caught exception %d\n", err);
402             return err;
403         }
404         const int32_t numStrings = reply.readInt32();
405         containers = new String16[numStrings];
406         for (int i = 0; i < numStrings; i++) {
407             containers[i] = reply.readString16();
408         }
409         return numStrings;
410     }
411 
shutdown(const sp<IMountShutdownObserver> & observer)412     void shutdown(const sp<IMountShutdownObserver>& observer)
413     {
414         Parcel data, reply;
415         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
416         data.writeStrongBinder(IInterface::asBinder(observer));
417         if (remote()->transact(TRANSACTION_shutdown, data, &reply) != NO_ERROR) {
418             ALOGD("shutdown could not contact remote\n");
419             return;
420         }
421         int32_t err = reply.readExceptionCode();
422         if (err < 0) {
423             ALOGD("shutdown caught exception %d\n", err);
424             return;
425         }
426         reply.readExceptionCode();
427     }
428 
finishMediaUpdate()429     void finishMediaUpdate()
430     {
431         Parcel data, reply;
432         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
433         if (remote()->transact(TRANSACTION_finishMediaUpdate, data, &reply) != NO_ERROR) {
434             ALOGD("finishMediaUpdate could not contact remote\n");
435             return;
436         }
437         int32_t err = reply.readExceptionCode();
438         if (err < 0) {
439             ALOGD("finishMediaUpdate caught exception %d\n", err);
440             return;
441         }
442         reply.readExceptionCode();
443     }
444 
mountObb(const String16 & rawPath,const String16 & canonicalPath,const String16 & key,const sp<IObbActionListener> & token,int32_t nonce,const sp<ObbInfo> & obbInfo)445     void mountObb(const String16& rawPath, const String16& canonicalPath, const String16& key,
446             const sp<IObbActionListener>& token, int32_t nonce, const sp<ObbInfo>& obbInfo)
447     {
448         Parcel data, reply;
449         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
450         data.writeString16(rawPath);
451         data.writeString16(canonicalPath);
452         data.writeString16(key);
453         data.writeStrongBinder(IInterface::asBinder(token));
454         data.writeInt32(nonce);
455         obbInfo->writeToParcel(&data);
456         if (remote()->transact(TRANSACTION_mountObb, data, &reply) != NO_ERROR) {
457             ALOGD("mountObb could not contact remote\n");
458             return;
459         }
460         int32_t err = reply.readExceptionCode();
461         if (err < 0) {
462             ALOGD("mountObb caught exception %d\n", err);
463             return;
464         }
465     }
466 
unmountObb(const String16 & filename,const bool force,const sp<IObbActionListener> & token,const int32_t nonce)467     void unmountObb(const String16& filename, const bool force,
468             const sp<IObbActionListener>& token, const int32_t nonce)
469     {
470         Parcel data, reply;
471         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
472         data.writeString16(filename);
473         data.writeInt32(force ? 1 : 0);
474         data.writeStrongBinder(IInterface::asBinder(token));
475         data.writeInt32(nonce);
476         if (remote()->transact(TRANSACTION_unmountObb, data, &reply) != NO_ERROR) {
477             ALOGD("unmountObb could not contact remote\n");
478             return;
479         }
480         int32_t err = reply.readExceptionCode();
481         if (err < 0) {
482             ALOGD("unmountObb caught exception %d\n", err);
483             return;
484         }
485     }
486 
isObbMounted(const String16 & filename)487     bool isObbMounted(const String16& filename)
488     {
489         Parcel data, reply;
490         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
491         data.writeString16(filename);
492         if (remote()->transact(TRANSACTION_isObbMounted, data, &reply) != NO_ERROR) {
493             ALOGD("isObbMounted could not contact remote\n");
494             return false;
495         }
496         int32_t err = reply.readExceptionCode();
497         if (err < 0) {
498             ALOGD("isObbMounted caught exception %d\n", err);
499             return false;
500         }
501         return reply.readInt32() != 0;
502     }
503 
getMountedObbPath(const String16 & filename,String16 & path)504     bool getMountedObbPath(const String16& filename, String16& path)
505     {
506         Parcel data, reply;
507         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
508         data.writeString16(filename);
509         if (remote()->transact(TRANSACTION_getMountedObbPath, data, &reply) != NO_ERROR) {
510             ALOGD("getMountedObbPath could not contact remote\n");
511             return false;
512         }
513         int32_t err = reply.readExceptionCode();
514         if (err < 0) {
515             ALOGD("getMountedObbPath caught exception %d\n", err);
516             return false;
517         }
518         path = reply.readString16();
519         return true;
520     }
521 
decryptStorage(const String16 & password)522     int32_t decryptStorage(const String16& password)
523     {
524         Parcel data, reply;
525         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
526         data.writeString16(password);
527         if (remote()->transact(TRANSACTION_decryptStorage, data, &reply) != NO_ERROR) {
528             ALOGD("decryptStorage could not contact remote\n");
529             return -1;
530         }
531         int32_t err = reply.readExceptionCode();
532         if (err < 0) {
533             ALOGD("decryptStorage caught exception %d\n", err);
534             return err;
535         }
536         return reply.readInt32();
537     }
538 
encryptStorage(const String16 & password)539     int32_t encryptStorage(const String16& password)
540     {
541         Parcel data, reply;
542         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
543         data.writeString16(password);
544         if (remote()->transact(TRANSACTION_encryptStorage, data, &reply) != NO_ERROR) {
545             ALOGD("encryptStorage could not contact remote\n");
546             return -1;
547         }
548         int32_t err = reply.readExceptionCode();
549         if (err < 0) {
550             ALOGD("encryptStorage caught exception %d\n", err);
551             return err;
552         }
553         return reply.readInt32();
554     }
555 };
556 
557 IMPLEMENT_META_INTERFACE(MountService, "android.os.storage.IStorageManager")
558 
559 // ----------------------------------------------------------------------
560 
561 }
562