1/*
2 * Copyright (c) 2021-2024 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 "bundle_scanner.h"
17
18#include <dirent.h>
19
20#include "bundle_mgr_service.h"
21#include "hitrace_meter.h"
22#include "datetime_ex.h"
23#include "perf_profile.h"
24
25namespace OHOS {
26namespace AppExecFwk {
27
28BundleScanner::BundleScanner()
29{
30    APP_LOGI("BundleScanner instance is created");
31}
32
33BundleScanner::~BundleScanner()
34{
35    APP_LOGI("BundleScanner instance is destroyed");
36}
37
38const std::list<std::string> &BundleScanner::Scan(const std::string &dirPath)
39{
40    HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
41    PerfProfile::GetInstance().SetBundleScanStartTime(GetTickCount());
42
43    APP_LOGD("path:%{private}s", dirPath.c_str());
44    if (!dirPath.empty()) {
45        if (!ScanImpl(dirPath)) {
46            APP_LOGW("BundleScanner::Scan scan error");
47        }
48    }
49
50    APP_LOGD("scan result num:%{public}zu", entries_.size());
51    for (const auto &item : entries_) {
52        APP_LOGD("app item:%{private}s", item.c_str());
53    }
54
55    PerfProfile::GetInstance().SetBundleScanEndTime(GetTickCount());
56    return entries_;
57}
58
59bool BundleScanner::ScanImpl(const std::string &dirPath)
60{
61    DIR *dirp = opendir(dirPath.c_str());
62    if (dirp == nullptr) {
63        APP_LOGE("BundleScanner::ScanImpl open dir:%{private}s fail, errno:%{public}d", dirPath.c_str(), errno);
64        return false;
65    }
66
67    struct dirent *dirent = nullptr;
68    for (;;) {
69        dirent = readdir(dirp);
70        if (dirent == nullptr) {
71            APP_LOGE("fail readdir err:%{public}d", errno);
72            break;
73        }
74
75        std::string currentName(dirent->d_name);
76        APP_LOGD("folder found:'%{private}s'", dirent->d_name);
77        if (currentName.compare(".") == 0 || currentName.compare("..") == 0) {
78            continue;
79        }
80        entries_.push_back(dirPath + ServiceConstants::PATH_SEPARATOR + currentName);
81    }
82
83    if (closedir(dirp) == -1) {
84        APP_LOGW("close dir fail, errno:%{public}d", errno);
85    }
86    return true;
87}
88
89}  // namespace AppExecFwk
90}  // namespace OHOS
91