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(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 }
    561