13e5483f6Sopenharmony_ci/*
23e5483f6Sopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd.
33e5483f6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43e5483f6Sopenharmony_ci * you may not use this file except in compliance with the License.
53e5483f6Sopenharmony_ci * You may obtain a copy of the License at
63e5483f6Sopenharmony_ci *
73e5483f6Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83e5483f6Sopenharmony_ci *
93e5483f6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103e5483f6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113e5483f6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123e5483f6Sopenharmony_ci * See the License for the specific language governing permissions and
133e5483f6Sopenharmony_ci * limitations under the License.
143e5483f6Sopenharmony_ci */
153e5483f6Sopenharmony_ci#define MLOG_TAG "FileUtils"
163e5483f6Sopenharmony_ci
173e5483f6Sopenharmony_ci#include "ringtone_file_utils.h"
183e5483f6Sopenharmony_ci
193e5483f6Sopenharmony_ci#include <dirent.h>
203e5483f6Sopenharmony_ci#include <fcntl.h>
213e5483f6Sopenharmony_ci#include <ftw.h>
223e5483f6Sopenharmony_ci#include <fstream>
233e5483f6Sopenharmony_ci#include <sstream>
243e5483f6Sopenharmony_ci#include <sys/sendfile.h>
253e5483f6Sopenharmony_ci#include <unistd.h>
263e5483f6Sopenharmony_ci#include <iostream>
273e5483f6Sopenharmony_ci
283e5483f6Sopenharmony_ci#include "directory_ex.h"
293e5483f6Sopenharmony_ci#include "ringtone_db_const.h"
303e5483f6Sopenharmony_ci#include "ringtone_errno.h"
313e5483f6Sopenharmony_ci#include "ringtone_log.h"
323e5483f6Sopenharmony_ci#include "ringtone_mimetype_utils.h"
333e5483f6Sopenharmony_ci#include "ringtone_type.h"
343e5483f6Sopenharmony_ci#include "vibrate_type.h"
353e5483f6Sopenharmony_ci#include "securec.h"
363e5483f6Sopenharmony_ci
373e5483f6Sopenharmony_cinamespace OHOS {
383e5483f6Sopenharmony_cinamespace Media {
393e5483f6Sopenharmony_ciusing namespace std;
403e5483f6Sopenharmony_cistatic const int32_t OPEN_FDS = 128;
413e5483f6Sopenharmony_cistatic const mode_t MODE_RWX_USR_GRP = 02771;
423e5483f6Sopenharmony_cistatic const mode_t MODE_RW_USR = 0644;
433e5483f6Sopenharmony_ciconst vector<string> EXIF_SUPPORTED_EXTENSION = {
443e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_3GA,
453e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_AC3,
463e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_A52,
473e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_AMR,
483e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_IMY,
493e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_RTTTL,
503e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_XMF,
513e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_RTX,
523e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_MXMF,
533e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_M4A,
543e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_M4B,
553e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_M4P,
563e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_F4A,
573e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_F4B,
583e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_F4P,
593e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_M3U,
603e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_SMF,
613e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_MKA,
623e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_RA,
633e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_MP3,
643e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_AAC,
653e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_ADTS,
663e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_ADT,
673e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_SND,
683e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_FLAC,
693e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_MP2,
703e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_MP1,
713e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_MPA,
723e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_M4R,
733e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_WAV,
743e5483f6Sopenharmony_ci    RINGTONE_CONTAINER_TYPE_OGG
753e5483f6Sopenharmony_ci};
763e5483f6Sopenharmony_ci
773e5483f6Sopenharmony_cistatic bool IsTargetExtension(const string &path)
783e5483f6Sopenharmony_ci{
793e5483f6Sopenharmony_ci    const string ext = RingtoneFileUtils::GetExtensionFromPath(path);
803e5483f6Sopenharmony_ci    std::string mimeType = RingtoneMimeTypeUtils::GetMimeTypeFromExtension(ext);
813e5483f6Sopenharmony_ci    int32_t mime = RingtoneMimeTypeUtils::GetMediaTypeFromMimeType(mimeType);
823e5483f6Sopenharmony_ci    if (mime == RINGTONE_MEDIA_TYPE_AUDIO) {
833e5483f6Sopenharmony_ci        return true;
843e5483f6Sopenharmony_ci    }
853e5483f6Sopenharmony_ci    RINGTONE_ERR_LOG("MimeType error:%{public}s,%{public}s", ext.c_str(), mimeType.c_str());
863e5483f6Sopenharmony_ci    bool ret = find(EXIF_SUPPORTED_EXTENSION.begin(), EXIF_SUPPORTED_EXTENSION.end(), ext) !=
873e5483f6Sopenharmony_ci        EXIF_SUPPORTED_EXTENSION.end();
883e5483f6Sopenharmony_ci    if (!ret) {
893e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("invalid target extension:%{public}s", ext.c_str());
903e5483f6Sopenharmony_ci    }
913e5483f6Sopenharmony_ci    return ret;
923e5483f6Sopenharmony_ci}
933e5483f6Sopenharmony_ci
943e5483f6Sopenharmony_cistatic bool IsVibrateFile(const string &path)
953e5483f6Sopenharmony_ci{
963e5483f6Sopenharmony_ci    const string ext = RingtoneFileUtils::GetExtensionFromPath(path);
973e5483f6Sopenharmony_ci    bool ret = (ext == VIBRATE_CONTAINER_TYPE_JSON);
983e5483f6Sopenharmony_ci    if (!ret) {
993e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("invalid target extension:%{public}s", ext.c_str());
1003e5483f6Sopenharmony_ci    }
1013e5483f6Sopenharmony_ci    return ret;
1023e5483f6Sopenharmony_ci}
1033e5483f6Sopenharmony_ci
1043e5483f6Sopenharmony_cistring RingtoneFileUtils::SplitByChar(const string &str, const char split)
1053e5483f6Sopenharmony_ci{
1063e5483f6Sopenharmony_ci    size_t splitIndex = str.find_last_of(split);
1073e5483f6Sopenharmony_ci    return (splitIndex == string::npos) ? ("") : (str.substr(splitIndex + 1));
1083e5483f6Sopenharmony_ci}
1093e5483f6Sopenharmony_ci
1103e5483f6Sopenharmony_cistring RingtoneFileUtils::GetExtensionFromPath(const string &path)
1113e5483f6Sopenharmony_ci{
1123e5483f6Sopenharmony_ci    string extention = SplitByChar(path, '.');
1133e5483f6Sopenharmony_ci    if (!extention.empty()) {
1143e5483f6Sopenharmony_ci        transform(extention.begin(), extention.end(), extention.begin(), ::tolower);
1153e5483f6Sopenharmony_ci    }
1163e5483f6Sopenharmony_ci    return extention;
1173e5483f6Sopenharmony_ci}
1183e5483f6Sopenharmony_ci
1193e5483f6Sopenharmony_cistring RingtoneFileUtils::GetFileNameFromPath(const string &path)
1203e5483f6Sopenharmony_ci{
1213e5483f6Sopenharmony_ci    string fileName = {};
1223e5483f6Sopenharmony_ci    size_t found = path.rfind("/");
1233e5483f6Sopenharmony_ci    if (found != string::npos && (found + 1) < path.size()) {
1243e5483f6Sopenharmony_ci        fileName = path.substr(found + 1);
1253e5483f6Sopenharmony_ci    } else {
1263e5483f6Sopenharmony_ci        fileName = "";
1273e5483f6Sopenharmony_ci    }
1283e5483f6Sopenharmony_ci
1293e5483f6Sopenharmony_ci    return fileName;
1303e5483f6Sopenharmony_ci}
1313e5483f6Sopenharmony_ci
1323e5483f6Sopenharmony_cistatic string ParseFromUri(const string& path, const string& key)
1333e5483f6Sopenharmony_ci{
1343e5483f6Sopenharmony_ci    RINGTONE_INFO_LOG("parsing uri : %{public}s for key : %{public}s", path.c_str(), key.c_str());
1353e5483f6Sopenharmony_ci    auto keyLen = key.size();
1363e5483f6Sopenharmony_ci    auto found = path.find(key);
1373e5483f6Sopenharmony_ci    if (found == string::npos) {
1383e5483f6Sopenharmony_ci        RINGTONE_INFO_LOG("there is no such field in uri: %{public}s", path.c_str());
1393e5483f6Sopenharmony_ci        return "";
1403e5483f6Sopenharmony_ci    }
1413e5483f6Sopenharmony_ci    string sub = path.substr(found + keyLen + 1);
1423e5483f6Sopenharmony_ci    found = sub.find("&");
1433e5483f6Sopenharmony_ci    if (found != string::npos) {
1443e5483f6Sopenharmony_ci        sub = sub.substr(0, found);
1453e5483f6Sopenharmony_ci    }
1463e5483f6Sopenharmony_ci    sub = RingtoneFileUtils::UrlDecode(sub);
1473e5483f6Sopenharmony_ci    RINGTONE_INFO_LOG("parsing uri : %{public}s -> key=%{public}s, value=%{public}s",
1483e5483f6Sopenharmony_ci        path.c_str(), key.c_str(), sub.c_str());
1493e5483f6Sopenharmony_ci    return sub;
1503e5483f6Sopenharmony_ci}
1513e5483f6Sopenharmony_ci
1523e5483f6Sopenharmony_cistring RingtoneFileUtils::GetFileNameFromPathOrUri(const string &path, bool &isTitle)
1533e5483f6Sopenharmony_ci{
1543e5483f6Sopenharmony_ci    string fileName = {};
1553e5483f6Sopenharmony_ci    size_t found = path.find("content://");
1563e5483f6Sopenharmony_ci    if (found == 0) {
1573e5483f6Sopenharmony_ci        fileName = ParseFromUri(path, "title"); // Pay attention! It's actually "title".
1583e5483f6Sopenharmony_ci        isTitle = true;
1593e5483f6Sopenharmony_ci    } else {
1603e5483f6Sopenharmony_ci        fileName = GetFileNameFromPath(path);
1613e5483f6Sopenharmony_ci        isTitle = false;
1623e5483f6Sopenharmony_ci    }
1633e5483f6Sopenharmony_ci    RINGTONE_INFO_LOG("%{public}s -> %{public}s", path.c_str(), fileName.c_str());
1643e5483f6Sopenharmony_ci    return fileName;
1653e5483f6Sopenharmony_ci}
1663e5483f6Sopenharmony_ci
1673e5483f6Sopenharmony_cistring RingtoneFileUtils::GetBaseNameFromPath(const string &path)
1683e5483f6Sopenharmony_ci{
1693e5483f6Sopenharmony_ci    size_t found = path.rfind("/");
1703e5483f6Sopenharmony_ci    size_t foundDot = path.rfind(".");
1713e5483f6Sopenharmony_ci
1723e5483f6Sopenharmony_ci    string baseName = {};
1733e5483f6Sopenharmony_ci    found = (found == string::npos ? 0 : found);
1743e5483f6Sopenharmony_ci    if ((foundDot > found) && (foundDot != string::npos)) {
1753e5483f6Sopenharmony_ci        baseName = path.substr(found + 1, foundDot - found - 1);
1763e5483f6Sopenharmony_ci    } else {
1773e5483f6Sopenharmony_ci        baseName = "";
1783e5483f6Sopenharmony_ci    }
1793e5483f6Sopenharmony_ci
1803e5483f6Sopenharmony_ci    return baseName;
1813e5483f6Sopenharmony_ci}
1823e5483f6Sopenharmony_ci
1833e5483f6Sopenharmony_cibool RingtoneFileUtils::IsSameFile(const string &srcPath, const string &dstPath)
1843e5483f6Sopenharmony_ci{
1853e5483f6Sopenharmony_ci    struct stat srcStatInfo {};
1863e5483f6Sopenharmony_ci    struct stat dstStatInfo {};
1873e5483f6Sopenharmony_ci
1883e5483f6Sopenharmony_ci    if (access(srcPath.c_str(), F_OK) || access(dstPath.c_str(), F_OK)) {
1893e5483f6Sopenharmony_ci        return false;
1903e5483f6Sopenharmony_ci    }
1913e5483f6Sopenharmony_ci    if (stat(srcPath.c_str(), &srcStatInfo) != 0) {
1923e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("Failed to get file %{private}s StatInfo, err=%{public}d", srcPath.c_str(), errno);
1933e5483f6Sopenharmony_ci        return false;
1943e5483f6Sopenharmony_ci    }
1953e5483f6Sopenharmony_ci    if (stat(dstPath.c_str(), &dstStatInfo) != 0) {
1963e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("Failed to get file %{private}s StatInfo, err=%{public}d", dstPath.c_str(), errno);
1973e5483f6Sopenharmony_ci        return false;
1983e5483f6Sopenharmony_ci    }
1993e5483f6Sopenharmony_ci    if (srcStatInfo.st_size != dstStatInfo.st_size) { /* file size */
2003e5483f6Sopenharmony_ci        RINGTONE_INFO_LOG("Size differs, srcStatInfo.st_size != dstStatInfo.st_size");
2013e5483f6Sopenharmony_ci        return false;
2023e5483f6Sopenharmony_ci    }
2033e5483f6Sopenharmony_ci
2043e5483f6Sopenharmony_ci    return true;
2053e5483f6Sopenharmony_ci}
2063e5483f6Sopenharmony_ci
2073e5483f6Sopenharmony_cistatic int32_t UnlinkCb(const char *fpath, const struct stat *sb, int32_t typeflag, struct FTW *ftwbuf)
2083e5483f6Sopenharmony_ci{
2093e5483f6Sopenharmony_ci    CHECK_AND_RETURN_RET_LOG(fpath != nullptr, E_FAIL, "fpath == nullptr");
2103e5483f6Sopenharmony_ci    int32_t errRet = remove(fpath);
2113e5483f6Sopenharmony_ci    if (errRet) {
2123e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("Failed to remove errno: %{public}d, path: %{private}s", errno, fpath);
2133e5483f6Sopenharmony_ci    }
2143e5483f6Sopenharmony_ci
2153e5483f6Sopenharmony_ci    return errRet;
2163e5483f6Sopenharmony_ci}
2173e5483f6Sopenharmony_ci
2183e5483f6Sopenharmony_ciint32_t RingtoneFileUtils::RemoveDirectory(const string &path)
2193e5483f6Sopenharmony_ci{
2203e5483f6Sopenharmony_ci    return nftw(path.c_str(), UnlinkCb, OPEN_FDS, FTW_DEPTH | FTW_PHYS);
2213e5483f6Sopenharmony_ci}
2223e5483f6Sopenharmony_ci
2233e5483f6Sopenharmony_cibool RingtoneFileUtils::Mkdir(const string &subStr, shared_ptr<int> errCodePtr)
2243e5483f6Sopenharmony_ci{
2253e5483f6Sopenharmony_ci    mode_t mask = umask(0);
2263e5483f6Sopenharmony_ci    if (mkdir(subStr.c_str(), MODE_RWX_USR_GRP) == -1) {
2273e5483f6Sopenharmony_ci        if (errCodePtr != nullptr) {
2283e5483f6Sopenharmony_ci            *errCodePtr = errno;
2293e5483f6Sopenharmony_ci        }
2303e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("Failed to create directory %{public}d", errno);
2313e5483f6Sopenharmony_ci        umask(mask);
2323e5483f6Sopenharmony_ci        return (errno == EEXIST) ? true : false;
2333e5483f6Sopenharmony_ci    }
2343e5483f6Sopenharmony_ci    umask(mask);
2353e5483f6Sopenharmony_ci    return true;
2363e5483f6Sopenharmony_ci}
2373e5483f6Sopenharmony_ci
2383e5483f6Sopenharmony_cibool RingtoneFileUtils::IsDirectory(const string &dirName, shared_ptr<int> errCodePtr)
2393e5483f6Sopenharmony_ci{
2403e5483f6Sopenharmony_ci    struct stat statInfo {};
2413e5483f6Sopenharmony_ci
2423e5483f6Sopenharmony_ci    if (stat(dirName.c_str(), &statInfo) == 0) {
2433e5483f6Sopenharmony_ci        if (statInfo.st_mode & S_IFDIR) {
2443e5483f6Sopenharmony_ci            return true;
2453e5483f6Sopenharmony_ci        }
2463e5483f6Sopenharmony_ci    } else if (errCodePtr != nullptr) {
2473e5483f6Sopenharmony_ci        *errCodePtr = errno;
2483e5483f6Sopenharmony_ci        return false;
2493e5483f6Sopenharmony_ci    }
2503e5483f6Sopenharmony_ci
2513e5483f6Sopenharmony_ci    return false;
2523e5483f6Sopenharmony_ci}
2533e5483f6Sopenharmony_ci
2543e5483f6Sopenharmony_cibool RingtoneFileUtils::CreateDirectory(const string &dirPath, shared_ptr<int> errCodePtr)
2553e5483f6Sopenharmony_ci{
2563e5483f6Sopenharmony_ci    string subStr;
2573e5483f6Sopenharmony_ci    string segment;
2583e5483f6Sopenharmony_ci
2593e5483f6Sopenharmony_ci    stringstream folderStream(dirPath);
2603e5483f6Sopenharmony_ci    while (getline(folderStream, segment, '/')) {
2613e5483f6Sopenharmony_ci        if (segment.empty()) {
2623e5483f6Sopenharmony_ci            continue;
2633e5483f6Sopenharmony_ci        }
2643e5483f6Sopenharmony_ci
2653e5483f6Sopenharmony_ci        subStr.append(RINGTONE_SLASH_CHAR + segment);
2663e5483f6Sopenharmony_ci        if (!IsDirectory(subStr, errCodePtr)) {
2673e5483f6Sopenharmony_ci            if (!Mkdir(subStr, errCodePtr)) {
2683e5483f6Sopenharmony_ci                return false;
2693e5483f6Sopenharmony_ci            }
2703e5483f6Sopenharmony_ci        }
2713e5483f6Sopenharmony_ci    }
2723e5483f6Sopenharmony_ci    return true;
2733e5483f6Sopenharmony_ci}
2743e5483f6Sopenharmony_ci
2753e5483f6Sopenharmony_ciint32_t RingtoneFileUtils::OpenFile(const string &filePath, const string &mode)
2763e5483f6Sopenharmony_ci{
2773e5483f6Sopenharmony_ci    int32_t errCode = E_ERR;
2783e5483f6Sopenharmony_ci
2793e5483f6Sopenharmony_ci    if (filePath.empty() || mode.empty()) {
2803e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("Invalid open argument! mode: %{private}s, path: %{private}s", mode.c_str(), filePath.c_str());
2813e5483f6Sopenharmony_ci        return errCode;
2823e5483f6Sopenharmony_ci    }
2833e5483f6Sopenharmony_ci
2843e5483f6Sopenharmony_ci    if (!IsTargetExtension(filePath)) {
2853e5483f6Sopenharmony_ci        return E_INVALID_PATH;
2863e5483f6Sopenharmony_ci    }
2873e5483f6Sopenharmony_ci
2883e5483f6Sopenharmony_ci    static const unordered_map<string, int32_t> RINGTONE_OPEN_MODE_MAP = {
2893e5483f6Sopenharmony_ci        { RINGTONE_FILEMODE_READONLY, O_RDONLY },
2903e5483f6Sopenharmony_ci        { RINGTONE_FILEMODE_WRITEONLY, O_WRONLY },
2913e5483f6Sopenharmony_ci        { RINGTONE_FILEMODE_READWRITE, O_RDWR },
2923e5483f6Sopenharmony_ci        { RINGTONE_FILEMODE_WRITETRUNCATE, O_WRONLY | O_TRUNC },
2933e5483f6Sopenharmony_ci        { RINGTONE_FILEMODE_WRITEAPPEND, O_WRONLY | O_APPEND },
2943e5483f6Sopenharmony_ci        { RINGTONE_FILEMODE_READWRITETRUNCATE, O_RDWR | O_TRUNC },
2953e5483f6Sopenharmony_ci        { RINGTONE_FILEMODE_READWRITEAPPEND, O_RDWR | O_APPEND },
2963e5483f6Sopenharmony_ci    };
2973e5483f6Sopenharmony_ci    if (RINGTONE_OPEN_MODE_MAP.find(mode) == RINGTONE_OPEN_MODE_MAP.end()) {
2983e5483f6Sopenharmony_ci        return E_ERR;
2993e5483f6Sopenharmony_ci    }
3003e5483f6Sopenharmony_ci
3013e5483f6Sopenharmony_ci    if (filePath.size() >= PATH_MAX) {
3023e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("File path too long %{public}d", (int)filePath.size());
3033e5483f6Sopenharmony_ci        return errCode;
3043e5483f6Sopenharmony_ci    }
3053e5483f6Sopenharmony_ci    string absFilePath;
3063e5483f6Sopenharmony_ci    if (!PathToRealPath(filePath, absFilePath)) {
3073e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("file is not real path, file path: %{private}s", filePath.c_str());
3083e5483f6Sopenharmony_ci        return errCode;
3093e5483f6Sopenharmony_ci    }
3103e5483f6Sopenharmony_ci    if (absFilePath.empty()) {
3113e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("Failed to obtain the canonical path for source path %{public}d %{private}s",
3123e5483f6Sopenharmony_ci            errno, filePath.c_str());
3133e5483f6Sopenharmony_ci        return errCode;
3143e5483f6Sopenharmony_ci    }
3153e5483f6Sopenharmony_ci    RINGTONE_INFO_LOG("File absFilePath is %{private}s", absFilePath.c_str());
3163e5483f6Sopenharmony_ci    return open(absFilePath.c_str(), RINGTONE_OPEN_MODE_MAP.at(mode));
3173e5483f6Sopenharmony_ci}
3183e5483f6Sopenharmony_ci
3193e5483f6Sopenharmony_ciint32_t RingtoneFileUtils::OpenVibrateFile(const std::string &filePath, const std::string &mode)
3203e5483f6Sopenharmony_ci{
3213e5483f6Sopenharmony_ci    int32_t errCode = E_ERR;
3223e5483f6Sopenharmony_ci
3233e5483f6Sopenharmony_ci    if (filePath.empty() || mode.empty()) {
3243e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("Invalid open argument! mode: %{private}s, path: %{private}s", mode.c_str(), filePath.c_str());
3253e5483f6Sopenharmony_ci        return errCode;
3263e5483f6Sopenharmony_ci    }
3273e5483f6Sopenharmony_ci
3283e5483f6Sopenharmony_ci    if (!IsVibrateFile(filePath)) {
3293e5483f6Sopenharmony_ci        return E_INVALID_PATH;
3303e5483f6Sopenharmony_ci    }
3313e5483f6Sopenharmony_ci
3323e5483f6Sopenharmony_ci    static const unordered_map<string, int32_t> RINGTONE_OPEN_MODE_MAP = {
3333e5483f6Sopenharmony_ci        { RINGTONE_FILEMODE_READONLY, O_RDONLY },
3343e5483f6Sopenharmony_ci        { RINGTONE_FILEMODE_WRITEONLY, O_WRONLY },
3353e5483f6Sopenharmony_ci        { RINGTONE_FILEMODE_READWRITE, O_RDWR },
3363e5483f6Sopenharmony_ci        { RINGTONE_FILEMODE_WRITETRUNCATE, O_WRONLY | O_TRUNC },
3373e5483f6Sopenharmony_ci        { RINGTONE_FILEMODE_WRITEAPPEND, O_WRONLY | O_APPEND },
3383e5483f6Sopenharmony_ci        { RINGTONE_FILEMODE_READWRITETRUNCATE, O_RDWR | O_TRUNC },
3393e5483f6Sopenharmony_ci        { RINGTONE_FILEMODE_READWRITEAPPEND, O_RDWR | O_APPEND },
3403e5483f6Sopenharmony_ci    };
3413e5483f6Sopenharmony_ci    if (RINGTONE_OPEN_MODE_MAP.find(mode) == RINGTONE_OPEN_MODE_MAP.end()) {
3423e5483f6Sopenharmony_ci        return E_ERR;
3433e5483f6Sopenharmony_ci    }
3443e5483f6Sopenharmony_ci
3453e5483f6Sopenharmony_ci    if (filePath.size() >= PATH_MAX) {
3463e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("File path too long %{public}d", (int)filePath.size());
3473e5483f6Sopenharmony_ci        return errCode;
3483e5483f6Sopenharmony_ci    }
3493e5483f6Sopenharmony_ci    string absFilePath;
3503e5483f6Sopenharmony_ci    if (!PathToRealPath(filePath, absFilePath)) {
3513e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("file is not real path, file path: %{private}s", filePath.c_str());
3523e5483f6Sopenharmony_ci        return errCode;
3533e5483f6Sopenharmony_ci    }
3543e5483f6Sopenharmony_ci    if (absFilePath.empty()) {
3553e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("Failed to obtain the canonical path for source path %{public}d %{private}s",
3563e5483f6Sopenharmony_ci            errno, filePath.c_str());
3573e5483f6Sopenharmony_ci        return errCode;
3583e5483f6Sopenharmony_ci    }
3593e5483f6Sopenharmony_ci    RINGTONE_INFO_LOG("File absFilePath is %{private}s", absFilePath.c_str());
3603e5483f6Sopenharmony_ci    return open(absFilePath.c_str(), RINGTONE_OPEN_MODE_MAP.at(mode));
3613e5483f6Sopenharmony_ci}
3623e5483f6Sopenharmony_ci
3633e5483f6Sopenharmony_cibool RingtoneFileUtils::IsFileExists(const string &fileName)
3643e5483f6Sopenharmony_ci{
3653e5483f6Sopenharmony_ci    struct stat statInfo {};
3663e5483f6Sopenharmony_ci
3673e5483f6Sopenharmony_ci    return ((stat(fileName.c_str(), &statInfo)) == 0);
3683e5483f6Sopenharmony_ci}
3693e5483f6Sopenharmony_ci
3703e5483f6Sopenharmony_ciint32_t RingtoneFileUtils::CreateFile(const string &filePath)
3713e5483f6Sopenharmony_ci{
3723e5483f6Sopenharmony_ci    int32_t errCode = E_ERR;
3733e5483f6Sopenharmony_ci
3743e5483f6Sopenharmony_ci    if (filePath.empty()) {
3753e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("Filepath is empty");
3763e5483f6Sopenharmony_ci        return E_VIOLATION_PARAMETERS;
3773e5483f6Sopenharmony_ci    }
3783e5483f6Sopenharmony_ci
3793e5483f6Sopenharmony_ci    if (!IsTargetExtension(filePath)) {
3803e5483f6Sopenharmony_ci        return E_INVALID_PATH;
3813e5483f6Sopenharmony_ci    }
3823e5483f6Sopenharmony_ci
3833e5483f6Sopenharmony_ci    if (IsFileExists(filePath)) {
3843e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("the file exists path: %{private}s", filePath.c_str());
3853e5483f6Sopenharmony_ci        return E_FILE_EXIST;
3863e5483f6Sopenharmony_ci    }
3873e5483f6Sopenharmony_ci
3883e5483f6Sopenharmony_ci    ofstream file(filePath);
3893e5483f6Sopenharmony_ci    if (!file) {
3903e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("Output file path could not be created errno %{public}d", errno);
3913e5483f6Sopenharmony_ci        return errCode;
3923e5483f6Sopenharmony_ci    }
3933e5483f6Sopenharmony_ci
3943e5483f6Sopenharmony_ci    file.close();
3953e5483f6Sopenharmony_ci
3963e5483f6Sopenharmony_ci    return E_SUCCESS;
3973e5483f6Sopenharmony_ci}
3983e5483f6Sopenharmony_ci
3993e5483f6Sopenharmony_cibool RingtoneFileUtils::DeleteFile(const string &fileName)
4003e5483f6Sopenharmony_ci{
4013e5483f6Sopenharmony_ci    return (remove(fileName.c_str()) == 0);
4023e5483f6Sopenharmony_ci}
4033e5483f6Sopenharmony_ci
4043e5483f6Sopenharmony_cibool RingtoneFileUtils::MoveFile(const string &oldPath, const string &newPath)
4053e5483f6Sopenharmony_ci{
4063e5483f6Sopenharmony_ci    bool errRet = false;
4073e5483f6Sopenharmony_ci
4083e5483f6Sopenharmony_ci    if (IsFileExists(oldPath) && !IsFileExists(newPath)) {
4093e5483f6Sopenharmony_ci        errRet = (rename(oldPath.c_str(), newPath.c_str()) == 0);
4103e5483f6Sopenharmony_ci    }
4113e5483f6Sopenharmony_ci
4123e5483f6Sopenharmony_ci    return errRet;
4133e5483f6Sopenharmony_ci}
4143e5483f6Sopenharmony_ci
4153e5483f6Sopenharmony_cibool RingtoneFileUtils::CopyFileUtil(const string &filePath, const string &newPath)
4163e5483f6Sopenharmony_ci{
4173e5483f6Sopenharmony_ci    struct stat fst{};
4183e5483f6Sopenharmony_ci    bool ret = false;
4193e5483f6Sopenharmony_ci    if (filePath.size() >= PATH_MAX) {
4203e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("File path too long %{public}d", static_cast<int>(filePath.size()));
4213e5483f6Sopenharmony_ci        return ret;
4223e5483f6Sopenharmony_ci    }
4233e5483f6Sopenharmony_ci    RINGTONE_INFO_LOG("File path is %{private}s", filePath.c_str());
4243e5483f6Sopenharmony_ci    string absFilePath;
4253e5483f6Sopenharmony_ci    if (!PathToRealPath(filePath, absFilePath)) {
4263e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("file is not real path, file path: %{private}s", filePath.c_str());
4273e5483f6Sopenharmony_ci        return ret;
4283e5483f6Sopenharmony_ci    }
4293e5483f6Sopenharmony_ci    if (absFilePath.empty()) {
4303e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("Failed to obtain the canonical path for source path%{private}s %{public}d",
4313e5483f6Sopenharmony_ci            filePath.c_str(), errno);
4323e5483f6Sopenharmony_ci        return ret;
4333e5483f6Sopenharmony_ci    }
4343e5483f6Sopenharmony_ci
4353e5483f6Sopenharmony_ci    int32_t source = open(absFilePath.c_str(), O_RDONLY);
4363e5483f6Sopenharmony_ci    if (source == -1) {
4373e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("Open failed for source file");
4383e5483f6Sopenharmony_ci        return ret;
4393e5483f6Sopenharmony_ci    }
4403e5483f6Sopenharmony_ci
4413e5483f6Sopenharmony_ci    int32_t dest = open(newPath.c_str(), O_WRONLY | O_CREAT, MODE_RW_USR);
4423e5483f6Sopenharmony_ci    if (dest == -1) {
4433e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("Open failed for destination file %{public}d", errno);
4443e5483f6Sopenharmony_ci        close(source);
4453e5483f6Sopenharmony_ci        return ret;
4463e5483f6Sopenharmony_ci    }
4473e5483f6Sopenharmony_ci
4483e5483f6Sopenharmony_ci    if (fstat(source, &fst) == 0) {
4493e5483f6Sopenharmony_ci        // Copy file content
4503e5483f6Sopenharmony_ci        if (sendfile(dest, source, nullptr, fst.st_size) != E_ERR) {
4513e5483f6Sopenharmony_ci            // Copy ownership and mode of source file
4523e5483f6Sopenharmony_ci            if (fchown(dest, fst.st_uid, fst.st_gid) == 0 &&
4533e5483f6Sopenharmony_ci                fchmod(dest, fst.st_mode) == 0) {
4543e5483f6Sopenharmony_ci                ret= true;
4553e5483f6Sopenharmony_ci            }
4563e5483f6Sopenharmony_ci        }
4573e5483f6Sopenharmony_ci    }
4583e5483f6Sopenharmony_ci
4593e5483f6Sopenharmony_ci    close(source);
4603e5483f6Sopenharmony_ci    close(dest);
4613e5483f6Sopenharmony_ci
4623e5483f6Sopenharmony_ci    return ret;
4633e5483f6Sopenharmony_ci}
4643e5483f6Sopenharmony_ci
4653e5483f6Sopenharmony_ciint64_t RingtoneFileUtils::Timespec2Millisecond(const struct timespec &time)
4663e5483f6Sopenharmony_ci{
4673e5483f6Sopenharmony_ci    return time.tv_sec * MSEC_TO_SEC + time.tv_nsec / MSEC_TO_NSEC;
4683e5483f6Sopenharmony_ci}
4693e5483f6Sopenharmony_ci
4703e5483f6Sopenharmony_cibool RingtoneFileUtils::StartsWith(const string &str, const string &prefix)
4713e5483f6Sopenharmony_ci{
4723e5483f6Sopenharmony_ci    return str.compare(0, prefix.size(), prefix) == 0;
4733e5483f6Sopenharmony_ci}
4743e5483f6Sopenharmony_ci
4753e5483f6Sopenharmony_ciint64_t RingtoneFileUtils::UTCTimeMilliSeconds()
4763e5483f6Sopenharmony_ci{
4773e5483f6Sopenharmony_ci    struct timespec t;
4783e5483f6Sopenharmony_ci    clock_gettime(CLOCK_REALTIME, &t);
4793e5483f6Sopenharmony_ci    return t.tv_sec * MSEC_TO_SEC + t.tv_nsec / MSEC_TO_NSEC;
4803e5483f6Sopenharmony_ci}
4813e5483f6Sopenharmony_ci
4823e5483f6Sopenharmony_ciint64_t RingtoneFileUtils::UTCTimeSeconds()
4833e5483f6Sopenharmony_ci{
4843e5483f6Sopenharmony_ci    struct timespec t{};
4853e5483f6Sopenharmony_ci    t.tv_sec = 0;
4863e5483f6Sopenharmony_ci    t.tv_nsec = 0;
4873e5483f6Sopenharmony_ci    clock_gettime(CLOCK_REALTIME, &t);
4883e5483f6Sopenharmony_ci    return (int64_t)(t.tv_sec);
4893e5483f6Sopenharmony_ci}
4903e5483f6Sopenharmony_ci
4913e5483f6Sopenharmony_cistring RingtoneFileUtils::StrCreateTimeByMilliseconds(const string &format, int64_t time)
4923e5483f6Sopenharmony_ci{
4933e5483f6Sopenharmony_ci    char strTime[DEFAULT_TIME_SIZE] = "";
4943e5483f6Sopenharmony_ci    int64_t times = time / MSEC_TO_SEC;
4953e5483f6Sopenharmony_ci    auto tm = localtime(&times);
4963e5483f6Sopenharmony_ci    if (tm == nullptr) {
4973e5483f6Sopenharmony_ci        return "";
4983e5483f6Sopenharmony_ci    }
4993e5483f6Sopenharmony_ci    (void)strftime(strTime, sizeof(strTime), format.c_str(), tm);
5003e5483f6Sopenharmony_ci    return strTime;
5013e5483f6Sopenharmony_ci}
5023e5483f6Sopenharmony_ci
5033e5483f6Sopenharmony_cistatic const int URL_DECODE_DOUBLE = 2;
5043e5483f6Sopenharmony_cistring RingtoneFileUtils::UrlDecode(const string &src)
5053e5483f6Sopenharmony_ci{
5063e5483f6Sopenharmony_ci    string ret;
5073e5483f6Sopenharmony_ci    char ch;
5083e5483f6Sopenharmony_ci    int tmpNum;
5093e5483f6Sopenharmony_ci    for (size_t i = 0; i < src.length(); i++) {
5103e5483f6Sopenharmony_ci        if (src[i]=='%') {
5113e5483f6Sopenharmony_ci            if (sscanf_s(src.substr(i + 1, URL_DECODE_DOUBLE).c_str(), "%x", &tmpNum) == -1) {
5123e5483f6Sopenharmony_ci                RINGTONE_ERR_LOG("Not a valid url: %{private}s", src.c_str());
5133e5483f6Sopenharmony_ci                return src;
5143e5483f6Sopenharmony_ci            }
5153e5483f6Sopenharmony_ci            ch = static_cast<char>(tmpNum);
5163e5483f6Sopenharmony_ci            ret += ch;
5173e5483f6Sopenharmony_ci            i = i + URL_DECODE_DOUBLE;
5183e5483f6Sopenharmony_ci        } else {
5193e5483f6Sopenharmony_ci            ret += src[i];
5203e5483f6Sopenharmony_ci        }
5213e5483f6Sopenharmony_ci    }
5223e5483f6Sopenharmony_ci    return ret;
5233e5483f6Sopenharmony_ci}
5243e5483f6Sopenharmony_ci
5253e5483f6Sopenharmony_cistatic int32_t MkdirRecursive(const string &path, size_t start)
5263e5483f6Sopenharmony_ci{
5273e5483f6Sopenharmony_ci    RINGTONE_DEBUG_LOG("start pos %{public}zu", start);
5283e5483f6Sopenharmony_ci    size_t end = path.find("/", start + 1);
5293e5483f6Sopenharmony_ci
5303e5483f6Sopenharmony_ci    string subDir = "";
5313e5483f6Sopenharmony_ci    if (end == std::string::npos) {
5323e5483f6Sopenharmony_ci        if (start + 1 == path.size()) {
5333e5483f6Sopenharmony_ci            RINGTONE_DEBUG_LOG("path size=%zu", path.size());
5343e5483f6Sopenharmony_ci        } else {
5353e5483f6Sopenharmony_ci            subDir = path.substr(start + 1, path.size() - start - 1);
5363e5483f6Sopenharmony_ci        }
5373e5483f6Sopenharmony_ci    } else {
5383e5483f6Sopenharmony_ci        subDir = path.substr(start + 1, end - start - 1);
5393e5483f6Sopenharmony_ci    }
5403e5483f6Sopenharmony_ci
5413e5483f6Sopenharmony_ci    if (subDir.size() == 0) {
5423e5483f6Sopenharmony_ci        return E_SUCCESS;
5433e5483f6Sopenharmony_ci    } else {
5443e5483f6Sopenharmony_ci        string real = path.substr(0, start + subDir.size() + 1);
5453e5483f6Sopenharmony_ci        mode_t mask = umask(0);
5463e5483f6Sopenharmony_ci        int result = mkdir(real.c_str(), MODE_RWX_USR_GRP);
5473e5483f6Sopenharmony_ci        if (result == 0) {
5483e5483f6Sopenharmony_ci            RINGTONE_INFO_LOG("mkdir %{public}s successfully", real.c_str());
5493e5483f6Sopenharmony_ci        } else {
5503e5483f6Sopenharmony_ci            RINGTONE_INFO_LOG("mkdir %{public}s failed, errno is %{public}d", real.c_str(), errno);
5513e5483f6Sopenharmony_ci        }
5523e5483f6Sopenharmony_ci        umask(mask);
5533e5483f6Sopenharmony_ci    }
5543e5483f6Sopenharmony_ci    if (end == std::string::npos) {
5553e5483f6Sopenharmony_ci        return E_SUCCESS;
5563e5483f6Sopenharmony_ci    }
5573e5483f6Sopenharmony_ci
5583e5483f6Sopenharmony_ci    return MkdirRecursive(path, end);
5593e5483f6Sopenharmony_ci}
5603e5483f6Sopenharmony_ci
5613e5483f6Sopenharmony_ciint32_t RingtoneFileUtils::CreatePreloadFolder(const string &path)
5623e5483f6Sopenharmony_ci{
5633e5483f6Sopenharmony_ci    RINGTONE_DEBUG_LOG("start");
5643e5483f6Sopenharmony_ci    if (access(path.c_str(), F_OK) == 0) {
5653e5483f6Sopenharmony_ci        RINGTONE_DEBUG_LOG("dir is existing");
5663e5483f6Sopenharmony_ci        return E_SUCCESS;
5673e5483f6Sopenharmony_ci    }
5683e5483f6Sopenharmony_ci
5693e5483f6Sopenharmony_ci    auto start = path.find(RINGTONE_CUSTOMIZED_BASE_PATH);
5703e5483f6Sopenharmony_ci    if (start == string::npos) {
5713e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("base dir is wrong");
5723e5483f6Sopenharmony_ci        return E_ERR;
5733e5483f6Sopenharmony_ci    }
5743e5483f6Sopenharmony_ci
5753e5483f6Sopenharmony_ci    return MkdirRecursive(path, start + RINGTONE_CUSTOMIZED_BASE_PATH.size());
5763e5483f6Sopenharmony_ci}
5773e5483f6Sopenharmony_ci
5783e5483f6Sopenharmony_civoid RingtoneFileUtils::CreateRingtoneDir()
5793e5483f6Sopenharmony_ci{
5803e5483f6Sopenharmony_ci    static const vector<string> userPreloadDirs = {
5813e5483f6Sopenharmony_ci        { RINGTONE_CUSTOMIZED_ALARM_PATH }, { RINGTONE_CUSTOMIZED_RINGTONE_PATH },
5823e5483f6Sopenharmony_ci        { RINGTONE_CUSTOMIZED_NOTIFICATIONS_PATH }
5833e5483f6Sopenharmony_ci    };
5843e5483f6Sopenharmony_ci
5853e5483f6Sopenharmony_ci    for (const auto &dir: userPreloadDirs) {
5863e5483f6Sopenharmony_ci        if (CreatePreloadFolder(dir) != E_SUCCESS) {
5873e5483f6Sopenharmony_ci            RINGTONE_INFO_LOG("scan failed on dir %{public}s", dir.c_str());
5883e5483f6Sopenharmony_ci            continue;
5893e5483f6Sopenharmony_ci        }
5903e5483f6Sopenharmony_ci    }
5913e5483f6Sopenharmony_ci}
5923e5483f6Sopenharmony_ci
5933e5483f6Sopenharmony_ciint32_t RingtoneFileUtils::MoveDirectory(const std::string &srcDir, const std::string &dstDir)
5943e5483f6Sopenharmony_ci{
5953e5483f6Sopenharmony_ci    if (access(srcDir.c_str(), F_OK) != 0) {
5963e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("access srcDir failed, errno is %{public}d", errno);
5973e5483f6Sopenharmony_ci        return E_FAIL;
5983e5483f6Sopenharmony_ci    }
5993e5483f6Sopenharmony_ci    if (access(dstDir.c_str(), F_OK) != 0) {
6003e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("access dstDir failed, errno is %{public}d", errno);
6013e5483f6Sopenharmony_ci        return E_FAIL;
6023e5483f6Sopenharmony_ci    }
6033e5483f6Sopenharmony_ci    int ret = E_SUCCESS;
6043e5483f6Sopenharmony_ci    for (const auto &dirEntry : std::filesystem::directory_iterator{ srcDir }) {
6053e5483f6Sopenharmony_ci        std::string srcFilePath = dirEntry.path();
6063e5483f6Sopenharmony_ci        std::string tmpFilePath = srcFilePath;
6073e5483f6Sopenharmony_ci        std::string dstFilePath = tmpFilePath.replace(0, srcDir.length(), dstDir);
6083e5483f6Sopenharmony_ci        if (!MoveFile(srcFilePath, dstFilePath)) {
6093e5483f6Sopenharmony_ci            RINGTONE_ERR_LOG("Move file failed, errno is %{public}d", errno);
6103e5483f6Sopenharmony_ci            ret = E_FAIL;
6113e5483f6Sopenharmony_ci        }
6123e5483f6Sopenharmony_ci    }
6133e5483f6Sopenharmony_ci    return ret;
6143e5483f6Sopenharmony_ci}
6153e5483f6Sopenharmony_ci
6163e5483f6Sopenharmony_civoid RingtoneFileUtils::AccessRingtoneDir()
6173e5483f6Sopenharmony_ci{
6183e5483f6Sopenharmony_ci    if (access(RINGTONE_CUSTOMIZED_BASE_RINGTONE_PATH.c_str(), F_OK) != 0) {
6193e5483f6Sopenharmony_ci        CreateRingtoneDir();
6203e5483f6Sopenharmony_ci        return;
6213e5483f6Sopenharmony_ci    }
6223e5483f6Sopenharmony_ci    struct stat fileStat;
6233e5483f6Sopenharmony_ci    if (stat(RINGTONE_CUSTOMIZED_BASE_RINGTONE_PATH.c_str(), &fileStat) != 0) {
6243e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("stat dir failed, errno is %{public}d", errno);
6253e5483f6Sopenharmony_ci        return;
6263e5483f6Sopenharmony_ci    }
6273e5483f6Sopenharmony_ci    // 检查组的写权限
6283e5483f6Sopenharmony_ci    if ((fileStat.st_mode & S_IWGRP) != 0) {
6293e5483f6Sopenharmony_ci        return;
6303e5483f6Sopenharmony_ci    }
6313e5483f6Sopenharmony_ci    if (IsEmptyFolder(RINGTONE_CUSTOMIZED_BASE_RINGTONE_PATH.c_str())) {
6323e5483f6Sopenharmony_ci        RINGTONE_ERR_LOG("The directory is empty and lacks group write permission.");
6333e5483f6Sopenharmony_ci        if (DeleteFile(RINGTONE_CUSTOMIZED_BASE_RINGTONE_PATH.c_str())) {
6343e5483f6Sopenharmony_ci            RINGTONE_ERR_LOG("DeleteFile denied, errCode: %{public}d", errno);
6353e5483f6Sopenharmony_ci        }
6363e5483f6Sopenharmony_ci        CreateRingtoneDir();
6373e5483f6Sopenharmony_ci    } else { //rename and move file
6383e5483f6Sopenharmony_ci        if (MoveFile(RINGTONE_CUSTOMIZED_BASE_RINGTONE_PATH.c_str(),
6393e5483f6Sopenharmony_ci            RINGTONE_CUSTOMIZED_BASE_RINGTONETMP_PATH.c_str())) {
6403e5483f6Sopenharmony_ci            if (CreatePreloadFolder(RINGTONE_CUSTOMIZED_BASE_RINGTONE_PATH.c_str()) != E_SUCCESS) {
6413e5483f6Sopenharmony_ci                RINGTONE_ERR_LOG("Create Ringtone dir failed, errno is %{public}d", errno);
6423e5483f6Sopenharmony_ci                //restore dir
6433e5483f6Sopenharmony_ci                MoveFile(RINGTONE_CUSTOMIZED_BASE_RINGTONETMP_PATH.c_str(),
6443e5483f6Sopenharmony_ci                    RINGTONE_CUSTOMIZED_BASE_RINGTONE_PATH.c_str());
6453e5483f6Sopenharmony_ci                return;
6463e5483f6Sopenharmony_ci            }
6473e5483f6Sopenharmony_ci            if (MoveDirectory(RINGTONE_CUSTOMIZED_BASE_RINGTONETMP_PATH.c_str(),
6483e5483f6Sopenharmony_ci                RINGTONE_CUSTOMIZED_BASE_RINGTONE_PATH.c_str()) != E_SUCCESS) {
6493e5483f6Sopenharmony_ci                RINGTONE_ERR_LOG("Move dir failed, errno is %{public}d", errno);
6503e5483f6Sopenharmony_ci                CreateRingtoneDir();
6513e5483f6Sopenharmony_ci                return;
6523e5483f6Sopenharmony_ci            }
6533e5483f6Sopenharmony_ci            if (DeleteFile(RINGTONE_CUSTOMIZED_BASE_RINGTONETMP_PATH.c_str())) {
6543e5483f6Sopenharmony_ci                RINGTONE_ERR_LOG("DeleteFile denied, errCode: %{public}d", errno);
6553e5483f6Sopenharmony_ci            }
6563e5483f6Sopenharmony_ci        } else {
6573e5483f6Sopenharmony_ci            RINGTONE_ERR_LOG("Move Ringtone dir failed, errno is %{public}d", errno);
6583e5483f6Sopenharmony_ci        }
6593e5483f6Sopenharmony_ci    }
6603e5483f6Sopenharmony_ci    return;
6613e5483f6Sopenharmony_ci}
6623e5483f6Sopenharmony_ci
6633e5483f6Sopenharmony_cistring RingtoneFileUtils::GetFileExtension(const string &path)
6643e5483f6Sopenharmony_ci{
6653e5483f6Sopenharmony_ci    if (!path.empty()) {
6663e5483f6Sopenharmony_ci        size_t dotIndex = path.rfind(".");
6673e5483f6Sopenharmony_ci        if (dotIndex != string::npos) {
6683e5483f6Sopenharmony_ci            return path.substr(dotIndex + 1);
6693e5483f6Sopenharmony_ci        }
6703e5483f6Sopenharmony_ci    }
6713e5483f6Sopenharmony_ci
6723e5483f6Sopenharmony_ci    RINGTONE_ERR_LOG("Failed to obtain file extension because given pathname is empty");
6733e5483f6Sopenharmony_ci    return "";
6743e5483f6Sopenharmony_ci}
6753e5483f6Sopenharmony_ci} // namespace Media
6763e5483f6Sopenharmony_ci} // namespace OHOS
677