1 /*
2  * Copyright (c) 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 "nlohmann/json.hpp"
17 #include "system_ability_manager.h"
18 #include "system_ability_manager_util.h"
19 #include "parameter.h"
20 #include "accesstoken_kit.h"
21 #include "ipc_skeleton.h"
22 #include "string_ex.h"
23 #include "tools.h"
24 #include "sam_log.h"
25 
26 namespace OHOS {
27 using namespace std;
28 constexpr int32_t MAX_NAME_SIZE = 200;
29 constexpr int32_t SPLIT_NAME_VECTOR_SIZE = 2;
30 constexpr int32_t UID_ROOT = 0;
31 constexpr int32_t UID_SYSTEM = 1000;
32 constexpr int32_t SHFIT_BIT = 32;
33 
34 constexpr const char* EVENT_TYPE = "eventId";
35 constexpr const char* EVENT_NAME = "name";
36 constexpr const char* EVENT_VALUE = "value";
37 constexpr const char* EVENT_EXTRA_DATA_ID = "extraDataId";
38 constexpr const char* MODULE_UPDATE_PARAM = "persist.samgr.moduleupdate";
39 std::shared_ptr<FFRTHandler> SamgrUtil::setParmHandler_ = make_shared<FFRTHandler>("setParmHandler");
40 
IsNameInValid(const std::u16string & name)41 bool SamgrUtil::IsNameInValid(const std::u16string& name)
42 {
43     HILOGD("%{public}s called:name = %{public}s", __func__, Str16ToStr8(name).c_str());
44     bool ret = false;
45     if (name.empty() || name.size() > MAX_NAME_SIZE || DeleteBlank(name).empty()) {
46         ret = true;
47     }
48 
49     return ret;
50 }
51 
ParseRemoteSaName(const std::u16string & name,std::string & deviceId,std::u16string & saName)52 void SamgrUtil::ParseRemoteSaName(const std::u16string& name, std::string& deviceId,
53     std::u16string& saName)
54 {
55     vector<string> strVector;
56     SplitStr(Str16ToStr8(name), "_", strVector);
57     if (strVector.size() == SPLIT_NAME_VECTOR_SIZE) {
58         deviceId = strVector[0];
59         saName = Str8ToStr16(strVector[1]);
60     }
61 }
62 
CheckDistributedPermission()63 bool SamgrUtil::CheckDistributedPermission()
64 {
65     auto callingUid = IPCSkeleton::GetCallingUid();
66     if (callingUid != UID_ROOT && callingUid != UID_SYSTEM) {
67         return false;
68     }
69     return true;
70 }
71 
IsSameEvent(const OnDemandEvent & event,std::list<OnDemandEvent> & enableOnceList)72 bool SamgrUtil::IsSameEvent(const OnDemandEvent& event, std::list<OnDemandEvent>& enableOnceList)
73 {
74     for (auto iter = enableOnceList.begin(); iter != enableOnceList.end(); iter++) {
75         if (event.eventId == iter->eventId && event.name == iter->name && event.value == iter->value) {
76             HILOGI("event already exits in enable-once list");
77             return true;
78         }
79     }
80     return false;
81 }
82 
EventToStr(const OnDemandEvent & event)83 std::string SamgrUtil::EventToStr(const OnDemandEvent& event)
84 {
85     nlohmann::json eventJson;
86     eventJson[EVENT_TYPE] = event.eventId;
87     eventJson[EVENT_NAME] = event.name;
88     eventJson[EVENT_VALUE] = event.value;
89     eventJson[EVENT_EXTRA_DATA_ID] = event.extraDataId;
90     std::string eventStr = eventJson.dump();
91     return eventStr;
92 }
93 
TransformDeviceId(const std::string & deviceId,int32_t type,bool isPrivate)94 std::string SamgrUtil::TransformDeviceId(const std::string& deviceId, int32_t type, bool isPrivate)
95 {
96     return isPrivate ? std::string() : deviceId;
97 }
98 
CheckCallerProcess(const SaProfile & saProfile)99 bool SamgrUtil::CheckCallerProcess(const SaProfile& saProfile)
100 {
101     if (!CheckCallerProcess(Str16ToStr8(saProfile.process))) {
102         HILOGE("can't operate SA: %{public}d by proc:%{public}s",
103             saProfile.saId, Str16ToStr8(saProfile.process).c_str());
104         return false;
105     }
106     return true;
107 }
108 
CheckCallerProcess(const std::string & callProcess)109 bool SamgrUtil::CheckCallerProcess(const std::string& callProcess)
110 {
111     uint32_t accessToken = IPCSkeleton::GetCallingTokenID();
112     Security::AccessToken::NativeTokenInfo nativeTokenInfo;
113     int32_t tokenInfoResult = Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(accessToken, nativeTokenInfo);
114     if (tokenInfoResult != ERR_OK) {
115         HILOGE("get token info failed");
116         return false;
117     }
118 
119     if (nativeTokenInfo.processName != callProcess) {
120         HILOGE("can't operate by proc:%{public}s", nativeTokenInfo.processName.c_str());
121         return false;
122     }
123     return true;
124 }
125 
CheckAllowUpdate(OnDemandPolicyType type,const SaProfile & saProfile)126 bool SamgrUtil::CheckAllowUpdate(OnDemandPolicyType type, const SaProfile& saProfile)
127 {
128     if (type == OnDemandPolicyType::START_POLICY && saProfile.startOnDemand.allowUpdate) {
129         return true;
130     } else if (type == OnDemandPolicyType::STOP_POLICY && saProfile.stopOnDemand.allowUpdate) {
131         return true;
132     }
133     return false;
134 }
135 
ConvertToOnDemandEvent(const SystemAbilityOnDemandEvent & from,OnDemandEvent & to)136 void SamgrUtil::ConvertToOnDemandEvent(const SystemAbilityOnDemandEvent& from, OnDemandEvent& to)
137 {
138     to.eventId = static_cast<int32_t>(from.eventId);
139     to.name = from.name;
140     to.value = from.value;
141     to.persistence = from.persistence;
142     for (auto& item : from.conditions) {
143         OnDemandCondition condition;
144         condition.eventId = static_cast<int32_t>(item.eventId);
145         condition.name = item.name;
146         condition.value = item.value;
147         to.conditions.push_back(condition);
148     }
149     to.enableOnce = from.enableOnce;
150 }
151 
ConvertToSystemAbilityOnDemandEvent(const OnDemandEvent & from,SystemAbilityOnDemandEvent & to)152 void SamgrUtil::ConvertToSystemAbilityOnDemandEvent(const OnDemandEvent& from,
153     SystemAbilityOnDemandEvent& to)
154 {
155     to.eventId = static_cast<OnDemandEventId>(from.eventId);
156     to.name = from.name;
157     to.value = from.value;
158     to.persistence = from.persistence;
159     for (auto& item : from.conditions) {
160         SystemAbilityOnDemandCondition condition;
161         condition.eventId = static_cast<OnDemandEventId>(item.eventId);
162         condition.name = item.name;
163         condition.value = item.value;
164         to.conditions.push_back(condition);
165     }
166     to.enableOnce = from.enableOnce;
167 }
168 
GenerateFreKey(int32_t uid,int32_t saId)169 uint64_t SamgrUtil::GenerateFreKey(int32_t uid, int32_t saId)
170 {
171     uint32_t uSaid = static_cast<uint32_t>(saId);
172     uint64_t key = static_cast<uint64_t>(uid);
173     return (key << SHFIT_BIT) | uSaid;
174 }
175 
GetCacheCommonEventSa(const OnDemandEvent & event,const std::list<SaControlInfo> & saControlList)176 std::list<int32_t> SamgrUtil::GetCacheCommonEventSa(const OnDemandEvent& event,
177     const std::list<SaControlInfo>& saControlList)
178 {
179     std::list<int32_t> saList;
180     if (event.eventId != COMMON_EVENT || event.extraDataId == -1) {
181         return saList;
182     }
183     for (auto& item : saControlList) {
184         if (item.cacheCommonEvent) {
185             saList.emplace_back(item.saId);
186         }
187     }
188     return saList;
189 }
190 
SetModuleUpdateParam(const std::string & key,const std::string & value)191 void SamgrUtil::SetModuleUpdateParam(const std::string& key, const std::string& value)
192 {
193     auto SetParamTask = [=] () {
194         int ret = SetParameter(key.c_str(), value.c_str());
195         if (ret != 0) {
196             HILOGE("SetModuleUpdateParam SetParameter error:%{public}d!", ret);
197             return;
198         }
199     };
200     setParmHandler_->PostTask(SetParamTask);
201 }
202 
SendUpdateSaState(int32_t systemAbilityId,const std::string & updateSaState)203 void SamgrUtil::SendUpdateSaState(int32_t systemAbilityId, const std::string& updateSaState)
204 {
205     if (SystemAbilityManager::GetInstance()->IsModuleUpdate(systemAbilityId)) {
206         std::string startKey = std::string(MODULE_UPDATE_PARAM) + ".start";
207         std::string saKey = std::string(MODULE_UPDATE_PARAM) + "." + std::to_string(systemAbilityId);
208         SamgrUtil::SetModuleUpdateParam(startKey, "true");
209         SamgrUtil::SetModuleUpdateParam(saKey, updateSaState);
210     }
211 }
212 
InvalidateSACache()213 void SamgrUtil::InvalidateSACache()
214 {
215     auto invalidateCacheTask = [] () {
216         SystemAbilityManager::GetInstance()->InvalidateCache();
217     };
218     setParmHandler_->PostTask(invalidateCacheTask);
219 }
220 }
221