530 lines
18 KiB
C++
530 lines
18 KiB
C++
|
/*
|
||
|
* 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 <storage/IMountService.h>
|
||
|
#include <binder/Parcel.h>
|
||
|
|
||
|
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_enableShared,
|
||
|
};
|
||
|
|
||
|
class BpMountService: public BpInterface<IMountService>
|
||
|
{
|
||
|
public:
|
||
|
BpMountService(const sp<IBinder>& impl)
|
||
|
: BpInterface<IMountService>(impl)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
virtual void registerListener(const sp<IMountServiceListener>& listener)
|
||
|
{
|
||
|
Parcel data, reply;
|
||
|
data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
|
||
|
data.writeStrongBinder(listener->asBinder());
|
||
|
if (remote()->transact(TRANSACTION_registerListener, data, &reply) != NO_ERROR) {
|
||
|
LOGD("registerListener could not contact remote\n");
|
||
|
return;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("registerListener caught exception %d\n", err);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
virtual void unregisterListener(const sp<IMountServiceListener>& listener)
|
||
|
{
|
||
|
Parcel data, reply;
|
||
|
data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
|
||
|
data.writeStrongBinder(listener->asBinder());
|
||
|
if (remote()->transact(TRANSACTION_unregisterListener, data, &reply) != NO_ERROR) {
|
||
|
LOGD("unregisterListener could not contact remote\n");
|
||
|
return;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("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) {
|
||
|
LOGD("isUsbMassStorageConnected could not contact remote\n");
|
||
|
return false;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("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) {
|
||
|
LOGD("setUsbMassStorageEnabled could not contact remote\n");
|
||
|
return;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("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) {
|
||
|
LOGD("isUsbMassStorageEnabled could not contact remote\n");
|
||
|
return false;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("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) {
|
||
|
LOGD("mountVolume could not contact remote\n");
|
||
|
return -1;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("mountVolume caught exception %d\n", err);
|
||
|
return err;
|
||
|
}
|
||
|
return reply.readInt32();
|
||
|
}
|
||
|
|
||
|
int32_t unmountVolume(const String16& mountPoint, const bool force)
|
||
|
{
|
||
|
Parcel data, reply;
|
||
|
data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
|
||
|
data.writeString16(mountPoint);
|
||
|
data.writeInt32(force ? 1 : 0);
|
||
|
if (remote()->transact(TRANSACTION_unmountVolume, data, &reply) != NO_ERROR) {
|
||
|
LOGD("unmountVolume could not contact remote\n");
|
||
|
return -1;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("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) {
|
||
|
LOGD("formatVolume could not contact remote\n");
|
||
|
return -1;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("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) {
|
||
|
LOGD("getStorageUsers could not contact remote\n");
|
||
|
return -1;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("getStorageUsers caught exception %d\n", err);
|
||
|
return err;
|
||
|
}
|
||
|
const int32_t numUsers = reply.readInt32();
|
||
|
*users = (int32_t*)malloc(sizeof(int32_t)*numUsers);
|
||
|
for (int i = 0; i < numUsers; i++) {
|
||
|
**users++ = reply.readInt32();
|
||
|
}
|
||
|
return 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) {
|
||
|
LOGD("getVolumeState could not contact remote\n");
|
||
|
return -1;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("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) {
|
||
|
LOGD("createSecureContainer could not contact remote\n");
|
||
|
return -1;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("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) {
|
||
|
LOGD("finalizeSecureContainer couldn't call remote\n");
|
||
|
return -1;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("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) {
|
||
|
LOGD("destroySecureContainer couldn't call remote");
|
||
|
return -1;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("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);
|
||
|
if (remote()->transact(TRANSACTION_mountSecureContainer, data, &reply) != NO_ERROR) {
|
||
|
LOGD("mountSecureContainer couldn't call remote");
|
||
|
return -1;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode(); // What to do...
|
||
|
if (err < 0) {
|
||
|
LOGD("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) {
|
||
|
LOGD("unmountSecureContainer couldn't call remote");
|
||
|
return -1;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode(); // What to do...
|
||
|
if (err < 0) {
|
||
|
LOGD("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) {
|
||
|
LOGD("isSecureContainerMounted couldn't call remote");
|
||
|
return false;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode(); // What to do...
|
||
|
if (err < 0) {
|
||
|
LOGD("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) {
|
||
|
LOGD("renameSecureContainer couldn't call remote");
|
||
|
return -1;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode(); // What to do...
|
||
|
if (err < 0) {
|
||
|
LOGD("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) {
|
||
|
LOGD("getSecureContainerPath couldn't call remote");
|
||
|
return false;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode(); // What to do...
|
||
|
if (err < 0) {
|
||
|
LOGD("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) {
|
||
|
LOGD("getSecureContainerList couldn't call remote");
|
||
|
return -1;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("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<IMountShutdownObserver>& observer)
|
||
|
{
|
||
|
Parcel data, reply;
|
||
|
data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
|
||
|
data.writeStrongBinder(observer->asBinder());
|
||
|
if (remote()->transact(TRANSACTION_shutdown, data, &reply) != NO_ERROR) {
|
||
|
LOGD("shutdown could not contact remote\n");
|
||
|
return;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("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) {
|
||
|
LOGD("finishMediaUpdate could not contact remote\n");
|
||
|
return;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("finishMediaUpdate caught exception %d\n", err);
|
||
|
return;
|
||
|
}
|
||
|
reply.readExceptionCode();
|
||
|
}
|
||
|
|
||
|
void mountObb(const String16& filename, const String16& key,
|
||
|
const sp<IObbActionListener>& token, int32_t nonce)
|
||
|
{
|
||
|
Parcel data, reply;
|
||
|
data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
|
||
|
data.writeString16(filename);
|
||
|
data.writeString16(key);
|
||
|
data.writeStrongBinder(token->asBinder());
|
||
|
data.writeInt32(nonce);
|
||
|
if (remote()->transact(TRANSACTION_mountObb, data, &reply) != NO_ERROR) {
|
||
|
LOGD("mountObb could not contact remote\n");
|
||
|
return;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("mountObb caught exception %d\n", err);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void unmountObb(const String16& filename, const bool force,
|
||
|
const sp<IObbActionListener>& token, const int32_t nonce)
|
||
|
{
|
||
|
Parcel data, reply;
|
||
|
data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
|
||
|
data.writeString16(filename);
|
||
|
data.writeInt32(force ? 1 : 0);
|
||
|
data.writeStrongBinder(token->asBinder());
|
||
|
data.writeInt32(nonce);
|
||
|
if (remote()->transact(TRANSACTION_unmountObb, data, &reply) != NO_ERROR) {
|
||
|
LOGD("unmountObb could not contact remote\n");
|
||
|
return;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("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) {
|
||
|
LOGD("isObbMounted could not contact remote\n");
|
||
|
return false;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("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) {
|
||
|
LOGD("getMountedObbPath could not contact remote\n");
|
||
|
return false;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("getMountedObbPath caught exception %d\n", err);
|
||
|
return false;
|
||
|
}
|
||
|
path = reply.readString16();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
virtual void enableShared(const bool enable)
|
||
|
{
|
||
|
Parcel data, reply;
|
||
|
data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
|
||
|
data.writeInt32(enable != 0);
|
||
|
if (remote()->transact(TRANSACTION_enableShared, data, &reply) != NO_ERROR) {
|
||
|
LOGD("enableShared could not contact remote\n");
|
||
|
return;
|
||
|
}
|
||
|
int32_t err = reply.readExceptionCode();
|
||
|
if (err < 0) {
|
||
|
LOGD("enableShared caught exception %d\n", err);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
IMPLEMENT_META_INTERFACE(MountService, "IMountService");
|
||
|
|
||
|
// ----------------------------------------------------------------------
|
||
|
|
||
|
};
|