/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "IMountService" #include #include namespace android { enum { TRANSACTION_registerListener = IBinder::FIRST_CALL_TRANSACTION, TRANSACTION_unregisterListener, TRANSACTION_isUsbMassStorageConnected, TRANSACTION_setUsbMassStorageEnabled, TRANSACTION_isUsbMassStorageEnabled, TRANSACTION_mountVolume, TRANSACTION_unmountVolume, TRANSACTION_formatVolume, TRANSACTION_getStorageUsers, TRANSACTION_getVolumeState, TRANSACTION_createSecureContainer, TRANSACTION_finalizeSecureContainer, TRANSACTION_destroySecureContainer, TRANSACTION_mountSecureContainer, TRANSACTION_unmountSecureContainer, TRANSACTION_isSecureContainerMounted, TRANSACTION_renameSecureContainer, TRANSACTION_getSecureContainerPath, TRANSACTION_getSecureContainerList, TRANSACTION_shutdown, TRANSACTION_finishMediaUpdate, TRANSACTION_mountObb, TRANSACTION_unmountObb, TRANSACTION_isObbMounted, TRANSACTION_getMountedObbPath, TRANSACTION_isExternalStorageEmulated, TRANSACTION_decryptStorage, TRANSACTION_encryptStorage, }; class BpMountService: public BpInterface { public: explicit BpMountService(const sp& impl) : BpInterface(impl) { } virtual void registerListener(const sp& listener) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(listener)); if (remote()->transact(TRANSACTION_registerListener, data, &reply) != NO_ERROR) { ALOGD("registerListener could not contact remote\n"); return; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("registerListener caught exception %d\n", err); return; } } virtual void unregisterListener(const sp& listener) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(listener)); if (remote()->transact(TRANSACTION_unregisterListener, data, &reply) != NO_ERROR) { ALOGD("unregisterListener could not contact remote\n"); return; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("unregisterListener caught exception %d\n", err); return; } } virtual bool isUsbMassStorageConnected() { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); if (remote()->transact(TRANSACTION_isUsbMassStorageConnected, data, &reply) != NO_ERROR) { ALOGD("isUsbMassStorageConnected could not contact remote\n"); return false; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("isUsbMassStorageConnected caught exception %d\n", err); return false; } return reply.readInt32() != 0; } virtual void setUsbMassStorageEnabled(const bool enable) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeInt32(enable != 0); if (remote()->transact(TRANSACTION_setUsbMassStorageEnabled, data, &reply) != NO_ERROR) { ALOGD("setUsbMassStorageEnabled could not contact remote\n"); return; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("setUsbMassStorageEnabled caught exception %d\n", err); return; } } virtual bool isUsbMassStorageEnabled() { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); if (remote()->transact(TRANSACTION_isUsbMassStorageEnabled, data, &reply) != NO_ERROR) { ALOGD("isUsbMassStorageEnabled could not contact remote\n"); return false; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("isUsbMassStorageEnabled caught exception %d\n", err); return false; } return reply.readInt32() != 0; } int32_t mountVolume(const String16& mountPoint) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(mountPoint); if (remote()->transact(TRANSACTION_mountVolume, data, &reply) != NO_ERROR) { ALOGD("mountVolume could not contact remote\n"); return -1; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("mountVolume caught exception %d\n", err); return err; } return reply.readInt32(); } int32_t unmountVolume(const String16& mountPoint, const bool force, const bool removeEncryption) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(mountPoint); data.writeInt32(force ? 1 : 0); data.writeInt32(removeEncryption ? 1 : 0); if (remote()->transact(TRANSACTION_unmountVolume, data, &reply) != NO_ERROR) { ALOGD("unmountVolume could not contact remote\n"); return -1; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("unmountVolume caught exception %d\n", err); return err; } return reply.readInt32(); } int32_t formatVolume(const String16& mountPoint) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(mountPoint); if (remote()->transact(TRANSACTION_formatVolume, data, &reply) != NO_ERROR) { ALOGD("formatVolume could not contact remote\n"); return -1; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("formatVolume caught exception %d\n", err); return err; } return reply.readInt32(); } int32_t getStorageUsers(const String16& mountPoint, int32_t** users) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(mountPoint); if (remote()->transact(TRANSACTION_getStorageUsers, data, &reply) != NO_ERROR) { ALOGD("getStorageUsers could not contact remote\n"); return -1; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("getStorageUsers caught exception %d\n", err); return err; } int32_t numUsersI = reply.readInt32(); uint32_t numUsers; if (numUsersI < 0) { ALOGW("Number of users is negative: %d\n", numUsersI); numUsers = 0; } else { numUsers = static_cast(numUsersI); } *users = (int32_t*)malloc(sizeof(int32_t)*numUsers); for (size_t i = 0; i < numUsers; i++) { **users++ = reply.readInt32(); } return static_cast(numUsers); } int32_t getVolumeState(const String16& mountPoint) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(mountPoint); if (remote()->transact(TRANSACTION_getVolumeState, data, &reply) != NO_ERROR) { ALOGD("getVolumeState could not contact remote\n"); return -1; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("getVolumeState caught exception %d\n", err); return err; } return reply.readInt32(); } int32_t createSecureContainer(const String16& id, const int32_t sizeMb, const String16& fstype, const String16& key, const int32_t ownerUid) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(id); data.writeInt32(sizeMb); data.writeString16(fstype); data.writeString16(key); data.writeInt32(ownerUid); if (remote()->transact(TRANSACTION_createSecureContainer, data, &reply) != NO_ERROR) { ALOGD("createSecureContainer could not contact remote\n"); return -1; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("createSecureContainer caught exception %d\n", err); return err; } return reply.readInt32(); } int32_t finalizeSecureContainer(const String16& id) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(id); if (remote()->transact(TRANSACTION_finalizeSecureContainer, data, &reply) != NO_ERROR) { ALOGD("finalizeSecureContainer couldn't call remote\n"); return -1; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("finalizeSecureContainer caught exception %d\n", err); return err; } return reply.readInt32(); } int32_t destroySecureContainer(const String16& id) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(id); if (remote()->transact(TRANSACTION_destroySecureContainer, data, &reply) != NO_ERROR) { ALOGD("destroySecureContainer couldn't call remote"); return -1; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("destroySecureContainer caught exception %d\n", err); return err; } return reply.readInt32(); } int32_t mountSecureContainer(const String16& id, const String16& key, const int32_t ownerUid) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(id); data.writeString16(key); data.writeInt32(ownerUid); // Assume read-only data.writeInt32(1); if (remote()->transact(TRANSACTION_mountSecureContainer, data, &reply) != NO_ERROR) { ALOGD("mountSecureContainer couldn't call remote"); return -1; } int32_t err = reply.readExceptionCode(); // What to do... if (err < 0) { ALOGD("mountSecureContainer caught exception %d\n", err); return err; } return reply.readInt32(); } int32_t unmountSecureContainer(const String16& id, const bool force) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(id); data.writeInt32(force ? 1 : 0); if (remote()->transact(TRANSACTION_getSecureContainerPath, data, &reply) != NO_ERROR) { ALOGD("unmountSecureContainer couldn't call remote"); return -1; } int32_t err = reply.readExceptionCode(); // What to do... if (err < 0) { ALOGD("unmountSecureContainer caught exception %d\n", err); return err; } return reply.readInt32(); } bool isSecureContainerMounted(const String16& id) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(id); if (remote()->transact(TRANSACTION_isSecureContainerMounted, data, &reply) != NO_ERROR) { ALOGD("isSecureContainerMounted couldn't call remote"); return false; } int32_t err = reply.readExceptionCode(); // What to do... if (err < 0) { ALOGD("isSecureContainerMounted caught exception %d\n", err); return false; } return reply.readInt32() != 0; } int32_t renameSecureContainer(const String16& oldId, const String16& newId) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(oldId); data.writeString16(newId); if (remote()->transact(TRANSACTION_renameSecureContainer, data, &reply) != NO_ERROR) { ALOGD("renameSecureContainer couldn't call remote"); return -1; } int32_t err = reply.readExceptionCode(); // What to do... if (err < 0) { ALOGD("renameSecureContainer caught exception %d\n", err); return err; } return reply.readInt32(); } bool getSecureContainerPath(const String16& id, String16& path) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(id); if (remote()->transact(TRANSACTION_getSecureContainerPath, data, &reply) != NO_ERROR) { ALOGD("getSecureContainerPath couldn't call remote"); return false; } int32_t err = reply.readExceptionCode(); // What to do... if (err < 0) { ALOGD("getSecureContainerPath caught exception %d\n", err); return false; } path = reply.readString16(); return true; } int32_t getSecureContainerList(const String16& id, String16*& containers) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(id); if (remote()->transact(TRANSACTION_getSecureContainerList, data, &reply) != NO_ERROR) { ALOGD("getSecureContainerList couldn't call remote"); return -1; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("getSecureContainerList caught exception %d\n", err); return err; } const int32_t numStrings = reply.readInt32(); containers = new String16[numStrings]; for (int i = 0; i < numStrings; i++) { containers[i] = reply.readString16(); } return numStrings; } void shutdown(const sp& observer) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(observer)); if (remote()->transact(TRANSACTION_shutdown, data, &reply) != NO_ERROR) { ALOGD("shutdown could not contact remote\n"); return; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("shutdown caught exception %d\n", err); return; } reply.readExceptionCode(); } void finishMediaUpdate() { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); if (remote()->transact(TRANSACTION_finishMediaUpdate, data, &reply) != NO_ERROR) { ALOGD("finishMediaUpdate could not contact remote\n"); return; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("finishMediaUpdate caught exception %d\n", err); return; } reply.readExceptionCode(); } void mountObb(const String16& rawPath, const String16& canonicalPath, const String16& key, const sp& token, int32_t nonce, const sp& obbInfo) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(rawPath); data.writeString16(canonicalPath); data.writeString16(key); data.writeStrongBinder(IInterface::asBinder(token)); data.writeInt32(nonce); obbInfo->writeToParcel(&data); if (remote()->transact(TRANSACTION_mountObb, data, &reply) != NO_ERROR) { ALOGD("mountObb could not contact remote\n"); return; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("mountObb caught exception %d\n", err); return; } } void unmountObb(const String16& filename, const bool force, const sp& token, const int32_t nonce) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(filename); data.writeInt32(force ? 1 : 0); data.writeStrongBinder(IInterface::asBinder(token)); data.writeInt32(nonce); if (remote()->transact(TRANSACTION_unmountObb, data, &reply) != NO_ERROR) { ALOGD("unmountObb could not contact remote\n"); return; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("unmountObb caught exception %d\n", err); return; } } bool isObbMounted(const String16& filename) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(filename); if (remote()->transact(TRANSACTION_isObbMounted, data, &reply) != NO_ERROR) { ALOGD("isObbMounted could not contact remote\n"); return false; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("isObbMounted caught exception %d\n", err); return false; } return reply.readInt32() != 0; } bool getMountedObbPath(const String16& filename, String16& path) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(filename); if (remote()->transact(TRANSACTION_getMountedObbPath, data, &reply) != NO_ERROR) { ALOGD("getMountedObbPath could not contact remote\n"); return false; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("getMountedObbPath caught exception %d\n", err); return false; } path = reply.readString16(); return true; } int32_t decryptStorage(const String16& password) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(password); if (remote()->transact(TRANSACTION_decryptStorage, data, &reply) != NO_ERROR) { ALOGD("decryptStorage could not contact remote\n"); return -1; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("decryptStorage caught exception %d\n", err); return err; } return reply.readInt32(); } int32_t encryptStorage(const String16& password) { Parcel data, reply; data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); data.writeString16(password); if (remote()->transact(TRANSACTION_encryptStorage, data, &reply) != NO_ERROR) { ALOGD("encryptStorage could not contact remote\n"); return -1; } int32_t err = reply.readExceptionCode(); if (err < 0) { ALOGD("encryptStorage caught exception %d\n", err); return err; } return reply.readInt32(); } }; IMPLEMENT_META_INTERFACE(MountService, "android.os.storage.IStorageManager") // ---------------------------------------------------------------------- }