* Copyright (C) 2024 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 "Scanner"
#include "ringtone_scanner_manager.h"
#include "directory_ex.h"
#include "ringtone_log.h"
#include "ringtone_scanner_utils.h"
#include "ringtone_tracer.h"
namespace OHOS {
namespace Media {
std::shared_ptr<RingtoneScannerManager> RingtoneScannerManager::instance_ = nullptr;
std::mutex RingtoneScannerManager::instanceMutex_;
std::shared_ptr<RingtoneScannerManager> RingtoneScannerManager::GetInstance()
{
if (instance_ == nullptr) {
std::lock_guard<std::mutex> guard(instanceMutex_);
if (instance_ != nullptr) {
return instance_;
}
instance_ = std::make_shared<RingtoneScannerManager>();
}
return instance_;
}
int32_t RingtoneScannerManager::ScanFile(const std::string &path,
const std::shared_ptr<IRingtoneScannerCallback> &callback)
{
RINGTONE_DEBUG_LOG("scan file %{private}s", path.c_str());
std::string realPath;
if (!PathToRealPath(path, realPath)) {
RINGTONE_ERR_LOG("failed to get real path %{private}s, errno %{public}d", path.c_str(), errno);
return E_INVALID_PATH;
}
if (!RingtoneScannerUtils::IsRegularFile(realPath)) {
RINGTONE_ERR_LOG("the path %{private}s is not a regular file", realPath.c_str());
return E_INVALID_PATH;
}
std::unique_ptr<RingtoneScannerObj> scanner =
std::make_unique<RingtoneScannerObj>(realPath, callback, RingtoneScannerObj::FILE);
executor_.Commit(move(scanner));
return E_OK;
}
int32_t RingtoneScannerManager::ScanFileSync(const std::string &path,
const std::shared_ptr<IRingtoneScannerCallback> &callback, bool isForceScan)
{
RINGTONE_DEBUG_LOG("scan file %{private}s", path.c_str());
std::string realPath;
if (!PathToRealPath(path, realPath)) {
RINGTONE_ERR_LOG("failed to get real path %{private}s, errno %{public}d", path.c_str(), errno);
return E_INVALID_PATH;
}
if (!RingtoneScannerUtils::IsRegularFile(realPath)) {
RINGTONE_ERR_LOG("the path %{private}s is not a regular file", realPath.c_str());
return E_INVALID_PATH;
}
RingtoneScannerObj scanner = RingtoneScannerObj(realPath, callback, RingtoneScannerObj::FILE);
if (isForceScan) {
scanner.SetForceScan(true);
}
scanner.Scan();
return E_OK;
}
int32_t RingtoneScannerManager::ScanDir(const std::string &path,
const std::shared_ptr<IRingtoneScannerCallback> &callback)
{
RINGTONE_DEBUG_LOG("scan dir %{private}s", path.c_str());
std::string realPath;
if (!PathToRealPath(path, realPath)) {
RINGTONE_ERR_LOG("failed to get real path %{private}s, errno %{public}d", path.c_str(), errno);
return E_INVALID_PATH;
}
if (!RingtoneScannerUtils::IsDirectory(realPath)) {
RINGTONE_ERR_LOG("the path %{private}s is not a directory", realPath.c_str());
return E_INVALID_PATH;
}
std::unique_ptr<RingtoneScannerObj> scanner = std::make_unique<RingtoneScannerObj>(realPath, callback,
RingtoneScannerObj::DIRECTORY);
executor_.Commit(move(scanner));
return E_OK;
}
int32_t RingtoneScannerManager::ScanDirSync(const std::string &path,
const std::shared_ptr<IRingtoneScannerCallback> &callback)
{
RINGTONE_DEBUG_LOG("scan dir %{private}s", path.c_str());
std::string realPath;
if (!PathToRealPath(path, realPath)) {
RINGTONE_ERR_LOG("failed to get real path %{private}s, errno %{public}d", path.c_str(), errno);
return E_INVALID_PATH;
}
if (!RingtoneScannerUtils::IsDirectory(realPath)) {
RINGTONE_ERR_LOG("the path %{private}s is not a directory", realPath.c_str());
return E_INVALID_PATH;
}
RingtoneScannerObj scanner = RingtoneScannerObj(realPath, callback, RingtoneScannerObj::DIRECTORY);
scanner.Scan();
return E_OK;
}
void RingtoneScannerManager::Start(bool isSync)
{
RingtoneTracer tracer;
tracer.Start("Ringtone Scanner Start");
if (isSync) {
RINGTONE_WARN_LOG("scan start, isSync = %{public}d", isSync);
RingtoneScannerObj scanner = RingtoneScannerObj(RingtoneScannerObj::START);
scanner.Scan();
RINGTONE_WARN_LOG("scan finished");
} else {
RINGTONE_WARN_LOG("scan start, isSync = %{public}d", isSync);
executor_.Start();
std::shared_ptr<RingtoneScannerObj> scanner = std::make_shared<RingtoneScannerObj>(RingtoneScannerObj::START);
executor_.Commit(scanner);
scanner->WaitFor();
RINGTONE_WARN_LOG("scan finished");
}
}
void RingtoneScannerManager::Stop()
{
this->executor_.Stop();
}
}
}