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