OSDN Git Service

Don't crash when primary volume is null in AppCollector.
[android-x86/frameworks-base.git] / libs / storage / IMountService.cpp
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:
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(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
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
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         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
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
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
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
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
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
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
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
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
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
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
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
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
445     void mountObb(const String16& rawPath, const String16& canonicalPath, const String16& key,
446             const sp<IObbActionListener>& token, int32_t nonce)
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         if (remote()->transact(TRANSACTION_mountObb, data, &reply) != NO_ERROR) {
456             ALOGD("mountObb could not contact remote\n");
457             return;
458         }
459         int32_t err = reply.readExceptionCode();
460         if (err < 0) {
461             ALOGD("mountObb caught exception %d\n", err);
462             return;
463         }
464     }
465
466     void unmountObb(const String16& filename, const bool force,
467             const sp<IObbActionListener>& token, const int32_t nonce)
468     {
469         Parcel data, reply;
470         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
471         data.writeString16(filename);
472         data.writeInt32(force ? 1 : 0);
473         data.writeStrongBinder(IInterface::asBinder(token));
474         data.writeInt32(nonce);
475         if (remote()->transact(TRANSACTION_unmountObb, data, &reply) != NO_ERROR) {
476             ALOGD("unmountObb could not contact remote\n");
477             return;
478         }
479         int32_t err = reply.readExceptionCode();
480         if (err < 0) {
481             ALOGD("unmountObb caught exception %d\n", err);
482             return;
483         }
484     }
485
486     bool isObbMounted(const String16& filename)
487     {
488         Parcel data, reply;
489         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
490         data.writeString16(filename);
491         if (remote()->transact(TRANSACTION_isObbMounted, data, &reply) != NO_ERROR) {
492             ALOGD("isObbMounted could not contact remote\n");
493             return false;
494         }
495         int32_t err = reply.readExceptionCode();
496         if (err < 0) {
497             ALOGD("isObbMounted caught exception %d\n", err);
498             return false;
499         }
500         return reply.readInt32() != 0;
501     }
502
503     bool getMountedObbPath(const String16& filename, String16& path)
504     {
505         Parcel data, reply;
506         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
507         data.writeString16(filename);
508         if (remote()->transact(TRANSACTION_getMountedObbPath, data, &reply) != NO_ERROR) {
509             ALOGD("getMountedObbPath could not contact remote\n");
510             return false;
511         }
512         int32_t err = reply.readExceptionCode();
513         if (err < 0) {
514             ALOGD("getMountedObbPath caught exception %d\n", err);
515             return false;
516         }
517         path = reply.readString16();
518         return true;
519     }
520
521     int32_t decryptStorage(const String16& password)
522     {
523         Parcel data, reply;
524         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
525         data.writeString16(password);
526         if (remote()->transact(TRANSACTION_decryptStorage, data, &reply) != NO_ERROR) {
527             ALOGD("decryptStorage could not contact remote\n");
528             return -1;
529         }
530         int32_t err = reply.readExceptionCode();
531         if (err < 0) {
532             ALOGD("decryptStorage caught exception %d\n", err);
533             return err;
534         }
535         return reply.readInt32();
536     }
537
538     int32_t encryptStorage(const String16& password)
539     {
540         Parcel data, reply;
541         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
542         data.writeString16(password);
543         if (remote()->transact(TRANSACTION_encryptStorage, data, &reply) != NO_ERROR) {
544             ALOGD("encryptStorage could not contact remote\n");
545             return -1;
546         }
547         int32_t err = reply.readExceptionCode();
548         if (err < 0) {
549             ALOGD("encryptStorage caught exception %d\n", err);
550             return err;
551         }
552         return reply.readInt32();
553     }
554 };
555
556 IMPLEMENT_META_INTERFACE(MountService, "IMountService")
557
558 // ----------------------------------------------------------------------
559
560 }