• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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