1 /*
2  * Copyright (C) 2021-2022 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 #define MLOG_TAG "MtpStorageManager"
16 #include "mtp_storage_manager.h"
17 #include <filesystem>
18 #include <mutex>
19 #include "media_log.h"
20 #include "medialibrary_errno.h"
21 #include "parameter.h"
22 
23 using namespace std;
24 
25 namespace OHOS {
26 namespace Media {
27 namespace {
28 enum SizeType {
29     TOTAL,
30     FREE,
31     USED
32 };
33 const std::string PUBLIC_PATH_DATA      = "/storage/media/local/files/Docs";
34 const std::string CHINESE_ABBREVIATION  = "zh-Hans";
35 const std::string ENGLISH_ABBREVIATION  = "en-Latn-US";
36 const std::string INNER_STORAGE_DESC_ZH = "内部存储";
37 const std::string INNER_STORAGE_DESC_EN = "Internal storage";
38 const std::string EXTER_STORAGE_DESC_ZH = "存储卡";
39 const std::string EXTER_STORAGE_DESC_EN = "Memory Card";
40 const std::string UNSPECIFIED           = "Unspecified";
41 const std::string LANGUAGE_KEY          = "persist.global.language";
42 const std::string DEFAULT_LANGUAGE_KEY  = "const.global.language";
43 constexpr int32_t SYSPARA_SIZE          = 64;
44 } // namespace
45 
46 std::shared_ptr<MtpStorageManager> MtpStorageManager::instance_ = nullptr;
47 std::mutex MtpStorageManager::mutex_;
48 
GetInstance()49 std::shared_ptr<MtpStorageManager> MtpStorageManager::GetInstance()
50 {
51     if (instance_ == nullptr) {
52         std::lock_guard<std::mutex> lock(mutex_);
53         if (instance_ == nullptr) {
54             instance_ = std::shared_ptr<MtpStorageManager>(new MtpStorageManager());
55         }
56     }
57     return instance_;
58 }
59 
GetTotalSize(const std::string & path)60 int64_t MtpStorageManager::GetTotalSize(const std::string &path)
61 {
62     std::string p = path.empty() ? PUBLIC_PATH_DATA : path;
63     std::error_code ec;
64     auto info = std::filesystem::space(p, ec);
65     if (ec.value() != E_OK) {
66         MEDIA_ERR_LOG("GetTotalSize failed, errno: %{public}d", errno);
67         return 0;
68     }
69 
70     return info.capacity;
71 }
72 
GetFreeSize(const std::string & path)73 int64_t MtpStorageManager::GetFreeSize(const std::string &path)
74 {
75     std::string p = path.empty() ? PUBLIC_PATH_DATA : path;
76     std::error_code ec;
77     auto info = std::filesystem::space(p, ec);
78     if (ec.value() != E_OK) {
79         MEDIA_ERR_LOG("GetFreeSize failed, errno: %{public}d", errno);
80         return 0;
81     }
82 
83     return info.free;
84 }
85 
AddStorage(shared_ptr<Storage> & storage)86 void MtpStorageManager::AddStorage(shared_ptr<Storage> &storage)
87 {
88     if (!storages.empty()) {
89         for (auto stor : storages) {
90             if (stor->GetStorageID() == storage->GetStorageID()) {
91                 return;
92             }
93         }
94     }
95     storages.push_back(storage);
96 }
97 
RemoveStorage(std::shared_ptr<Storage> & storage)98 void MtpStorageManager::RemoveStorage(std::shared_ptr<Storage> &storage)
99 {
100     auto iter = std::find(storages.begin(), storages.end(), storage);
101     if (iter != storages.end()) {
102         storages.erase(iter);
103     }
104 }
105 
GetStorage(uint32_t id)106 shared_ptr<Storage> MtpStorageManager::GetStorage(uint32_t id)
107 {
108     for (auto storage : storages) {
109         if (storage->GetStorageID() == id) {
110             return storage;
111         }
112     }
113     return nullptr;
114 }
115 
HasStorage(uint32_t id)116 bool MtpStorageManager::HasStorage(uint32_t id)
117 {
118     bool result = false;
119 
120     if (id == MTP_STORAGE_ID_ALL || id == MTP_STORAGE_ID_ALL2) {
121         result = (storages.size() > 0);
122     } else {
123         result = (GetStorage(id) != nullptr);
124     }
125 
126     return result;
127 }
128 
GetStorages()129 std::vector<std::shared_ptr<Storage>> MtpStorageManager::GetStorages()
130 {
131     return storages;
132 }
133 
ClearStorages()134 void MtpStorageManager::ClearStorages()
135 {
136     std::vector<std::shared_ptr<Storage>>().swap(storages);
137 }
138 
GetSystemLanguage()139 std::string MtpStorageManager::GetSystemLanguage()
140 {
141     char param[SYSPARA_SIZE] = {0};
142     int status = GetParameter(LANGUAGE_KEY.c_str(), "", param, SYSPARA_SIZE);
143     if (status > 0) {
144         return param;
145     }
146     status = GetParameter(DEFAULT_LANGUAGE_KEY.c_str(), "", param, SYSPARA_SIZE);
147     if (status > 0) {
148         return param;
149     }
150     MEDIA_ERR_LOG("Failed to get system language");
151     return "";
152 }
153 
GetStorageDescription(const uint16_t type)154 std::string MtpStorageManager::GetStorageDescription(const uint16_t type)
155 {
156     std::string language = GetSystemLanguage();
157     if (language.empty()) {
158         language = CHINESE_ABBREVIATION;
159     }
160     switch (type) {
161         case MTP_STORAGE_FIXEDRAM:
162             return language == CHINESE_ABBREVIATION ? INNER_STORAGE_DESC_ZH : INNER_STORAGE_DESC_EN;
163         case MTP_STORAGE_REMOVABLERAM:
164             return language == CHINESE_ABBREVIATION ? EXTER_STORAGE_DESC_ZH : EXTER_STORAGE_DESC_EN;
165         default:
166             break;
167     }
168     return UNSPECIFIED;
169 }
170 
171 }  // namespace Media
172 }  // namespace OHOS
173