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 };
52 
53 class BpMountService: public BpInterface<IMountService>
54 {
55 public:
BpMountService(const sp<IBinder> & impl)56     explicit BpMountService(const sp<IBinder>& impl)
57         : BpInterface<IMountService>(impl)
58     {
59     }
60 
registerListener(const sp<IMountServiceListener> & listener)61     virtual void registerListener(const sp<IMountServiceListener>& listener)
62     {
63         Parcel data, reply;
64         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
65         data.writeStrongBinder(IInterface::asBinder(listener));
66         if (remote()->transact(TRANSACTION_registerListener, data, &reply) != NO_ERROR) {
67             ALOGD("registerListener could not contact remote\n");
68             return;
69         }
70         int32_t err = reply.readExceptionCode();
71         if (err < 0) {
72             ALOGD("registerListener caught exception %d\n", err);
73             return;
74         }
75     }
76 
unregisterListener(const sp<IMountServiceListener> & listener)77     virtual void unregisterListener(const sp<IMountServiceListener>& listener)
78     {
79         Parcel data, reply;
80         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
81         data.writeStrongBinder(IInterface::asBinder(listener));
82         if (remote()->transact(TRANSACTION_unregisterListener, data, &reply) != NO_ERROR) {
83             ALOGD("unregisterListener could not contact remote\n");
84             return;
85         }
86         int32_t err = reply.readExceptionCode();
87         if (err < 0) {
88             ALOGD("unregisterListener caught exception %d\n", err);
89             return;
90         }
91     }
92 
isUsbMassStorageConnected()93     virtual bool isUsbMassStorageConnected()
94     {
95         Parcel data, reply;
96         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
97         if (remote()->transact(TRANSACTION_isUsbMassStorageConnected, data, &reply) != NO_ERROR) {
98             ALOGD("isUsbMassStorageConnected could not contact remote\n");
99             return false;
100         }
101         int32_t err = reply.readExceptionCode();
102         if (err < 0) {
103             ALOGD("isUsbMassStorageConnected caught exception %d\n", err);
104             return false;
105         }
106         return reply.readInt32() != 0;
107     }
108 
setUsbMassStorageEnabled(const bool enable)109     virtual void setUsbMassStorageEnabled(const bool enable)
110     {
111         Parcel data, reply;
112         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
113         data.writeInt32(enable != 0);
114         if (remote()->transact(TRANSACTION_setUsbMassStorageEnabled, data, &reply) != NO_ERROR) {
115             ALOGD("setUsbMassStorageEnabled could not contact remote\n");
116             return;
117         }
118         int32_t err = reply.readExceptionCode();
119         if (err < 0) {
120             ALOGD("setUsbMassStorageEnabled caught exception %d\n", err);
121             return;
122         }
123     }
124 
isUsbMassStorageEnabled()125     virtual bool isUsbMassStorageEnabled()
126     {
127         Parcel data, reply;
128         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
129         if (remote()->transact(TRANSACTION_isUsbMassStorageEnabled, data, &reply) != NO_ERROR) {
130             ALOGD("isUsbMassStorageEnabled could not contact remote\n");
131             return false;
132         }
133         int32_t err = reply.readExceptionCode();
134         if (err < 0) {
135             ALOGD("isUsbMassStorageEnabled caught exception %d\n", err);
136             return false;
137         }
138         return reply.readInt32() != 0;
139     }
140 
mountVolume(const String16 & mountPoint)141     int32_t mountVolume(const String16& mountPoint)
142     {
143         Parcel data, reply;
144         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
145         data.writeString16(mountPoint);
146         if (remote()->transact(TRANSACTION_mountVolume, data, &reply) != NO_ERROR) {
147             ALOGD("mountVolume could not contact remote\n");
148             return -1;
149         }
150         int32_t err = reply.readExceptionCode();
151         if (err < 0) {
152             ALOGD("mountVolume caught exception %d\n", err);
153             return err;
154         }
155         return reply.readInt32();
156     }
157 
unmountVolume(const String16 & mountPoint,const bool force,const bool removeEncryption)158     int32_t unmountVolume(const String16& mountPoint, const bool force, const bool removeEncryption)
159     {
160         Parcel data, reply;
161         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
162         data.writeString16(mountPoint);
163         data.writeInt32(force ? 1 : 0);
164         data.writeInt32(removeEncryption ? 1 : 0);
165         if (remote()->transact(TRANSACTION_unmountVolume, data, &reply) != NO_ERROR) {
166             ALOGD("unmountVolume could not contact remote\n");
167             return -1;
168         }
169         int32_t err = reply.readExceptionCode();
170         if (err < 0) {
171             ALOGD("unmountVolume caught exception %d\n", err);
172             return err;
173         }
174         return reply.readInt32();
175     }
176 
formatVolume(const String16 & mountPoint)177     int32_t formatVolume(const String16& mountPoint)
178     {
179         Parcel data, reply;
180         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
181         data.writeString16(mountPoint);
182         if (remote()->transact(TRANSACTION_formatVolume, data, &reply) != NO_ERROR) {
183             ALOGD("formatVolume could not contact remote\n");
184             return -1;
185         }
186         int32_t err = reply.readExceptionCode();
187         if (err < 0) {
188             ALOGD("formatVolume caught exception %d\n", err);
189             return err;
190         }
191         return reply.readInt32();
192     }
193 
getStorageUsers(const String16 & mountPoint,int32_t ** users)194     int32_t getStorageUsers(const String16& mountPoint, int32_t** users)
195     {
196         Parcel data, reply;
197         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
198         data.writeString16(mountPoint);
199         if (remote()->transact(TRANSACTION_getStorageUsers, data, &reply) != NO_ERROR) {
200             ALOGD("getStorageUsers could not contact remote\n");
201             return -1;
202         }
203         int32_t err = reply.readExceptionCode();
204         if (err < 0) {
205             ALOGD("getStorageUsers caught exception %d\n", err);
206             return err;
207         }
208         int32_t numUsersI = reply.readInt32();
209         uint32_t numUsers;
210         if (numUsersI < 0) {
211             ALOGW("Number of users is negative: %d\n", numUsersI);
212             numUsers = 0;
213         } else {
214             numUsers = static_cast<uint32_t>(numUsersI);
215         }
216         *users = (int32_t*)malloc(sizeof(int32_t)*numUsers);
217         for (size_t i = 0; i < numUsers; i++) {
218             **users++ = reply.readInt32();
219         }
220         return static_cast<int32_t>(numUsers);
221     }
222 
getVolumeState(const String16 & mountPoint)223     int32_t getVolumeState(const String16& mountPoint)
224     {
225         Parcel data, reply;
226         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
227         data.writeString16(mountPoint);
228         if (remote()->transact(TRANSACTION_getVolumeState, data, &reply) != NO_ERROR) {
229             ALOGD("getVolumeState could not contact remote\n");
230             return -1;
231         }
232         int32_t err = reply.readExceptionCode();
233         if (err < 0) {
234             ALOGD("getVolumeState caught exception %d\n", err);
235             return err;
236         }
237         return reply.readInt32();
238     }
239 
createSecureContainer(const String16 & id,const int32_t sizeMb,const String16 & fstype,const String16 & key,const int32_t ownerUid)240     int32_t createSecureContainer(const String16& id, const int32_t sizeMb, const String16& fstype,
241             const String16& key, const int32_t ownerUid)
242     {
243         Parcel data, reply;
244         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
245         data.writeString16(id);
246         data.writeInt32(sizeMb);
247         data.writeString16(fstype);
248         data.writeString16(key);
249         data.writeInt32(ownerUid);
250         if (remote()->transact(TRANSACTION_createSecureContainer, data, &reply) != NO_ERROR) {
251             ALOGD("createSecureContainer could not contact remote\n");
252             return -1;
253         }
254         int32_t err = reply.readExceptionCode();
255         if (err < 0) {
256             ALOGD("createSecureContainer caught exception %d\n", err);
257             return err;
258         }
259         return reply.readInt32();
260     }
261 
finalizeSecureContainer(const String16 & id)262     int32_t finalizeSecureContainer(const String16& id)
263     {
264         Parcel data, reply;
265         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
266         data.writeString16(id);
267         if (remote()->transact(TRANSACTION_finalizeSecureContainer, data, &reply) != NO_ERROR) {
268             ALOGD("finalizeSecureContainer couldn't call remote\n");
269             return -1;
270         }
271         int32_t err = reply.readExceptionCode();
272         if (err < 0) {
273             ALOGD("finalizeSecureContainer caught exception %d\n", err);
274             return err;
275         }
276         return reply.readInt32();
277     }
278 
destroySecureContainer(const String16 & id)279     int32_t destroySecureContainer(const String16& id)
280     {
281         Parcel data, reply;
282         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
283         data.writeString16(id);
284         if (remote()->transact(TRANSACTION_destroySecureContainer, data, &reply) != NO_ERROR) {
285             ALOGD("destroySecureContainer couldn't call remote");
286             return -1;
287         }
288         int32_t err = reply.readExceptionCode();
289         if (err < 0) {
290             ALOGD("destroySecureContainer caught exception %d\n", err);
291             return err;
292         }
293         return reply.readInt32();
294     }
295 
mountSecureContainer(const String16 & id,const String16 & key,const int32_t ownerUid)296     int32_t mountSecureContainer(const String16& id, const String16& key, const int32_t ownerUid)
297     {
298         Parcel data, reply;
299         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
300         data.writeString16(id);
301         data.writeString16(key);
302         data.writeInt32(ownerUid);
303         // Assume read-only
304         data.writeInt32(1);
305         if (remote()->transact(TRANSACTION_mountSecureContainer, data, &reply) != NO_ERROR) {
306             ALOGD("mountSecureContainer couldn't call remote");
307             return -1;
308         }
309         int32_t err = reply.readExceptionCode(); // What to do...
310         if (err < 0) {
311             ALOGD("mountSecureContainer caught exception %d\n", err);
312             return err;
313         }
314         return reply.readInt32();
315     }
316 
unmountSecureContainer(const String16 & id,const bool force)317     int32_t unmountSecureContainer(const String16& id, const bool force)
318     {
319         Parcel data, reply;
320         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
321         data.writeString16(id);
322         data.writeInt32(force ? 1 : 0);
323         if (remote()->transact(TRANSACTION_getSecureContainerPath, data, &reply) != NO_ERROR) {
324             ALOGD("unmountSecureContainer couldn't call remote");
325             return -1;
326         }
327         int32_t err = reply.readExceptionCode(); // What to do...
328         if (err < 0) {
329             ALOGD("unmountSecureContainer caught exception %d\n", err);
330             return err;
331         }
332         return reply.readInt32();
333     }
334 
isSecureContainerMounted(const String16 & id)335     bool isSecureContainerMounted(const String16& id)
336     {
337         Parcel data, reply;
338         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
339         data.writeString16(id);
340         if (remote()->transact(TRANSACTION_isSecureContainerMounted, data, &reply) != NO_ERROR) {
341             ALOGD("isSecureContainerMounted couldn't call remote");
342             return false;
343         }
344         int32_t err = reply.readExceptionCode(); // What to do...
345         if (err < 0) {
346             ALOGD("isSecureContainerMounted caught exception %d\n", err);
347             return false;
348         }
349         return reply.readInt32() != 0;
350     }
351 
renameSecureContainer(const String16 & oldId,const String16 & newId)352     int32_t renameSecureContainer(const String16& oldId, const String16& newId)
353     {
354         Parcel data, reply;
355         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
356         data.writeString16(oldId);
357         data.writeString16(newId);
358         if (remote()->transact(TRANSACTION_renameSecureContainer, data, &reply) != NO_ERROR) {
359             ALOGD("renameSecureContainer couldn't call remote");
360             return -1;
361         }
362         int32_t err = reply.readExceptionCode(); // What to do...
363         if (err < 0) {
364             ALOGD("renameSecureContainer caught exception %d\n", err);
365             return err;
366         }
367         return reply.readInt32();
368     }
369 
getSecureContainerPath(const String16 & id,String16 & path)370     bool getSecureContainerPath(const String16& id, String16& path)
371     {
372         Parcel data, reply;
373         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
374         data.writeString16(id);
375         if (remote()->transact(TRANSACTION_getSecureContainerPath, data, &reply) != NO_ERROR) {
376             ALOGD("getSecureContainerPath couldn't call remote");
377             return false;
378         }
379         int32_t err = reply.readExceptionCode(); // What to do...
380         if (err < 0) {
381             ALOGD("getSecureContainerPath caught exception %d\n", err);
382             return false;
383         }
384         path = reply.readString16();
385         return true;
386     }
387 
getSecureContainerList(const String16 & id,String16 * & containers)388     int32_t getSecureContainerList(const String16& id, String16*& containers)
389     {
390         Parcel data, reply;
391         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
392         data.writeString16(id);
393         if (remote()->transact(TRANSACTION_getSecureContainerList, data, &reply) != NO_ERROR) {
394             ALOGD("getSecureContainerList couldn't call remote");
395             return -1;
396         }
397         int32_t err = reply.readExceptionCode();
398         if (err < 0) {
399             ALOGD("getSecureContainerList caught exception %d\n", err);
400             return err;
401         }
402         const int32_t numStrings = reply.readInt32();
403         containers = new String16[numStrings];
404         for (int i = 0; i < numStrings; i++) {
405             containers[i] = reply.readString16();
406         }
407         return numStrings;
408     }
409 
shutdown(const sp<IMountShutdownObserver> & observer)410     void shutdown(const sp<IMountShutdownObserver>& observer)
411     {
412         Parcel data, reply;
413         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
414         data.writeStrongBinder(IInterface::asBinder(observer));
415         if (remote()->transact(TRANSACTION_shutdown, data, &reply) != NO_ERROR) {
416             ALOGD("shutdown could not contact remote\n");
417             return;
418         }
419         int32_t err = reply.readExceptionCode();
420         if (err < 0) {
421             ALOGD("shutdown caught exception %d\n", err);
422             return;
423         }
424         reply.readExceptionCode();
425     }
426 
finishMediaUpdate()427     void finishMediaUpdate()
428     {
429         Parcel data, reply;
430         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
431         if (remote()->transact(TRANSACTION_finishMediaUpdate, data, &reply) != NO_ERROR) {
432             ALOGD("finishMediaUpdate could not contact remote\n");
433             return;
434         }
435         int32_t err = reply.readExceptionCode();
436         if (err < 0) {
437             ALOGD("finishMediaUpdate caught exception %d\n", err);
438             return;
439         }
440         reply.readExceptionCode();
441     }
442 
mountObb(const String16 & rawPath,const String16 & canonicalPath,const sp<IObbActionListener> & token,int32_t nonce,const sp<ObbInfo> & obbInfo)443     void mountObb(const String16& rawPath, const String16& canonicalPath,
444             const sp<IObbActionListener>& token, int32_t nonce, const sp<ObbInfo>& obbInfo)
445     {
446         Parcel data, reply;
447         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
448         data.writeString16(rawPath);
449         data.writeString16(canonicalPath);
450         data.writeStrongBinder(IInterface::asBinder(token));
451         data.writeInt32(nonce);
452         obbInfo->writeToParcel(&data);
453         if (remote()->transact(TRANSACTION_mountObb, data, &reply) != NO_ERROR) {
454             ALOGD("mountObb could not contact remote\n");
455             return;
456         }
457         int32_t err = reply.readExceptionCode();
458         if (err < 0) {
459             ALOGD("mountObb caught exception %d\n", err);
460             return;
461         }
462     }
463 
unmountObb(const String16 & filename,const bool force,const sp<IObbActionListener> & token,const int32_t nonce)464     void unmountObb(const String16& filename, const bool force,
465             const sp<IObbActionListener>& token, const int32_t nonce)
466     {
467         Parcel data, reply;
468         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
469         data.writeString16(filename);
470         data.writeInt32(force ? 1 : 0);
471         data.writeStrongBinder(IInterface::asBinder(token));
472         data.writeInt32(nonce);
473         if (remote()->transact(TRANSACTION_unmountObb, data, &reply) != NO_ERROR) {
474             ALOGD("unmountObb could not contact remote\n");
475             return;
476         }
477         int32_t err = reply.readExceptionCode();
478         if (err < 0) {
479             ALOGD("unmountObb caught exception %d\n", err);
480             return;
481         }
482     }
483 
isObbMounted(const String16 & filename)484     bool isObbMounted(const String16& filename)
485     {
486         Parcel data, reply;
487         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
488         data.writeString16(filename);
489         if (remote()->transact(TRANSACTION_isObbMounted, data, &reply) != NO_ERROR) {
490             ALOGD("isObbMounted could not contact remote\n");
491             return false;
492         }
493         int32_t err = reply.readExceptionCode();
494         if (err < 0) {
495             ALOGD("isObbMounted caught exception %d\n", err);
496             return false;
497         }
498         return reply.readInt32() != 0;
499     }
500 
getMountedObbPath(const String16 & filename,String16 & path)501     bool getMountedObbPath(const String16& filename, String16& path)
502     {
503         Parcel data, reply;
504         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
505         data.writeString16(filename);
506         if (remote()->transact(TRANSACTION_getMountedObbPath, data, &reply) != NO_ERROR) {
507             ALOGD("getMountedObbPath could not contact remote\n");
508             return false;
509         }
510         int32_t err = reply.readExceptionCode();
511         if (err < 0) {
512             ALOGD("getMountedObbPath caught exception %d\n", err);
513             return false;
514         }
515         path = reply.readString16();
516         return true;
517     }
518 };
519 
520 IMPLEMENT_META_INTERFACE(MountService, "android.os.storage.IStorageManager")
521 
522 // ----------------------------------------------------------------------
523 
524 }
525