VolumeManager.cpp revision 49e2bce5b74129c26a35e25d4693cbfe98c4688e
1/* 2 * Copyright (C) 2008 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#include <stdio.h> 18#include <stdlib.h> 19#include <string.h> 20#include <errno.h> 21 22#define LOG_TAG "Vold" 23 24#include <cutils/log.h> 25 26#include <sysutils/NetlinkEvent.h> 27 28#include "VolumeManager.h" 29#include "DirectVolume.h" 30#include "ErrorCode.h" 31 32VolumeManager *VolumeManager::sInstance = NULL; 33 34VolumeManager *VolumeManager::Instance() { 35 if (!sInstance) 36 sInstance = new VolumeManager(); 37 return sInstance; 38} 39 40VolumeManager::VolumeManager() { 41 mBlockDevices = new BlockDeviceCollection(); 42 mVolumes = new VolumeCollection(); 43 mBroadcaster = NULL; 44} 45 46VolumeManager::~VolumeManager() { 47 delete mBlockDevices; 48} 49 50int VolumeManager::start() { 51 return 0; 52} 53 54int VolumeManager::stop() { 55 return 0; 56} 57 58int VolumeManager::addVolume(Volume *v) { 59 mVolumes->push_back(v); 60 return 0; 61} 62 63void VolumeManager::handleBlockEvent(NetlinkEvent *evt) { 64 const char *devpath = evt->findParam("DEVPATH"); 65 66 /* Lookup a volume to handle this device */ 67 VolumeCollection::iterator it; 68 bool hit = false; 69 for (it = mVolumes->begin(); it != mVolumes->end(); ++it) { 70 if (!(*it)->handleBlockEvent(evt)) { 71 hit = true; 72 break; 73 } 74 } 75 76 if (!hit) { 77 LOGW("No volumes handled block event for '%s'", devpath); 78 } 79} 80 81int VolumeManager::listVolumes(SocketClient *cli) { 82 VolumeCollection::iterator i; 83 84 for (i = mVolumes->begin(); i != mVolumes->end(); ++i) { 85 char *buffer; 86 asprintf(&buffer, "%s %s %d", 87 (*i)->getLabel(), (*i)->getMountpoint(), 88 (*i)->getState()); 89 cli->sendMsg(ErrorCode::VolumeListResult, buffer, false); 90 free(buffer); 91 } 92 cli->sendMsg(ErrorCode::CommandOkay, "Volumes listed.", false); 93 return 0; 94} 95 96int VolumeManager::mountVolume(const char *label) { 97 Volume *v = lookupVolume(label); 98 99 if (!v) { 100 errno = ENOENT; 101 return -1; 102 } 103 104 if (v->getState() != Volume::State_Idle) { 105 errno = EBUSY; 106 return -1; 107 } 108 109 return v->mount(); 110} 111 112int VolumeManager::unmountVolume(const char *label) { 113 Volume *v = lookupVolume(label); 114 115 if (!v) { 116 errno = ENOENT; 117 return -1; 118 } 119 120 if (v->getState() != Volume::State_Mounted) { 121 errno = EBUSY; 122 return -1; 123 } 124 125 return v->unmount(); 126} 127 128Volume *VolumeManager::lookupVolume(const char *label) { 129 VolumeCollection::iterator i; 130 131 for (i = mVolumes->begin(); i != mVolumes->end(); ++i) { 132 if (!strcmp(label, (*i)->getLabel())) 133 return (*i); 134 } 135 return NULL; 136} 137