1a1db01bdSopenharmony_ci/*
2a1db01bdSopenharmony_ci * Copyright (c) 2020 Huawei Device Co., Ltd.
3a1db01bdSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4a1db01bdSopenharmony_ci * you may not use this file except in compliance with the License.
5a1db01bdSopenharmony_ci * You may obtain a copy of the License at
6a1db01bdSopenharmony_ci *
7a1db01bdSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8a1db01bdSopenharmony_ci *
9a1db01bdSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10a1db01bdSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11a1db01bdSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12a1db01bdSopenharmony_ci * See the License for the specific language governing permissions and
13a1db01bdSopenharmony_ci * limitations under the License.
14a1db01bdSopenharmony_ci */
15a1db01bdSopenharmony_ci
16a1db01bdSopenharmony_ci#include "app_manager.h"
17a1db01bdSopenharmony_ci
18a1db01bdSopenharmony_ci#define __STDC_FORMAT_MACROS
19a1db01bdSopenharmony_ci#include <cinttypes>
20a1db01bdSopenharmony_ci#include <cstring>
21a1db01bdSopenharmony_ci
22a1db01bdSopenharmony_ci#include "token_generate.h"
23a1db01bdSopenharmony_ci#include "util/abilityms_log.h"
24a1db01bdSopenharmony_ci
25a1db01bdSopenharmony_cinamespace OHOS {
26a1db01bdSopenharmony_ciAppRecord *AppManager::StartAppProcess(const BundleInfo &bundleInfo)
27a1db01bdSopenharmony_ci{
28a1db01bdSopenharmony_ci    CHECK_NULLPTR_RETURN_PTR(bundleInfo.bundleName, "AppManager", "invalid argument");
29a1db01bdSopenharmony_ci    AppRecord *appRecord = GetAppRecordByBundleName(bundleInfo.bundleName);
30a1db01bdSopenharmony_ci    if (appRecord != nullptr) {
31a1db01bdSopenharmony_ci        PRINTI("AppManager", "%{public}s AppRecord is already exist", bundleInfo.bundleName);
32a1db01bdSopenharmony_ci        return appRecord;
33a1db01bdSopenharmony_ci    }
34a1db01bdSopenharmony_ci    uint64_t token = TokenGenerate::GenerateToken();
35a1db01bdSopenharmony_ci    appRecord = new AppRecord(bundleInfo, token);
36a1db01bdSopenharmony_ci    AbilityMsStatus status = spawnClient_.SpawnProcess(*appRecord);
37a1db01bdSopenharmony_ci    if (!status.IsOk()) {
38a1db01bdSopenharmony_ci        status.LogStatus();
39a1db01bdSopenharmony_ci        delete appRecord;
40a1db01bdSopenharmony_ci        return nullptr;
41a1db01bdSopenharmony_ci    }
42a1db01bdSopenharmony_ci    PRINTD("AppManager", "start app name:%{public}s, token: %{private}" PRIu64,
43a1db01bdSopenharmony_ci        appRecord->GetBundleInfo().bundleName, token);
44a1db01bdSopenharmony_ci    appRecords_.emplace_back(appRecord);
45a1db01bdSopenharmony_ci    return appRecord;
46a1db01bdSopenharmony_ci}
47a1db01bdSopenharmony_ci
48a1db01bdSopenharmony_civoid AppManager::RemoveAppRecord(const AppRecord &appRecord)
49a1db01bdSopenharmony_ci{
50a1db01bdSopenharmony_ci    for (auto iterator = appRecords_.begin(); iterator != appRecords_.end();) {
51a1db01bdSopenharmony_ci        AppRecord *current = *iterator;
52a1db01bdSopenharmony_ci        if (current != nullptr && current->GetIdentityId() == appRecord.GetIdentityId()) {
53a1db01bdSopenharmony_ci            PRINTD("AppManager", "remove process %{private}" PRIu64, current->GetIdentityId());
54a1db01bdSopenharmony_ci            current->UnloadPermission();
55a1db01bdSopenharmony_ci            iterator = appRecords_.erase(iterator);
56a1db01bdSopenharmony_ci            delete current;
57a1db01bdSopenharmony_ci        } else {
58a1db01bdSopenharmony_ci            ++iterator;
59a1db01bdSopenharmony_ci        }
60a1db01bdSopenharmony_ci    }
61a1db01bdSopenharmony_ci}
62a1db01bdSopenharmony_ci
63a1db01bdSopenharmony_ciAbilityMsStatus AppManager::TerminateAppProcess(const char *bundleName)
64a1db01bdSopenharmony_ci{
65a1db01bdSopenharmony_ci    AppRecord *current = GetAppRecordByBundleName(bundleName);
66a1db01bdSopenharmony_ci    if (current == nullptr) {
67a1db01bdSopenharmony_ci        PRINTI("AppManager", "app record is not find");
68a1db01bdSopenharmony_ci        return AbilityMsStatus::Ok();
69a1db01bdSopenharmony_ci    }
70a1db01bdSopenharmony_ci    // exit app process
71a1db01bdSopenharmony_ci    return current->AppExitTransaction();
72a1db01bdSopenharmony_ci}
73a1db01bdSopenharmony_ci
74a1db01bdSopenharmony_civoid AppManager::RemoveAppRecord(const char *bundleName)
75a1db01bdSopenharmony_ci{
76a1db01bdSopenharmony_ci    CHECK_NULLPTR_RETURN(bundleName, "AppManager", "start");
77a1db01bdSopenharmony_ci    for (auto iterator = appRecords_.cbegin(); iterator != appRecords_.cend();) {
78a1db01bdSopenharmony_ci        const AppRecord *current = *iterator;
79a1db01bdSopenharmony_ci        if (current != nullptr && current->GetBundleInfo().bundleName != nullptr &&
80a1db01bdSopenharmony_ci            (strcmp(current->GetBundleInfo().bundleName, bundleName) == 0)) {
81a1db01bdSopenharmony_ci            PRINTD("AppManager", "remove process name:%{public}s", bundleName);
82a1db01bdSopenharmony_ci            current->UnloadPermission();
83a1db01bdSopenharmony_ci            iterator = appRecords_.erase(iterator);
84a1db01bdSopenharmony_ci            delete current;
85a1db01bdSopenharmony_ci        } else {
86a1db01bdSopenharmony_ci            ++iterator;
87a1db01bdSopenharmony_ci        }
88a1db01bdSopenharmony_ci    }
89a1db01bdSopenharmony_ci}
90a1db01bdSopenharmony_ci
91a1db01bdSopenharmony_ciconst AppRecord *AppManager::GetAppRecordByToken(uint64_t token, pid_t pid)
92a1db01bdSopenharmony_ci{
93a1db01bdSopenharmony_ci    for (const auto &appRecord : appRecords_) {
94a1db01bdSopenharmony_ci        if (appRecord != nullptr && appRecord->GetIdentityId() == token && appRecord->GetPid() == pid) {
95a1db01bdSopenharmony_ci            return appRecord;
96a1db01bdSopenharmony_ci        }
97a1db01bdSopenharmony_ci    }
98a1db01bdSopenharmony_ci    return nullptr;
99a1db01bdSopenharmony_ci}
100a1db01bdSopenharmony_ci
101a1db01bdSopenharmony_ciAppRecord *AppManager::GetAppRecordByBundleName(const char *bundleName)
102a1db01bdSopenharmony_ci{
103a1db01bdSopenharmony_ci    CHECK_NULLPTR_RETURN_PTR(bundleName, "AppManager", "invalid argument");
104a1db01bdSopenharmony_ci    for (const auto &appRecord : appRecords_) {
105a1db01bdSopenharmony_ci        if (appRecord != nullptr && appRecord->GetBundleInfo().bundleName != nullptr &&
106a1db01bdSopenharmony_ci            (strcmp(appRecord->GetBundleInfo().bundleName, bundleName) == 0)) {
107a1db01bdSopenharmony_ci            return appRecord;
108a1db01bdSopenharmony_ci        }
109a1db01bdSopenharmony_ci    }
110a1db01bdSopenharmony_ci    return nullptr;
111a1db01bdSopenharmony_ci}
112a1db01bdSopenharmony_ci}
113