2 * Copyright (C) 2015 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include "VolumeBase.h"
19 #include "VolumeManager.h"
20 #include "ResponseCode.h"
22 #include <base/stringprintf.h>
23 #include <base/logging.h>
27 #include <sys/mount.h>
29 #include <sys/types.h>
31 using android::base::StringPrintf;
38 VolumeBase::VolumeBase(Type type) :
39 mType(type), mMountFlags(0), mMountUserId(-1), mCreated(false), mState(
40 State::kUnmounted), mSilent(false) {
43 VolumeBase::~VolumeBase() {
47 void VolumeBase::setState(State state) {
49 notifyEvent(ResponseCode::VolumeStateChanged, StringPrintf("%d", mState));
52 status_t VolumeBase::setDiskId(const std::string& diskId) {
54 LOG(WARNING) << getId() << " diskId change requires destroyed";
62 status_t VolumeBase::setMountFlags(int mountFlags) {
63 if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
64 LOG(WARNING) << getId() << " flags change requires state unmounted or unmountable";
68 mMountFlags = mountFlags;
72 status_t VolumeBase::setMountUserId(userid_t mountUserId) {
73 if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
74 LOG(WARNING) << getId() << " user change requires state unmounted or unmountable";
78 mMountUserId = mountUserId;
82 status_t VolumeBase::setSilent(bool silent) {
84 LOG(WARNING) << getId() << " silence change requires destroyed";
92 status_t VolumeBase::setId(const std::string& id) {
94 LOG(WARNING) << getId() << " id change requires not created";
102 status_t VolumeBase::setPath(const std::string& path) {
103 if (mState != State::kChecking) {
104 LOG(WARNING) << getId() << " path change requires state checking";
109 notifyEvent(ResponseCode::VolumePathChanged, mPath);
113 status_t VolumeBase::setInternalPath(const std::string& internalPath) {
114 if (mState != State::kChecking) {
115 LOG(WARNING) << getId() << " internal path change requires state checking";
119 mInternalPath = internalPath;
120 notifyEvent(ResponseCode::VolumeInternalPathChanged, mInternalPath);
124 void VolumeBase::notifyEvent(int event) {
126 VolumeManager::Instance()->getBroadcaster()->sendBroadcast(event,
127 getId().c_str(), false);
130 void VolumeBase::notifyEvent(int event, const std::string& value) {
132 VolumeManager::Instance()->getBroadcaster()->sendBroadcast(event,
133 StringPrintf("%s %s", getId().c_str(), value.c_str()).c_str(), false);
136 void VolumeBase::addVolume(const std::shared_ptr<VolumeBase>& volume) {
137 mVolumes.push_back(volume);
140 void VolumeBase::removeVolume(const std::shared_ptr<VolumeBase>& volume) {
141 mVolumes.remove(volume);
144 std::shared_ptr<VolumeBase> VolumeBase::findVolume(const std::string& id) {
145 for (auto vol : mVolumes) {
146 if (vol->getId() == id) {
153 status_t VolumeBase::create() {
157 status_t res = doCreate();
158 notifyEvent(ResponseCode::VolumeCreated, StringPrintf("%d %s", mType, mDiskId.c_str()));
159 setState(State::kUnmounted);
163 status_t VolumeBase::doCreate() {
167 status_t VolumeBase::destroy() {
170 if (mState == State::kMounted) {
172 setState(State::kBadRemoval);
174 setState(State::kRemoved);
177 notifyEvent(ResponseCode::VolumeDestroyed);
178 status_t res = doDestroy();
183 status_t VolumeBase::doDestroy() {
187 status_t VolumeBase::mount() {
188 if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
189 LOG(WARNING) << getId() << " mount requires state unmounted or unmountable";
193 setState(State::kChecking);
194 status_t res = doMount();
196 setState(State::kMounted);
198 setState(State::kUnmountable);
204 status_t VolumeBase::unmount() {
205 if (mState != State::kMounted) {
206 LOG(WARNING) << getId() << " unmount requires state mounted";
210 setState(State::kEjecting);
212 for (auto vol : mVolumes) {
213 if (vol->destroy()) {
214 LOG(WARNING) << getId() << " failed to destroy " << vol->getId()
220 status_t res = doUnmount();
221 setState(State::kUnmounted);
225 status_t VolumeBase::format() {
226 if (mState == State::kMounted) {
230 if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) {
231 LOG(WARNING) << getId() << " format requires state unmounted or unmountable";
235 setState(State::kFormatting);
236 status_t res = doFormat();
237 setState(State::kUnmounted);
241 status_t VolumeBase::doFormat() {
246 } // namespace android