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