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 "volumemanager_n_exporter.h"
17 
18 #include <singleton.h>
19 #include <tuple>
20 
21 #include "n_async/n_async_work_callback.h"
22 #include "n_async/n_async_work_promise.h"
23 #include "n_class.h"
24 #include "n_error.h"
25 #include "n_func_arg.h"
26 #include "n_val.h"
27 #include "storage_manager_connect.h"
28 #include "storage_service_errno.h"
29 #include "storage_service_log.h"
30 
31 using namespace OHOS::StorageManager;
32 using namespace OHOS::FileManagement::LibN;
33 
34 namespace OHOS {
35 namespace StorageManager {
36 namespace ModuleVolumeManager {
CheckVolumes(napi_env env,napi_callback_info info,NFuncArg & funcArg)37 bool CheckVolumes(napi_env env, napi_callback_info info, NFuncArg& funcArg)
38 {
39     if (!IsSystemApp()) {
40         NError(E_PERMISSION_SYS).ThrowErr(env);
41         return false;
42     }
43     if (!funcArg.InitArgs((int)NARG_CNT::ZERO, (int)NARG_CNT::ONE)) {
44         NError(E_PARAMS).ThrowErr(env);
45         return false;
46     }
47     return true;
48 }
49 
GetAllVolumes(napi_env env,napi_callback_info info)50 napi_value GetAllVolumes(napi_env env, napi_callback_info info)
51 {
52     NFuncArg funcArg(env, info);
53     bool checkresult = CheckVolumes(env, info, funcArg);
54     if (!checkresult) {
55         return nullptr;
56     }
57     auto volumeInfo = std::make_shared<std::vector<VolumeExternal>>();
58     auto cbExec = [volumeInfo]() -> NError {
59         int32_t errNum = DelayedSingleton<StorageManagerConnect>::GetInstance()->GetAllVolumes(*volumeInfo);
60         if (errNum != E_OK) {
61             return NError(Convert2JsErrNum(errNum));
62         }
63         return NError(ERRNO_NOERR);
64     };
65     auto cbComplete = [volumeInfo](napi_env env, NError err) -> NVal {
66         if (err) {
67             return { env, err.GetNapiErr(env) };
68         }
69         napi_value volumeInfoArray = nullptr;
70         napi_status status = napi_create_array(env, &volumeInfoArray);
71         if (status != napi_ok) {
72             return { env, NError(status).GetNapiErr(env) };
73         }
74         for (size_t i = 0; i < (*volumeInfo).size(); i++) {
75             NVal volumeInfoObject = NVal::CreateObject(env);
76             volumeInfoObject.AddProp("id", NVal::CreateUTF8String(env, (*volumeInfo)[i].GetId()).val_);
77             volumeInfoObject.AddProp("uuid", NVal::CreateUTF8String(env, (*volumeInfo)[i].GetUuid()).val_);
78             volumeInfoObject.AddProp("diskId", NVal::CreateUTF8String(env, (*volumeInfo)[i].GetDiskId()).val_);
79             volumeInfoObject.AddProp("description",
80                 NVal::CreateUTF8String(env, (*volumeInfo)[i].GetDescription()).val_);
81             volumeInfoObject.AddProp("removable", NVal::CreateBool(env, (bool)true).val_);
82             volumeInfoObject.AddProp("state", NVal::CreateInt32(env, (*volumeInfo)[i].GetState()).val_);
83             volumeInfoObject.AddProp("path", NVal::CreateUTF8String(env, (*volumeInfo)[i].GetPath()).val_);
84             volumeInfoObject.AddProp("fsType", NVal::CreateUTF8String(env, (*volumeInfo)[i].GetFsTypeString()).val_);
85             status = napi_set_element(env, volumeInfoArray, i, volumeInfoObject.val_);
86             if (status != napi_ok) {
87                 return { env, NError(status).GetNapiErr(env) };
88             }
89         }
90         return { NVal(env, volumeInfoArray) };
91     };
92     std::string procedureName = "GetAllVolumes";
93     NVal thisVar(env, funcArg.GetThisVar());
94     if (funcArg.GetArgc() == (uint)NARG_CNT::ZERO) {
95         return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_;
96     } else {
97         NVal cb(env, funcArg[(int)NARG_POS::FIRST]);
98         return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_;
99     }
100 }
101 
CheckMount(napi_env env,napi_callback_info info,NFuncArg & funcArg)102 bool CheckMount(napi_env env, napi_callback_info info, NFuncArg& funcArg)
103 {
104     if (!IsSystemApp()) {
105         NError(E_PERMISSION_SYS).ThrowErr(env);
106         return false;
107     }
108     if (!funcArg.InitArgs((int)NARG_CNT::ONE, (int)NARG_CNT::TWO)) {
109         NError(E_PARAMS).ThrowErr(env);
110         return false;
111     }
112     return true;
113 }
114 
115 
Mount(napi_env env,napi_callback_info info)116 napi_value Mount(napi_env env, napi_callback_info info)
117 {
118     NFuncArg funcArg(env, info);
119     bool checkresult = CheckMount(env, info, funcArg);
120     if (!checkresult) {
121         return nullptr;
122     }
123     bool succ = false;
124     std::unique_ptr<char []> volumeId;
125     tie(succ, volumeId, std::ignore) = NVal(env, funcArg[(int)NARG_POS::FIRST]).ToUTF8String();
126     if (!succ) {
127         NError(E_PARAMS).ThrowErr(env);
128         return nullptr;
129     }
130 
131     std::string volumeIdString(volumeId.get());
132     auto cbExec = [volumeIdString]() -> NError {
133         int32_t result = DelayedSingleton<StorageManagerConnect>::GetInstance()->Mount(volumeIdString);
134         if (result != E_OK) {
135             return NError(Convert2JsErrNum(result));
136         }
137         return NError(ERRNO_NOERR);
138     };
139     auto cbComplete = [](napi_env env, NError err) -> NVal {
140         if (err) {
141             return { env, err.GetNapiErr(env) };
142         }
143         return { NVal::CreateUndefined(env) };
144     };
145 
146     std::string procedureName = "Mount";
147     NVal thisVar(env, funcArg.GetThisVar());
148     if (funcArg.GetArgc() == (uint)NARG_CNT::ONE) {
149         return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_;
150     } else {
151         NVal cb(env, funcArg[(int)NARG_POS::SECOND]);
152         return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_;
153     }
154 }
155 
Unmount(napi_env env,napi_callback_info info)156 napi_value Unmount(napi_env env, napi_callback_info info)
157 {
158     NFuncArg funcArg(env, info);
159     bool checkresult = CheckMount(env, info, funcArg);
160     if (!checkresult) {
161         return nullptr;
162     }
163     bool succ = false;
164     std::unique_ptr<char []> volumeId;
165     tie(succ, volumeId, std::ignore) = NVal(env, funcArg[(int)NARG_POS::FIRST]).ToUTF8String();
166     if (!succ) {
167         NError(E_PARAMS).ThrowErr(env);
168         return nullptr;
169     }
170 
171     std::string volumeIdString(volumeId.get());
172     auto cbExec = [volumeIdString]() -> NError {
173         int32_t result = DelayedSingleton<StorageManagerConnect>::GetInstance()->Unmount(volumeIdString);
174         if (result != E_OK) {
175             return NError(Convert2JsErrNum(result));
176         }
177         return NError(ERRNO_NOERR);
178     };
179     auto cbComplete = [](napi_env env, NError err) -> NVal {
180         if (err) {
181             return { env, err.GetNapiErr(env) };
182         }
183         return { NVal::CreateUndefined(env) };
184     };
185 
186     std::string procedureName = "Unmount";
187     NVal thisVar(env, funcArg.GetThisVar());
188     if (funcArg.GetArgc() == (uint)NARG_CNT::ONE) {
189         return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_;
190     } else {
191         NVal cb(env, funcArg[(int)NARG_POS::SECOND]);
192         return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_;
193     }
194 }
195 
196 
GetVolumeByUuid(napi_env env,napi_callback_info info)197 napi_value GetVolumeByUuid(napi_env env, napi_callback_info info)
198 {
199     NFuncArg funcArg(env, info);
200     bool checkresult = CheckMount(env, info, funcArg);
201     if (!checkresult) {
202         return nullptr;
203     }
204     bool succ = false;
205     std::unique_ptr<char []> uuid;
206     tie(succ, uuid, std::ignore) = NVal(env, funcArg[(int)NARG_POS::FIRST]).ToUTF8String();
207     if (!succ) {
208         NError(E_PARAMS).ThrowErr(env);
209         return nullptr;
210     }
211     auto volumeInfo = std::make_shared<VolumeExternal>();
212     std::string uuidString(uuid.get());
213     auto cbExec = [uuidString, volumeInfo]() -> NError {
214         int32_t errNum = DelayedSingleton<StorageManagerConnect>::GetInstance()->GetVolumeByUuid(uuidString,
215             *volumeInfo);
216         if (errNum != E_OK) {
217             return NError(Convert2JsErrNum(errNum));
218         }
219         return NError(ERRNO_NOERR);
220     };
221     auto cbComplete = [volumeInfo](napi_env env, NError err) -> NVal {
222         if (err) {
223             return { env, err.GetNapiErr(env) };
224         }
225         NVal volumeObject = NVal::CreateObject(env);
226         volumeObject.AddProp("id", NVal::CreateUTF8String(env, volumeInfo->GetId()).val_);
227         volumeObject.AddProp("uuid", NVal::CreateUTF8String(env, volumeInfo->GetUuid()).val_);
228         volumeObject.AddProp("diskId", NVal::CreateUTF8String(env, volumeInfo->GetDiskId()).val_);
229         volumeObject.AddProp("description",
230             NVal::CreateUTF8String(env, volumeInfo->GetDescription()).val_);
231         volumeObject.AddProp("removable", NVal::CreateBool(env, (bool)true).val_);
232         volumeObject.AddProp("state", NVal::CreateInt32(env, volumeInfo->GetState()).val_);
233         volumeObject.AddProp("path", NVal::CreateUTF8String(env, volumeInfo->GetPath()).val_);
234         volumeObject.AddProp("fsType", NVal::CreateUTF8String(env, volumeInfo->GetFsTypeString()).val_);
235 
236         return volumeObject;
237     };
238 
239     std::string procedureName = "GetVolumeByUuid";
240     NVal thisVar(env, funcArg.GetThisVar());
241     if (funcArg.GetArgc() == (uint)NARG_CNT::ONE) {
242         return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_;
243     } else {
244         NVal cb(env, funcArg[(int)NARG_POS::SECOND]);
245         return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_;
246     }
247 }
248 
249 
GetVolumeById(napi_env env,napi_callback_info info)250 napi_value GetVolumeById(napi_env env, napi_callback_info info)
251 {
252     NFuncArg funcArg(env, info);
253     bool checkresult = CheckMount(env, info, funcArg);
254     if (!checkresult) {
255         return nullptr;
256     }
257     bool succ = false;
258     std::unique_ptr<char []> volumeId;
259     tie(succ, volumeId, std::ignore) = NVal(env, funcArg[(int)NARG_POS::FIRST]).ToUTF8String();
260     if (!succ) {
261         NError(E_PARAMS).ThrowErr(env);
262         return nullptr;
263     }
264 
265     auto volumeInfo = std::make_shared<VolumeExternal>();
266     std::string volumeIdString(volumeId.get());
267     auto cbExec = [volumeIdString, volumeInfo]() -> NError {
268         int32_t errNum = DelayedSingleton<StorageManagerConnect>::GetInstance()->GetVolumeById(volumeIdString,
269             *volumeInfo);
270         if (errNum != E_OK) {
271             return NError(Convert2JsErrNum(errNum));
272         }
273         return NError(ERRNO_NOERR);
274     };
275     auto cbComplete = [volumeInfo](napi_env env, NError err) -> NVal {
276         if (err) {
277             return { env, err.GetNapiErr(env) };
278         }
279         NVal volumeObject = NVal::CreateObject(env);
280         volumeObject.AddProp("id", NVal::CreateUTF8String(env, volumeInfo->GetId()).val_);
281         volumeObject.AddProp("uuid", NVal::CreateUTF8String(env, volumeInfo->GetUuid()).val_);
282         volumeObject.AddProp("diskId", NVal::CreateUTF8String(env, volumeInfo->GetDiskId()).val_);
283         volumeObject.AddProp("description",
284             NVal::CreateUTF8String(env, volumeInfo->GetDescription()).val_);
285         volumeObject.AddProp("removable", NVal::CreateBool(env, (bool)true).val_);
286         volumeObject.AddProp("state", NVal::CreateInt32(env, volumeInfo->GetState()).val_);
287         volumeObject.AddProp("path", NVal::CreateUTF8String(env, volumeInfo->GetPath()).val_);
288 
289         return volumeObject;
290     };
291 
292     std::string procedureName = "GetVolumeById";
293     NVal thisVar(env, funcArg.GetThisVar());
294     if (funcArg.GetArgc() == (uint)NARG_CNT::ONE) {
295         return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_;
296     } else {
297         NVal cb(env, funcArg[(int)NARG_POS::SECOND]);
298         return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_;
299     }
300 }
301 
SetVolumeDescription(napi_env env,napi_callback_info info)302 napi_value SetVolumeDescription(napi_env env, napi_callback_info info)
303 {
304     if (!IsSystemApp()) {
305         NError(E_PERMISSION_SYS).ThrowErr(env);
306         return nullptr;
307     }
308     NFuncArg funcArg(env, info);
309     if (!funcArg.InitArgs((int)NARG_CNT::TWO, (int)NARG_CNT::THREE)) {
310         NError(E_PARAMS).ThrowErr(env);
311         return nullptr;
312     }
313 
314     bool succ = false;
315     std::unique_ptr<char []> uuid;
316     std::unique_ptr<char []> description;
317     tie(succ, uuid, std::ignore) = NVal(env, funcArg[(int)NARG_POS::FIRST]).ToUTF8String();
318     if (!succ) {
319         NError(E_PARAMS).ThrowErr(env);
320         return nullptr;
321     }
322 
323     tie(succ, description, std::ignore) = NVal(env, funcArg[(int)NARG_POS::SECOND]).ToUTF8String();
324     if (!succ) {
325         NError(E_PARAMS).ThrowErr(env);
326         return nullptr;
327     }
328 
329     std::string uuidString(uuid.get());
330     std::string descStr(description.get());
331     auto cbExec = [uuidString, descStr]() -> NError {
332         int32_t result = DelayedSingleton<StorageManagerConnect>::GetInstance()->SetVolumeDescription(uuidString,
333             descStr);
334         if (result != E_OK) {
335             return NError(Convert2JsErrNum(result));
336         }
337         return NError(ERRNO_NOERR);
338     };
339     auto cbComplete = [](napi_env env, NError err) -> NVal {
340         if (err) {
341             return { env, err.GetNapiErr(env) };
342         }
343         return { NVal::CreateUndefined(env) };
344     };
345 
346     std::string procedureName = "SetVolumeDescription";
347     NVal thisVar(env, funcArg.GetThisVar());
348     if (funcArg.GetArgc() == (uint)NARG_CNT::TWO) {
349         return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_;
350     } else {
351         NVal cb(env, funcArg[(int)NARG_POS::THIRD]);
352         return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_;
353     }
354 }
355 
Format(napi_env env,napi_callback_info info)356 napi_value Format(napi_env env, napi_callback_info info)
357 {
358     if (!IsSystemApp()) {
359         NError(E_PERMISSION_SYS).ThrowErr(env);
360         return nullptr;
361     }
362     NFuncArg funcArg(env, info);
363     if (!funcArg.InitArgs((int)NARG_CNT::TWO, (int)NARG_CNT::THREE)) {
364         NError(E_PARAMS).ThrowErr(env);
365         return nullptr;
366     }
367 
368     bool succ = false;
369     std::unique_ptr<char []> volumeId;
370     std::unique_ptr<char []> fsType;
371     tie(succ, volumeId, std::ignore) = NVal(env, funcArg[(int)NARG_POS::FIRST]).ToUTF8String();
372     if (!succ) {
373         NError(E_PARAMS).ThrowErr(env);
374         return nullptr;
375     }
376 
377     tie(succ, fsType, std::ignore) = NVal(env, funcArg[(int)NARG_POS::SECOND]).ToUTF8String();
378     if (!succ) {
379         NError(E_PARAMS).ThrowErr(env);
380         return nullptr;
381     }
382 
383     std::string volumeIdString(volumeId.get());
384     std::string fsTypeString(fsType.get());
385     auto cbExec = [volumeIdString, fsTypeString]() -> NError {
386         int32_t result = DelayedSingleton<StorageManagerConnect>::GetInstance()->Format(volumeIdString, fsTypeString);
387         if (result != E_OK) {
388             return NError(Convert2JsErrNum(result));
389         }
390         return NError(ERRNO_NOERR);
391     };
392     auto cbComplete = [](napi_env env, NError err) -> NVal {
393         if (err) {
394             return { env, err.GetNapiErr(env) };
395         }
396         return { NVal::CreateUndefined(env) };
397     };
398 
399     std::string procedureName = "Format";
400     NVal thisVar(env, funcArg.GetThisVar());
401     if (funcArg.GetArgc() == (uint)NARG_CNT::TWO) {
402         return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_;
403     } else {
404         NVal cb(env, funcArg[(int)NARG_POS::THIRD]);
405         return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_;
406     }
407 }
408 
Partition(napi_env env,napi_callback_info info)409 napi_value Partition(napi_env env, napi_callback_info info)
410 {
411     if (!IsSystemApp()) {
412         NError(E_PERMISSION_SYS).ThrowErr(env);
413         return nullptr;
414     }
415     NFuncArg funcArg(env, info);
416     if (!funcArg.InitArgs((int)NARG_CNT::TWO, (int)NARG_CNT::THREE)) {
417         NError(E_PARAMS).ThrowErr(env);
418         return nullptr;
419     }
420 
421     bool succ = false;
422     std::unique_ptr<char []> diskId;
423     int32_t type;
424     tie(succ, diskId, std::ignore) = NVal(env, funcArg[(int)NARG_POS::FIRST]).ToUTF8String();
425     if (!succ) {
426         NError(E_PARAMS).ThrowErr(env);
427         return nullptr;
428     }
429 
430     std::tie(succ, type) = NVal(env, funcArg[(int)NARG_POS::SECOND]).ToInt32();
431     if (!succ) {
432         NError(E_PARAMS).ThrowErr(env);
433         return nullptr;
434     }
435 
436     std::string diskIdString(diskId.get());
437     auto cbExec = [diskIdString, type]() -> NError {
438         int32_t result = DelayedSingleton<StorageManagerConnect>::GetInstance()->Partition(diskIdString, type);
439         if (result != E_OK) {
440             return NError(Convert2JsErrNum(result));
441         }
442         return NError(ERRNO_NOERR);
443     };
444     auto cbComplete = [](napi_env env, NError err) -> NVal {
445         if (err) {
446             return { env, err.GetNapiErr(env) };
447         }
448         return { NVal::CreateUndefined(env) };
449     };
450 
451     std::string procedureName = "Partition";
452     NVal thisVar(env, funcArg.GetThisVar());
453     if (funcArg.GetArgc() == (uint)NARG_CNT::TWO) {
454         return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_;
455     } else {
456         NVal cb(env, funcArg[(int)NARG_POS::THIRD]);
457         return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_;
458     }
459 }
460 } // namespace ModuleVolumeManager
461 } // namespace StorageManager
462 } // namespace OHOS
463