Home | History | Annotate | Download | only in storage
      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(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         // Assume read-only
    299         data.writeInt32(1);
    300         if (remote()->transact(TRANSACTION_mountSecureContainer, data, &reply) != NO_ERROR) {
    301             ALOGD("mountSecureContainer couldn't call remote");
    302             return -1;
    303         }
    304         int32_t err = reply.readExceptionCode(); // What to do...
    305         if (err < 0) {
    306             ALOGD("mountSecureContainer caught exception %d\n", err);
    307             return err;
    308         }
    309         return reply.readInt32();
    310     }
    311 
    312     int32_t unmountSecureContainer(const String16& id, const bool force)
    313     {
    314         Parcel data, reply;
    315         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
    316         data.writeString16(id);
    317         data.writeInt32(force ? 1 : 0);
    318         if (remote()->transact(TRANSACTION_getSecureContainerPath, data, &reply) != NO_ERROR) {
    319             ALOGD("unmountSecureContainer couldn't call remote");
    320             return -1;
    321         }
    322         int32_t err = reply.readExceptionCode(); // What to do...
    323         if (err < 0) {
    324             ALOGD("unmountSecureContainer caught exception %d\n", err);
    325             return err;
    326         }
    327         return reply.readInt32();
    328     }
    329 
    330     bool isSecureContainerMounted(const String16& id)
    331     {
    332         Parcel data, reply;
    333         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
    334         data.writeString16(id);
    335         if (remote()->transact(TRANSACTION_isSecureContainerMounted, data, &reply) != NO_ERROR) {
    336             ALOGD("isSecureContainerMounted couldn't call remote");
    337             return false;
    338         }
    339         int32_t err = reply.readExceptionCode(); // What to do...
    340         if (err < 0) {
    341             ALOGD("isSecureContainerMounted caught exception %d\n", err);
    342             return false;
    343         }
    344         return reply.readInt32() != 0;
    345     }
    346 
    347     int32_t renameSecureContainer(const String16& oldId, const String16& newId)
    348     {
    349         Parcel data, reply;
    350         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
    351         data.writeString16(oldId);
    352         data.writeString16(newId);
    353         if (remote()->transact(TRANSACTION_renameSecureContainer, data, &reply) != NO_ERROR) {
    354             ALOGD("renameSecureContainer couldn't call remote");
    355             return -1;
    356         }
    357         int32_t err = reply.readExceptionCode(); // What to do...
    358         if (err < 0) {
    359             ALOGD("renameSecureContainer caught exception %d\n", err);
    360             return err;
    361         }
    362         return reply.readInt32();
    363     }
    364 
    365     bool getSecureContainerPath(const String16& id, String16& path)
    366     {
    367         Parcel data, reply;
    368         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
    369         data.writeString16(id);
    370         if (remote()->transact(TRANSACTION_getSecureContainerPath, data, &reply) != NO_ERROR) {
    371             ALOGD("getSecureContainerPath couldn't call remote");
    372             return false;
    373         }
    374         int32_t err = reply.readExceptionCode(); // What to do...
    375         if (err < 0) {
    376             ALOGD("getSecureContainerPath caught exception %d\n", err);
    377             return false;
    378         }
    379         path = reply.readString16();
    380         return true;
    381     }
    382 
    383     int32_t getSecureContainerList(const String16& id, String16*& containers)
    384     {
    385         Parcel data, reply;
    386         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
    387         data.writeString16(id);
    388         if (remote()->transact(TRANSACTION_getSecureContainerList, data, &reply) != NO_ERROR) {
    389             ALOGD("getSecureContainerList couldn't call remote");
    390             return -1;
    391         }
    392         int32_t err = reply.readExceptionCode();
    393         if (err < 0) {
    394             ALOGD("getSecureContainerList caught exception %d\n", err);
    395             return err;
    396         }
    397         const int32_t numStrings = reply.readInt32();
    398         containers = new String16[numStrings];
    399         for (int i = 0; i < numStrings; i++) {
    400             containers[i] = reply.readString16();
    401         }
    402         return numStrings;
    403     }
    404 
    405     void shutdown(const sp<IMountShutdownObserver>& observer)
    406     {
    407         Parcel data, reply;
    408         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
    409         data.writeStrongBinder(observer->asBinder());
    410         if (remote()->transact(TRANSACTION_shutdown, data, &reply) != NO_ERROR) {
    411             ALOGD("shutdown could not contact remote\n");
    412             return;
    413         }
    414         int32_t err = reply.readExceptionCode();
    415         if (err < 0) {
    416             ALOGD("shutdown caught exception %d\n", err);
    417             return;
    418         }
    419         reply.readExceptionCode();
    420     }
    421 
    422     void finishMediaUpdate()
    423     {
    424         Parcel data, reply;
    425         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
    426         if (remote()->transact(TRANSACTION_finishMediaUpdate, data, &reply) != NO_ERROR) {
    427             ALOGD("finishMediaUpdate could not contact remote\n");
    428             return;
    429         }
    430         int32_t err = reply.readExceptionCode();
    431         if (err < 0) {
    432             ALOGD("finishMediaUpdate caught exception %d\n", err);
    433             return;
    434         }
    435         reply.readExceptionCode();
    436     }
    437 
    438     void mountObb(const String16& rawPath, const String16& canonicalPath, const String16& key,
    439             const sp<IObbActionListener>& token, int32_t nonce)
    440     {
    441         Parcel data, reply;
    442         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
    443         data.writeString16(rawPath);
    444         data.writeString16(canonicalPath);
    445         data.writeString16(key);
    446         data.writeStrongBinder(token->asBinder());
    447         data.writeInt32(nonce);
    448         if (remote()->transact(TRANSACTION_mountObb, data, &reply) != NO_ERROR) {
    449             ALOGD("mountObb could not contact remote\n");
    450             return;
    451         }
    452         int32_t err = reply.readExceptionCode();
    453         if (err < 0) {
    454             ALOGD("mountObb caught exception %d\n", err);
    455             return;
    456         }
    457     }
    458 
    459     void unmountObb(const String16& filename, const bool force,
    460             const sp<IObbActionListener>& token, const int32_t nonce)
    461     {
    462         Parcel data, reply;
    463         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
    464         data.writeString16(filename);
    465         data.writeInt32(force ? 1 : 0);
    466         data.writeStrongBinder(token->asBinder());
    467         data.writeInt32(nonce);
    468         if (remote()->transact(TRANSACTION_unmountObb, data, &reply) != NO_ERROR) {
    469             ALOGD("unmountObb could not contact remote\n");
    470             return;
    471         }
    472         int32_t err = reply.readExceptionCode();
    473         if (err < 0) {
    474             ALOGD("unmountObb caught exception %d\n", err);
    475             return;
    476         }
    477     }
    478 
    479     bool isObbMounted(const String16& filename)
    480     {
    481         Parcel data, reply;
    482         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
    483         data.writeString16(filename);
    484         if (remote()->transact(TRANSACTION_isObbMounted, data, &reply) != NO_ERROR) {
    485             ALOGD("isObbMounted could not contact remote\n");
    486             return false;
    487         }
    488         int32_t err = reply.readExceptionCode();
    489         if (err < 0) {
    490             ALOGD("isObbMounted caught exception %d\n", err);
    491             return false;
    492         }
    493         return reply.readInt32() != 0;
    494     }
    495 
    496     bool getMountedObbPath(const String16& filename, String16& path)
    497     {
    498         Parcel data, reply;
    499         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
    500         data.writeString16(filename);
    501         if (remote()->transact(TRANSACTION_getMountedObbPath, data, &reply) != NO_ERROR) {
    502             ALOGD("getMountedObbPath could not contact remote\n");
    503             return false;
    504         }
    505         int32_t err = reply.readExceptionCode();
    506         if (err < 0) {
    507             ALOGD("getMountedObbPath caught exception %d\n", err);
    508             return false;
    509         }
    510         path = reply.readString16();
    511         return true;
    512     }
    513 
    514     int32_t decryptStorage(const String16& password)
    515     {
    516         Parcel data, reply;
    517         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
    518         data.writeString16(password);
    519         if (remote()->transact(TRANSACTION_decryptStorage, data, &reply) != NO_ERROR) {
    520             ALOGD("decryptStorage could not contact remote\n");
    521             return -1;
    522         }
    523         int32_t err = reply.readExceptionCode();
    524         if (err < 0) {
    525             ALOGD("decryptStorage caught exception %d\n", err);
    526             return err;
    527         }
    528         return reply.readInt32();
    529     }
    530 
    531     int32_t encryptStorage(const String16& password)
    532     {
    533         Parcel data, reply;
    534         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
    535         data.writeString16(password);
    536         if (remote()->transact(TRANSACTION_encryptStorage, data, &reply) != NO_ERROR) {
    537             ALOGD("encryptStorage could not contact remote\n");
    538             return -1;
    539         }
    540         int32_t err = reply.readExceptionCode();
    541         if (err < 0) {
    542             ALOGD("encryptStorage caught exception %d\n", err);
    543             return err;
    544         }
    545         return reply.readInt32();
    546     }
    547 };
    548 
    549 IMPLEMENT_META_INTERFACE(MountService, "IMountService");
    550 
    551 // ----------------------------------------------------------------------
    552 
    553 };
    554