1 /*
2  * Copyright (c) 2023 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 "bms_helper.h"
17 #include "aafwk_event_error_code.h"
18 #include "ability_errors.h"
19 #include "abilityms_log.h"
20 #include "utils.h"
21 
22 using namespace OHOS::ACELite;
23 
24 namespace OHOS::AbilitySlite {
25 namespace {
26 constexpr uint16_t BUNDLE_LIST_CAPACITY = 256;
27 const char* DEFAULT_STARTUP_BUNDLE_NAME = "com.ohos.launcher";
28 }
~BMSHelper()29 BMSHelper::~BMSHelper()
30 {
31     Erase();
32 }
33 
RegisterBundleNames(const List<char * > & names)34 int32_t BMSHelper::RegisterBundleNames(const List<char *> &names)
35 {
36     if (names.Size() + bundleNames_.Size() > BUNDLE_LIST_CAPACITY) {
37         return PARAM_CHECK_ERROR;
38     }
39     for (auto node = names.Begin(); node != names.End(); node = node->next_) {
40         char *bundleName = node->value_;
41         if (bundleName != nullptr) {
42             char *name = Utils::Strdup(bundleName);
43             bundleNames_.PushBack(name);
44         }
45     }
46     return ERR_OK;
47 }
48 
RegisterStartupBundleName(const char * bundleName)49 int32_t BMSHelper::RegisterStartupBundleName(const char *bundleName)
50 {
51     if (bundleName == nullptr) {
52         return PARAM_NULL_ERROR;
53     }
54     AdapterFree(startupBundleName_);
55     startupBundleName_ = Utils::Strdup(bundleName);
56     return ERR_OK;
57 }
58 
GetStartupBundleName()59 const char *BMSHelper::GetStartupBundleName()
60 {
61     if (startupBundleName_ == nullptr) {
62         return DEFAULT_STARTUP_BUNDLE_NAME;
63     }
64     return startupBundleName_;
65 }
66 
RegisterTemporaryBundleNames(const List<char * > & names)67 int32_t BMSHelper::RegisterTemporaryBundleNames(const List<char *> &names)
68 {
69     if (names.Size() + temporaryBundleNames_.Size() > BUNDLE_LIST_CAPACITY) {
70         return PARAM_CHECK_ERROR;
71     }
72     for (auto node = names.Begin(); node != names.End(); node = node->next_) {
73         char *bundleName = node->value_;
74         if (bundleName != nullptr) {
75             char *name = Utils::Strdup(bundleName);
76             temporaryBundleNames_.PushBack(name);
77         }
78     }
79     return ERR_OK;
80 }
81 
IsTemporaryBundleName(const char * bundleName)82 bool BMSHelper::IsTemporaryBundleName(const char *bundleName)
83 {
84     if (bundleName == nullptr) {
85         return false;
86     }
87     for (auto node = temporaryBundleNames_.Begin(); node != temporaryBundleNames_.End(); node = node->next_) {
88         char *temporaryBundleName = node->value_;
89         if (temporaryBundleName != nullptr && strcmp(bundleName, temporaryBundleName) == 0) {
90             return true;
91         }
92     }
93     return false;
94 }
95 
Erase()96 void BMSHelper::Erase()
97 {
98     while (bundleNames_.Front() != nullptr) {
99         char *name = bundleNames_.Front();
100         AdapterFree(name);
101         bundleNames_.PopFront();
102     }
103     AdapterFree(startupBundleName_);
104     while (temporaryBundleNames_.Front() != nullptr) {
105         char *name = temporaryBundleNames_.Front();
106         AdapterFree(name);
107         temporaryBundleNames_.PopFront();
108     }
109 }
110 
IsNativeApp(const char * bundleName)111 bool BMSHelper::IsNativeApp(const char *bundleName)
112 {
113     if (bundleName == nullptr) {
114         return false;
115     }
116     for (auto node = bundleNames_.Begin(); node != bundleNames_.End(); node = node->next_) {
117         char *bundleName_ = node->value_;
118         if (strcmp(bundleName, bundleName_) == 0) {
119             return true;
120         }
121     }
122     return false;
123 }
124 
QueryAbilitySvcInfo(const Want * want,AbilitySvcInfo * svcInfo)125 uint8_t BMSHelper::QueryAbilitySvcInfo(const Want *want, AbilitySvcInfo *svcInfo)
126 {
127 #ifdef _MINI_BMS_
128     if (want == nullptr || want->element == nullptr || want->element->bundleName == nullptr) {
129         return PARAM_NULL_ERROR;
130     }
131     if (IsNativeApp(want->element->bundleName)) {
132         svcInfo->bundleName = OHOS::Utils::Strdup(want->element->bundleName);
133         svcInfo->path = nullptr;
134         svcInfo->isNativeApp = true;
135         return ERR_OK;
136     }
137 
138     AbilityInfo abilityInfo = { nullptr, nullptr };
139     memset_s(&abilityInfo, sizeof(AbilityInfo), 0, sizeof(AbilityInfo));
140     QueryAbilityInfo(want, &abilityInfo);
141     if (!IsValidAbility(&abilityInfo)) {
142         APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_START_UNKNOWN_BUNDLE_INFO);
143         HILOG_ERROR(HILOG_MODULE_AAFWK, "Invalid AbilityInfo");
144         ClearAbilityInfo(&abilityInfo);
145         return PARAM_CHECK_ERROR;
146     }
147     svcInfo->bundleName = OHOS::Utils::Strdup(abilityInfo.bundleName);
148     svcInfo->path = OHOS::Utils::Strdup(abilityInfo.srcPath);
149     svcInfo->isNativeApp = false;
150     ClearAbilityInfo(&abilityInfo);
151     return ERR_OK;
152 #else
153     svcInfo->bundleName = Utils::Strdup(want->element->bundleName);
154     // Here users assign want->data with js app path.
155     svcInfo->path = Utils::Strdup((const char *)want->data);
156     return ERR_OK;
157 #endif
158 }
159 
IsValidAbility(const AbilityInfo * abilityInfo)160 bool BMSHelper::IsValidAbility(const AbilityInfo *abilityInfo)
161 {
162     if (abilityInfo == nullptr) {
163         return false;
164     }
165     if (abilityInfo->bundleName == nullptr || abilityInfo->srcPath == nullptr) {
166         return false;
167     }
168     if (strlen(abilityInfo->bundleName) == 0 || strlen(abilityInfo->srcPath) == 0) {
169         return false;
170     }
171     return true;
172 }
173 
ClearAbilitySvcInfo(AbilitySvcInfo * abilitySvcInfo)174 void BMSHelper::ClearAbilitySvcInfo(AbilitySvcInfo *abilitySvcInfo)
175 {
176     if (abilitySvcInfo == nullptr) {
177         return;
178     }
179     AdapterFree(abilitySvcInfo->bundleName);
180     AdapterFree(abilitySvcInfo->path);
181 }
182 }
183