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            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
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            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
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
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
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
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
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
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
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        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            ALOGD("getVolumeState could not contact remote\n");
225            return -1;
226        }
227        int32_t err = reply.readExceptionCode();
228        if (err < 0) {
229            ALOGD("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            ALOGD("createSecureContainer could not contact remote\n");
247            return -1;
248        }
249        int32_t err = reply.readExceptionCode();
250        if (err < 0) {
251            ALOGD("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            ALOGD("finalizeSecureContainer couldn't call remote\n");
264            return -1;
265        }
266        int32_t err = reply.readExceptionCode();
267        if (err < 0) {
268            ALOGD("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            ALOGD("destroySecureContainer couldn't call remote");
281            return -1;
282        }
283        int32_t err = reply.readExceptionCode();
284        if (err < 0) {
285            ALOGD("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            ALOGD("mountSecureContainer couldn't call remote");
300            return -1;
301        }
302        int32_t err = reply.readExceptionCode(); // What to do...
303        if (err < 0) {
304            ALOGD("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            ALOGD("unmountSecureContainer couldn't call remote");
318            return -1;
319        }
320        int32_t err = reply.readExceptionCode(); // What to do...
321        if (err < 0) {
322            ALOGD("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            ALOGD("isSecureContainerMounted couldn't call remote");
335            return false;
336        }
337        int32_t err = reply.readExceptionCode(); // What to do...
338        if (err < 0) {
339            ALOGD("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            ALOGD("renameSecureContainer couldn't call remote");
353            return -1;
354        }
355        int32_t err = reply.readExceptionCode(); // What to do...
356        if (err < 0) {
357            ALOGD("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            ALOGD("getSecureContainerPath couldn't call remote");
370            return false;
371        }
372        int32_t err = reply.readExceptionCode(); // What to do...
373        if (err < 0) {
374            ALOGD("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            ALOGD("getSecureContainerList couldn't call remote");
388            return -1;
389        }
390        int32_t err = reply.readExceptionCode();
391        if (err < 0) {
392            ALOGD("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            ALOGD("shutdown could not contact remote\n");
410            return;
411        }
412        int32_t err = reply.readExceptionCode();
413        if (err < 0) {
414            ALOGD("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            ALOGD("finishMediaUpdate could not contact remote\n");
426            return;
427        }
428        int32_t err = reply.readExceptionCode();
429        if (err < 0) {
430            ALOGD("finishMediaUpdate caught exception %d\n", err);
431            return;
432        }
433        reply.readExceptionCode();
434    }
435
436    void mountObb(const String16& rawPath, const String16& canonicalPath, const String16& key,
437            const sp<IObbActionListener>& token, int32_t nonce)
438    {
439        Parcel data, reply;
440        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
441        data.writeString16(rawPath);
442        data.writeString16(canonicalPath);
443        data.writeString16(key);
444        data.writeStrongBinder(token->asBinder());
445        data.writeInt32(nonce);
446        if (remote()->transact(TRANSACTION_mountObb, data, &reply) != NO_ERROR) {
447            ALOGD("mountObb could not contact remote\n");
448            return;
449        }
450        int32_t err = reply.readExceptionCode();
451        if (err < 0) {
452            ALOGD("mountObb caught exception %d\n", err);
453            return;
454        }
455    }
456
457    void unmountObb(const String16& filename, const bool force,
458            const sp<IObbActionListener>& token, const int32_t nonce)
459    {
460        Parcel data, reply;
461        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
462        data.writeString16(filename);
463        data.writeInt32(force ? 1 : 0);
464        data.writeStrongBinder(token->asBinder());
465        data.writeInt32(nonce);
466        if (remote()->transact(TRANSACTION_unmountObb, data, &reply) != NO_ERROR) {
467            ALOGD("unmountObb could not contact remote\n");
468            return;
469        }
470        int32_t err = reply.readExceptionCode();
471        if (err < 0) {
472            ALOGD("unmountObb caught exception %d\n", err);
473            return;
474        }
475    }
476
477    bool isObbMounted(const String16& filename)
478    {
479        Parcel data, reply;
480        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
481        data.writeString16(filename);
482        if (remote()->transact(TRANSACTION_isObbMounted, data, &reply) != NO_ERROR) {
483            ALOGD("isObbMounted could not contact remote\n");
484            return false;
485        }
486        int32_t err = reply.readExceptionCode();
487        if (err < 0) {
488            ALOGD("isObbMounted caught exception %d\n", err);
489            return false;
490        }
491        return reply.readInt32() != 0;
492    }
493
494    bool getMountedObbPath(const String16& filename, String16& path)
495    {
496        Parcel data, reply;
497        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
498        data.writeString16(filename);
499        if (remote()->transact(TRANSACTION_getMountedObbPath, data, &reply) != NO_ERROR) {
500            ALOGD("getMountedObbPath could not contact remote\n");
501            return false;
502        }
503        int32_t err = reply.readExceptionCode();
504        if (err < 0) {
505            ALOGD("getMountedObbPath caught exception %d\n", err);
506            return false;
507        }
508        path = reply.readString16();
509        return true;
510    }
511
512    int32_t decryptStorage(const String16& password)
513    {
514        Parcel data, reply;
515        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
516        data.writeString16(password);
517        if (remote()->transact(TRANSACTION_decryptStorage, data, &reply) != NO_ERROR) {
518            ALOGD("decryptStorage could not contact remote\n");
519            return -1;
520        }
521        int32_t err = reply.readExceptionCode();
522        if (err < 0) {
523            ALOGD("decryptStorage caught exception %d\n", err);
524            return err;
525        }
526        return reply.readInt32();
527    }
528
529    int32_t encryptStorage(const String16& password)
530    {
531        Parcel data, reply;
532        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
533        data.writeString16(password);
534        if (remote()->transact(TRANSACTION_encryptStorage, data, &reply) != NO_ERROR) {
535            ALOGD("encryptStorage could not contact remote\n");
536            return -1;
537        }
538        int32_t err = reply.readExceptionCode();
539        if (err < 0) {
540            ALOGD("encryptStorage caught exception %d\n", err);
541            return err;
542        }
543        return reply.readInt32();
544    }
545};
546
547IMPLEMENT_META_INTERFACE(MountService, "IMountService");
548
549// ----------------------------------------------------------------------
550
551};
552