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_utils.h"
25 #include "volume/notification.h"
26 
27 using namespace std;
28 
29 namespace OHOS {
30 namespace StorageManager {
VolumeManagerService()31     VolumeManagerService::VolumeManagerService() {}
~VolumeManagerService()32     VolumeManagerService::~VolumeManagerService() {}
33 
VolumeStateNotify(VolumeState state,std::shared_ptr<VolumeExternal> volume)34     void VolumeManagerService::VolumeStateNotify(VolumeState state, std::shared_ptr<VolumeExternal> volume)
35     {
36         DelayedSingleton<Notification>::GetInstance()->NotifyVolumeChange(state, volume);
37     }
38 
OnVolumeCreated(VolumeCore vc)39     void VolumeManagerService::OnVolumeCreated(VolumeCore vc)
40     {
41         auto volumePtr = make_shared<VolumeExternal>(vc);
42         volumeMap_.Insert(volumePtr->GetId(), volumePtr);
43         Mount(volumePtr->GetId());
44     }
45 
OnVolumeStateChanged(string volumeId,VolumeState state)46     void VolumeManagerService::OnVolumeStateChanged(string volumeId, VolumeState state)
47     {
48         if (!volumeMap_.Contains(volumeId)) {
49             LOGE("VolumeManagerService::OnVolumeDestroyed volumeId %{public}s not exists", volumeId.c_str());
50             return;
51         }
52         std::shared_ptr<VolumeExternal> volumePtr = volumeMap_.ReadVal(volumeId);
53         VolumeStateNotify(state, volumePtr);
54         if (state == VolumeState::REMOVED || state == VolumeState::BAD_REMOVAL) {
55             volumeMap_.Erase(volumeId);
56         }
57     }
58 
OnVolumeMounted(std::string volumeId,int fsType,std::string fsUuid,std::string path,std::string description)59     void VolumeManagerService::OnVolumeMounted(std::string volumeId, int fsType, std::string fsUuid,
60         std::string path, std::string description)
61     {
62         if (!volumeMap_.Contains(volumeId)) {
63             LOGE("VolumeManagerService::OnVolumeMounted volumeId %{public}s not exists", volumeId.c_str());
64             return;
65         }
66         std::shared_ptr<VolumeExternal> volumePtr = volumeMap_.ReadVal(volumeId);
67         if (volumePtr == nullptr) {
68             LOGE("volumePtr is nullptr for volumeId");
69             return;
70         }
71         volumePtr->SetFsType(fsType);
72         volumePtr->SetFsUuid(fsUuid);
73         volumePtr->SetPath(path);
74         std::string des = description;
75         auto disk = DelayedSingleton<DiskManagerService>::GetInstance()->GetDiskById(volumePtr->GetDiskId());
76         if (disk != nullptr) {
77             if (des == "") {
78                 if (disk->GetFlag() == SD_FLAG) {
79                     des = "MySDCard";
80                 } else if (disk->GetFlag() == USB_FLAG) {
81                     des = "MyUSB";
82                 } else {
83                     des = "Default";
84                 }
85             }
86         volumePtr->SetFlags(disk->GetFlag());
87         }
88         volumePtr->SetDescription(des);
89         volumePtr->SetState(VolumeState::MOUNTED);
90         VolumeStateNotify(VolumeState::MOUNTED, volumePtr);
91     }
92 
Mount(std::string volumeId)93     int32_t VolumeManagerService::Mount(std::string volumeId)
94     {
95         if (!volumeMap_.Contains(volumeId)) {
96             LOGE("VolumeManagerService::Mount volumeId %{public}s not exists", volumeId.c_str());
97             return E_NON_EXIST;
98         }
99         std::shared_ptr<VolumeExternal> volumePtr = volumeMap_.ReadVal(volumeId);
100         if (volumePtr == nullptr) {
101             LOGE("volumePtr is nullptr for volumeId");
102             return -EFAULT;
103         }
104         if (volumePtr->GetState() != VolumeState::UNMOUNTED) {
105             LOGE("VolumeManagerService::The type of volume(Id %{public}s) is not unmounted", volumeId.c_str());
106             return E_MOUNT;
107         }
108         std::shared_ptr<StorageDaemonCommunication> sdCommunication;
109         sdCommunication = DelayedSingleton<StorageDaemonCommunication>::GetInstance();
110         int32_t result = Check(volumePtr->GetId());
111         if (result == E_OK) {
112             result = sdCommunication->Mount(volumeId, 0);
113             if (result != E_OK) {
114                 volumePtr->SetState(VolumeState::UNMOUNTED);
115             }
116         } else {
117             volumePtr->SetState(VolumeState::UNMOUNTED);
118         }
119         return result;
120     }
121 
Unmount(std::string volumeId)122     int32_t VolumeManagerService::Unmount(std::string volumeId)
123     {
124         if (!volumeMap_.Contains(volumeId)) {
125             LOGE("VolumeManagerService::Unmount volumeId %{public}s not exists", volumeId.c_str());
126             return E_NON_EXIST;
127         }
128         std::shared_ptr<VolumeExternal> volumePtr = volumeMap_.ReadVal(volumeId);
129         if (volumePtr == nullptr) {
130             LOGE("volumePtr is nullptr for volumeId");
131             return -EFAULT;
132         }
133         if (volumePtr->GetState() != VolumeState::MOUNTED) {
134             LOGE("VolumeManagerService::The type of volume(Id %{public}s) is not mounted", volumeId.c_str());
135             return E_UMOUNT;
136         }
137         std::shared_ptr<StorageDaemonCommunication> sdCommunication;
138         sdCommunication = DelayedSingleton<StorageDaemonCommunication>::GetInstance();
139         volumePtr->SetState(VolumeState::EJECTING);
140         int32_t result = sdCommunication->Unmount(volumeId);
141         if (result == E_OK) {
142             volumePtr->SetState(VolumeState::UNMOUNTED);
143             volumePtr->Reset();
144         } else {
145             volumePtr->SetState(VolumeState::MOUNTED);
146         }
147         return result;
148     }
149 
Check(std::string volumeId)150     int32_t VolumeManagerService::Check(std::string volumeId)
151     {
152         std::shared_ptr<VolumeExternal> volumePtr = volumeMap_.ReadVal(volumeId);
153         if (volumePtr == nullptr) {
154             LOGE("volumePtr is nullptr for volumeId");
155             return -EFAULT;
156         }
157         std::shared_ptr<StorageDaemonCommunication> sdCommunication;
158         sdCommunication = DelayedSingleton<StorageDaemonCommunication>::GetInstance();
159         volumePtr->SetState(VolumeState::CHECKING);
160         int32_t result = sdCommunication->Check(volumeId);
161         return result;
162     }
163 
GetAllVolumes()164     vector<VolumeExternal> VolumeManagerService::GetAllVolumes()
165     {
166         vector<VolumeExternal> result;
167         for (auto it = volumeMap_.Begin(); it != volumeMap_.End(); ++it) {
168             VolumeExternal vc = *(it->second);
169             result.push_back(vc);
170         }
171         return result;
172     }
173 
GetVolumeByUuid(std::string volumeUuid)174     std::shared_ptr<VolumeExternal> VolumeManagerService::GetVolumeByUuid(std::string volumeUuid)
175     {
176         for (auto it = volumeMap_.Begin(); it != volumeMap_.End(); ++it) {
177             auto vc = it->second;
178             if (vc->GetUuid() == volumeUuid) {
179                 LOGE("VolumeManagerService::GetVolumeByUuid volumeUuid %{public}s exists",
180                     GetAnonyString(volumeUuid).c_str());
181                 return vc;
182             }
183         }
184         return nullptr;
185     }
186 
GetVolumeByUuid(std::string fsUuid,VolumeExternal & vc)187     int32_t VolumeManagerService::GetVolumeByUuid(std::string fsUuid, VolumeExternal &vc)
188     {
189         for (auto it = volumeMap_.Begin(); it != volumeMap_.End(); ++it) {
190             auto volume = it->second;
191             if (volume->GetUuid() == fsUuid) {
192                 LOGI("VolumeManagerService::GetVolumeByUuid volumeUuid %{public}s exists",
193                     GetAnonyString(fsUuid).c_str());
194                 vc = *volume;
195                 return E_OK;
196             }
197         }
198         return E_NON_EXIST;
199     }
200 
GetVolumeById(std::string volumeId,VolumeExternal & vc)201     int32_t VolumeManagerService::GetVolumeById(std::string volumeId, VolumeExternal &vc)
202     {
203         if (volumeMap_.Contains(volumeId)) {
204             vc = *volumeMap_.ReadVal(volumeId);
205             return E_OK;
206         }
207         return E_NON_EXIST;
208     }
209 
SetVolumeDescription(std::string fsUuid,std::string description)210     int32_t VolumeManagerService::SetVolumeDescription(std::string fsUuid, std::string description)
211     {
212         for (auto it = volumeMap_.Begin(); it != volumeMap_.End(); ++it) {
213             auto volume = it->second;
214             if (volume->GetUuid() == fsUuid) {
215                 LOGI("VolumeManagerService::SetVolumeDescription volumeUuid %{public}s exists",
216                     GetAnonyString(fsUuid).c_str());
217                 if (volume->GetState() != VolumeState::UNMOUNTED) {
218                     LOGE("VolumeManagerService::SetVolumeDescription volume state is not unmounted!");
219                     return E_VOL_STATE;
220                 }
221                 std::shared_ptr<StorageDaemonCommunication> sdCommunication;
222                 sdCommunication = DelayedSingleton<StorageDaemonCommunication>::GetInstance();
223                 return sdCommunication->SetVolumeDescription(volume->GetId(), description);
224             }
225         }
226         return E_NON_EXIST;
227     }
228 
Format(std::string volumeId,std::string fsType)229     int32_t VolumeManagerService::Format(std::string volumeId, std::string fsType)
230     {
231         if (volumeMap_.Find(volumeId) == volumeMap_.End()) {
232             return E_NON_EXIST;
233         }
234         if (volumeMap_.ReadVal(volumeId)->GetState() != VolumeState::UNMOUNTED) {
235             LOGE("VolumeManagerService::SetVolumeDescription volume state is not unmounted!");
236             return E_VOL_STATE;
237         }
238         // check fstype!!!!
239         std::shared_ptr<StorageDaemonCommunication> sdCommunication;
240         sdCommunication = DelayedSingleton<StorageDaemonCommunication>::GetInstance();
241         return sdCommunication->Format(volumeId, fsType);
242     }
243 } // StorageManager
244 } // OHOS
245