* Copyright (C) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define MLOG_TAG "MtpStorageManager"
#include "mtp_storage_manager.h"
#include <filesystem>
#include <mutex>
#include "media_log.h"
#include "medialibrary_errno.h"
#include "parameter.h"
using namespace std;
namespace OHOS {
namespace Media {
namespace {
enum SizeType {
TOTAL,
FREE,
USED
};
const std::string PUBLIC_PATH_DATA = "/storage/media/local/files/Docs";
const std::string CHINESE_ABBREVIATION = "zh-Hans";
const std::string ENGLISH_ABBREVIATION = "en-Latn-US";
const std::string EXTER_STORAGE_DESC_ZH = "存储卡";
const std::string EXTER_STORAGE_DESC_EN = "Memory Card";
const std::string UNSPECIFIED = "Unspecified";
const std::string DESC_PHONE_ZH = "我的手机";
const std::string DESC_PHONE_EN = "My phone";
const std::string DESC_TABLET_ZH = "我的平板";
const std::string DESC_TABLET_EN = "My tablet";
const std::string DEVICE_PHONE = "phone";
const std::string DEVICE_TABLET = "tablet";
const std::string DEVICE_TYPE_KEY = "const.product.devicetype";
const std::string LANGUAGE_KEY = "persist.global.language";
const std::string DEFAULT_LANGUAGE_KEY = "const.global.language";
constexpr int32_t SYSPARA_SIZE = 64;
}
std::shared_ptr<MtpStorageManager> MtpStorageManager::instance_ = nullptr;
std::mutex MtpStorageManager::mutex_;
std::shared_ptr<MtpStorageManager> MtpStorageManager::GetInstance()
{
if (instance_ == nullptr) {
std::lock_guard<std::mutex> lock(mutex_);
if (instance_ == nullptr) {
instance_ = std::make_shared<MtpStorageManager>();
}
}
return instance_;
}
int64_t MtpStorageManager::GetTotalSize(const std::string &path)
{
std::string p = path.empty() ? PUBLIC_PATH_DATA : path;
std::error_code ec;
auto info = std::filesystem::space(p, ec);
CHECK_AND_RETURN_RET_LOG(ec.value() == E_OK, 0, "GetTotalSize failed, errno: %{public}d", errno);
return info.capacity;
}
int64_t MtpStorageManager::GetFreeSize(const std::string &path)
{
std::string p = path.empty() ? PUBLIC_PATH_DATA : path;
std::error_code ec;
auto info = std::filesystem::space(p, ec);
CHECK_AND_RETURN_RET_LOG(ec.value() == E_OK, 0, "GetFreeSize failed, errno: %{public}d", errno);
return info.available;
}
void MtpStorageManager::AddStorage(shared_ptr<Storage> &storage)
{
if (!storages.empty()) {
for (auto stor : storages) {
if (stor->GetStorageID() == storage->GetStorageID()) {
return;
}
}
}
storages.push_back(storage);
}
void MtpStorageManager::RemoveStorage(std::shared_ptr<Storage> &storage)
{
auto iter = std::find(storages.begin(), storages.end(), storage);
if (iter != storages.end()) {
storages.erase(iter);
}
}
shared_ptr<Storage> MtpStorageManager::GetStorage(uint32_t id)
{
for (auto storage : storages) {
if (storage->GetStorageID() == id) {
return storage;
}
}
return nullptr;
}
bool MtpStorageManager::HasStorage(uint32_t id)
{
bool result = false;
if (id == MTP_STORAGE_ID_ALL || id == MTP_STORAGE_ID_ALL2) {
result = (storages.size() > 0);
} else {
result = (GetStorage(id) != nullptr);
}
return result;
}
std::vector<std::shared_ptr<Storage>> MtpStorageManager::GetStorages()
{
return storages;
}
void MtpStorageManager::ClearStorages()
{
std::vector<std::shared_ptr<Storage>>().swap(storages);
}
std::string MtpStorageManager::GetSystemLanguage()
{
char param[SYSPARA_SIZE] = {0};
int status = GetParameter(LANGUAGE_KEY.c_str(), "", param, SYSPARA_SIZE);
CHECK_AND_RETURN_RET(status <= 0, param);
status = GetParameter(DEFAULT_LANGUAGE_KEY.c_str(), "", param, SYSPARA_SIZE);
CHECK_AND_RETURN_RET(status <= 0, param);
MEDIA_ERR_LOG("Failed to get system language");
return "";
}
std::string MtpStorageManager::GetDeviceType()
{
char param[SYSPARA_SIZE] = {0};
int status = GetParameter(DEVICE_TYPE_KEY.c_str(), DEVICE_PHONE.c_str(), param, SYSPARA_SIZE);
CHECK_AND_RETURN_RET(status <= 0, DEVICE_PHONE);
return std::string(param);
}
std::string MtpStorageManager::GetStorageDescriptionByDeviceType(const std::string &language)
{
const std::string deviceType = GetDeviceType();
if (deviceType == DEVICE_PHONE) {
return language == CHINESE_ABBREVIATION ? DESC_PHONE_ZH : DESC_PHONE_EN;
} else if (deviceType == DEVICE_TABLET) {
return language == CHINESE_ABBREVIATION ? DESC_TABLET_ZH : DESC_TABLET_EN;
} else {
MEDIA_ERR_LOG("language[%{public}s] deviceType[%{public}s] is unknown",
language.c_str(), deviceType.c_str());
return UNSPECIFIED;
}
}
std::string MtpStorageManager::GetStorageDescription(const uint16_t type)
{
std::string language = GetSystemLanguage();
if (language.empty()) {
language = CHINESE_ABBREVIATION;
}
switch (type) {
case MTP_STORAGE_FIXEDRAM:
return GetStorageDescriptionByDeviceType(language);
case MTP_STORAGE_REMOVABLERAM:
return language == CHINESE_ABBREVIATION ? EXTER_STORAGE_DESC_ZH : EXTER_STORAGE_DESC_EN;
default:
break;
}
return UNSPECIFIED;
}
}
}