1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "volume/volume_manager_service.h"
17
18 #include "disk.h"
19 #include "disk/disk_manager_service.h"
20 #include "safe_map.h"
21 #include "storage_daemon_communication/storage_daemon_communication.h"
22 #include "storage_service_errno.h"
23 #include "storage_service_log.h"
24 #include "utils/storage_radar.h"
25 #include "utils/storage_utils.h"
26 #include "volume/notification.h"
27
28 using namespace std;
29 using namespace OHOS::StorageService;
30 namespace OHOS {
31 namespace StorageManager {
VolumeManagerService()32 VolumeManagerService::VolumeManagerService() {}
~VolumeManagerService()33 VolumeManagerService::~VolumeManagerService() {}
34
VolumeStateNotify(VolumeState state,std::shared_ptr<VolumeExternal> volume)35 void VolumeManagerService::VolumeStateNotify(VolumeState state, std::shared_ptr<VolumeExternal> volume)
36 {
37 DelayedSingleton<Notification>::GetInstance()->NotifyVolumeChange(state, volume);
38 }
39
OnVolumeCreated(VolumeCore vc)40 void VolumeManagerService::OnVolumeCreated(VolumeCore vc)
41 {
42 auto volumePtr = make_shared<VolumeExternal>(vc);
43 volumeMap_.Insert(volumePtr->GetId(), volumePtr);
44 Mount(volumePtr->GetId());
45 }
46
OnVolumeStateChanged(string volumeId,VolumeState state)47 void VolumeManagerService::OnVolumeStateChanged(string volumeId, VolumeState state)
48 {
49 if (!volumeMap_.Contains(volumeId)) {
50 LOGE("VolumeManagerService::OnVolumeDestroyed volumeId %{public}s not exists", volumeId.c_str());
51 return;
52 }
53 std::shared_ptr<VolumeExternal> volumePtr = volumeMap_.ReadVal(volumeId);
54 VolumeStateNotify(state, volumePtr);
55 if (state == VolumeState::REMOVED || state == VolumeState::BAD_REMOVAL) {
56 volumeMap_.Erase(volumeId);
57 }
58 }
59
OnVolumeMounted(std::string volumeId,int fsType,std::string fsUuid,std::string path,std::string description)60 void VolumeManagerService::OnVolumeMounted(std::string volumeId, int fsType, std::string fsUuid,
61 std::string path, std::string description)
62 {
63 if (!volumeMap_.Contains(volumeId)) {
64 LOGE("VolumeManagerService::OnVolumeMounted volumeId %{public}s not exists", volumeId.c_str());
65 return;
66 }
67 std::shared_ptr<VolumeExternal> volumePtr = volumeMap_.ReadVal(volumeId);
68 if (volumePtr == nullptr) {
69 LOGE("volumePtr is nullptr for volumeId");
70 return;
71 }
72 volumePtr->SetFsType(fsType);
73 volumePtr->SetFsUuid(fsUuid);
74 volumePtr->SetPath(path);
75 std::string des = description;
76 auto disk = DelayedSingleton<DiskManagerService>::GetInstance()->GetDiskById(volumePtr->GetDiskId());
77 if (disk != nullptr) {
78 if (des == "") {
79 if (disk->GetFlag() == SD_FLAG) {
80 des = "MySDCard";
81 } else if (disk->GetFlag() == USB_FLAG) {
82 des = "MyUSB";
83 } else {
84 des = "Default";
85 }
86 }
87 volumePtr->SetFlags(disk->GetFlag());
88 }
89 volumePtr->SetDescription(des);
90 volumePtr->SetState(VolumeState::MOUNTED);
91 VolumeStateNotify(VolumeState::MOUNTED, volumePtr);
92 }
93
Mount(std::string volumeId)94 int32_t VolumeManagerService::Mount(std::string volumeId)
95 {
96 if (!volumeMap_.Contains(volumeId)) {
97 LOGE("VolumeManagerService::Mount volumeId %{public}s not exists", volumeId.c_str());
98 return E_NON_EXIST;
99 }
100 std::shared_ptr<VolumeExternal> volumePtr = volumeMap_.ReadVal(volumeId);
101 if (volumePtr == nullptr) {
102 LOGE("volumePtr is nullptr for volumeId");
103 return E_VOLUMEEX_IS_NULLPTR;
104 }
105 if (volumePtr->GetState() != VolumeState::UNMOUNTED) {
106 LOGE("VolumeManagerService::The type of volume(Id %{public}s) is not unmounted", volumeId.c_str());
107 return E_VOL_MOUNT_ERR;
108 }
109 std::shared_ptr<StorageDaemonCommunication> sdCommunication;
110 sdCommunication = DelayedSingleton<StorageDaemonCommunication>::GetInstance();
111 int32_t result = Check(volumePtr->GetId());
112 if (result == E_OK) {
113 result = sdCommunication->Mount(volumeId, 0);
114 if (result != E_OK) {
115 volumePtr->SetState(VolumeState::UNMOUNTED);
116 }
117 } else {
118 volumePtr->SetState(VolumeState::UNMOUNTED);
119 StorageRadar::ReportVolumeOperation("VolumeManagerService::Check", result);
120 }
121 return result;
122 }
123
Unmount(std::string volumeId)124 int32_t VolumeManagerService::Unmount(std::string volumeId)
125 {
126 if (!volumeMap_.Contains(volumeId)) {
127 LOGE("VolumeManagerService::Unmount volumeId %{public}s not exists", volumeId.c_str());
128 return E_NON_EXIST;
129 }
130 std::shared_ptr<VolumeExternal> volumePtr = volumeMap_.ReadVal(volumeId);
131 if (volumePtr == nullptr) {
132 LOGE("volumePtr is nullptr for volumeId");
133 return E_VOLUMEEX_IS_NULLPTR;
134 }
135 if (volumePtr->GetState() != VolumeState::MOUNTED) {
136 LOGE("VolumeManagerService::The type of volume(Id %{public}s) is not mounted", volumeId.c_str());
137 return E_VOL_UMOUNT_ERR;
138 }
139 std::shared_ptr<StorageDaemonCommunication> sdCommunication;
140 sdCommunication = DelayedSingleton<StorageDaemonCommunication>::GetInstance();
141 volumePtr->SetState(VolumeState::EJECTING);
142 int32_t result = sdCommunication->Unmount(volumeId);
143 if (result == E_OK) {
144 volumePtr->SetState(VolumeState::UNMOUNTED);
145 volumePtr->Reset();
146 } else {
147 volumePtr->SetState(VolumeState::MOUNTED);
148 }
149 return result;
150 }
151
Check(std::string volumeId)152 int32_t VolumeManagerService::Check(std::string volumeId)
153 {
154 std::shared_ptr<VolumeExternal> volumePtr = volumeMap_.ReadVal(volumeId);
155 if (volumePtr == nullptr) {
156 LOGE("volumePtr is nullptr for volumeId");
157 return E_VOLUMEEX_IS_NULLPTR;
158 }
159 volumePtr->SetState(VolumeState::CHECKING);
160 if (volumePtr->GetFsType() == FsType::MTP) {
161 return E_OK;
162 }
163 std::shared_ptr<StorageDaemonCommunication> sdCommunication;
164 sdCommunication = DelayedSingleton<StorageDaemonCommunication>::GetInstance();
165 int32_t result = sdCommunication->Check(volumeId);
166 return result;
167 }
168
GetAllVolumes()169 vector<VolumeExternal> VolumeManagerService::GetAllVolumes()
170 {
171 vector<VolumeExternal> result;
172 for (auto it = volumeMap_.Begin(); it != volumeMap_.End(); ++it) {
173 VolumeExternal vc = *(it->second);
174 result.push_back(vc);
175 }
176 return result;
177 }
178
GetVolumeByUuid(std::string volumeUuid)179 std::shared_ptr<VolumeExternal> VolumeManagerService::GetVolumeByUuid(std::string volumeUuid)
180 {
181 for (auto it = volumeMap_.Begin(); it != volumeMap_.End(); ++it) {
182 auto vc = it->second;
183 if (vc->GetUuid() == volumeUuid) {
184 LOGE("VolumeManagerService::GetVolumeByUuid volumeUuid %{public}s exists",
185 GetAnonyString(volumeUuid).c_str());
186 return vc;
187 }
188 }
189 return nullptr;
190 }
191
GetVolumeByUuid(std::string fsUuid,VolumeExternal & vc)192 int32_t VolumeManagerService::GetVolumeByUuid(std::string fsUuid, VolumeExternal &vc)
193 {
194 for (auto it = volumeMap_.Begin(); it != volumeMap_.End(); ++it) {
195 auto volume = it->second;
196 if (volume->GetUuid() == fsUuid) {
197 LOGI("VolumeManagerService::GetVolumeByUuid volumeUuid %{public}s exists",
198 GetAnonyString(fsUuid).c_str());
199 vc = *volume;
200 return E_OK;
201 }
202 }
203 return E_NON_EXIST;
204 }
205
GetVolumeById(std::string volumeId,VolumeExternal & vc)206 int32_t VolumeManagerService::GetVolumeById(std::string volumeId, VolumeExternal &vc)
207 {
208 if (volumeMap_.Contains(volumeId)) {
209 vc = *volumeMap_.ReadVal(volumeId);
210 return E_OK;
211 }
212 return E_NON_EXIST;
213 }
214
SetVolumeDescription(std::string fsUuid,std::string description)215 int32_t VolumeManagerService::SetVolumeDescription(std::string fsUuid, std::string description)
216 {
217 for (auto it = volumeMap_.Begin(); it != volumeMap_.End(); ++it) {
218 auto volume = it->second;
219 if (volume->GetUuid() == fsUuid) {
220 LOGI("VolumeManagerService::SetVolumeDescription volumeUuid %{public}s exists",
221 GetAnonyString(fsUuid).c_str());
222 if (volume->GetState() != VolumeState::UNMOUNTED) {
223 LOGE("VolumeManagerService::SetVolumeDescription volume state is not unmounted!");
224 return E_VOL_STATE;
225 }
226 std::shared_ptr<StorageDaemonCommunication> sdCommunication;
227 sdCommunication = DelayedSingleton<StorageDaemonCommunication>::GetInstance();
228 return sdCommunication->SetVolumeDescription(volume->GetId(), description);
229 }
230 }
231 return E_NON_EXIST;
232 }
233
Format(std::string volumeId,std::string fsType)234 int32_t VolumeManagerService::Format(std::string volumeId, std::string fsType)
235 {
236 if (volumeMap_.Find(volumeId) == volumeMap_.End()) {
237 return E_NON_EXIST;
238 }
239 std::shared_ptr<VolumeExternal> volumePtr = volumeMap_.ReadVal(volumeId);
240 if ((volumePtr != nullptr) && (volumePtr->GetFsType() == FsType::MTP)) {
241 LOGE("MTP device not support to format.");
242 return E_NOT_SUPPORT;
243 }
244 if (volumeMap_.ReadVal(volumeId)->GetState() != VolumeState::UNMOUNTED) {
245 LOGE("VolumeManagerService::SetVolumeDescription volume state is not unmounted!");
246 return E_VOL_STATE;
247 }
248 // check fstype!!!!
249 std::shared_ptr<StorageDaemonCommunication> sdCommunication;
250 sdCommunication = DelayedSingleton<StorageDaemonCommunication>::GetInstance();
251 return sdCommunication->Format(volumeId, fsType);
252 }
253
NotifyMtpMounted(const std::string & id,const std::string & path,const std::string & desc,const std::string & uuid)254 void VolumeManagerService::NotifyMtpMounted(const std::string &id, const std::string &path, const std::string &desc,
255 const std::string &uuid)
256 {
257 LOGI("VolumeManagerService NotifyMtpMounted");
258 VolumeCore core(id, 0, "");
259 auto volumePtr = make_shared<VolumeExternal>(core);
260 volumePtr->SetPath(path);
261 volumePtr->SetFsType(FsType::MTP);
262 volumePtr->SetDescription(desc);
263 volumePtr->SetState(MOUNTED);
264 volumePtr->SetFsUuid(uuid);
265 volumeMap_.Insert(volumePtr->GetId(), volumePtr);
266 VolumeStateNotify(VolumeState::MOUNTED, volumePtr);
267 }
268
NotifyMtpUnmounted(const std::string & id,const std::string & path,const bool isBadRemove)269 void VolumeManagerService::NotifyMtpUnmounted(const std::string &id, const std::string &path, const bool isBadRemove)
270 {
271 LOGI("VolumeManagerService NotifyMtpUnmounted");
272 if (!volumeMap_.Contains(id)) {
273 LOGE("VolumeManagerService::Unmount id %{public}s not exists", id.c_str());
274 return;
275 }
276 std::shared_ptr<VolumeExternal> volumePtr = volumeMap_.ReadVal(id);
277 if (volumePtr == nullptr) {
278 LOGE("volumePtr is nullptr for id");
279 return;
280 }
281 if (!isBadRemove) {
282 VolumeStateNotify(VolumeState::UNMOUNTED, volumePtr);
283 } else {
284 VolumeStateNotify(VolumeState::BAD_REMOVAL, volumePtr);
285 }
286
287 volumeMap_.Erase(id);
288 }
289 } // StorageManager
290 } // OHOS
291