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 "app_jump_interceptor_manager_rdb.h"
17 #include "app_log_tag_wrapper.h"
18 #include "bundle_mgr_service.h"
19 #include "scope_guard.h"
20
21 namespace OHOS {
22 namespace AppExecFwk {
23 namespace {
24 const std::string APP_JUMP_INTERCEPTOR_RDB_TABLE_NAME = "app_jump_interceptor";
25
26 const int32_t CALLER_PKG_INDEX = 1;
27 const int32_t TARGET_PKG_INDEX = 2;
28 const int32_t SELECT_STATUS_INDEX = 3;
29 // app jump interceptor table key
30 const std::string CALLER_PKG = "CALLER_PKG";
31 const std::string TARGET_PKG = "TARGET_PKG";
32 const std::string SELECT_STATUS = "SELECT_STATUS";
33 const std::string USER_ID = "USER_ID";
34 const std::string MODIFIED_TIME = "MODIFIED_TIME";
35 }
36
AppJumpInterceptorManagerRdb()37 AppJumpInterceptorManagerRdb::AppJumpInterceptorManagerRdb()
38 {
39 BmsRdbConfig bmsRdbConfig;
40 bmsRdbConfig.dbName = ServiceConstants::BUNDLE_RDB_NAME;
41 bmsRdbConfig.tableName = APP_JUMP_INTERCEPTOR_RDB_TABLE_NAME;
42 bmsRdbConfig.createTableSql = std::string(
43 "CREATE TABLE IF NOT EXISTS "
44 + APP_JUMP_INTERCEPTOR_RDB_TABLE_NAME
45 + "(ID INTEGER PRIMARY KEY AUTOINCREMENT, CALLER_PKG TEXT NOT NULL, "
46 + "TARGET_PKG TEXT NOT NULL, SELECT_STATUS INTEGER, "
47 + "USER_ID INTEGER, MODIFIED_TIME INTEGER);");
48 rdbDataManager_ = std::make_shared<RdbDataManager>(bmsRdbConfig);
49 rdbDataManager_->CreateTable();
50 }
51
~AppJumpInterceptorManagerRdb()52 AppJumpInterceptorManagerRdb::~AppJumpInterceptorManagerRdb()
53 {
54 }
55
SubscribeCommonEvent()56 bool AppJumpInterceptorManagerRdb::SubscribeCommonEvent()
57 {
58 if (eventSubscriber_ != nullptr) {
59 LOG_I(BMS_TAG_DEFAULT, "subscribeCommonEvent already subscribed");
60 return true;
61 }
62 eventSubscriber_ = new (std::nothrow) AppJumpInterceptorEventSubscriber(shared_from_this());
63 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
64 if (!dataMgr->RegisterBundleEventCallback(eventSubscriber_)) {
65 LOG_E(BMS_TAG_DEFAULT, "subscribeCommonEvent subscribed failure");
66 return false;
67 };
68 LOG_I(BMS_TAG_DEFAULT, "subscribeCommonEvent subscribed success");
69 return true;
70 }
71
72
ConfirmAppJumpControlRule(const std::string & callerBundleName,const std::string & targetBundleName,int32_t userId)73 ErrCode AppJumpInterceptorManagerRdb::ConfirmAppJumpControlRule(const std::string &callerBundleName,
74 const std::string &targetBundleName, int32_t userId)
75 {
76 std::vector<AppJumpControlRule> controlRules;
77 AppJumpControlRule rule;
78 rule.callerPkg = callerBundleName;
79 rule.targetPkg = targetBundleName;
80 controlRules.emplace_back(rule);
81 DeleteAppJumpControlRule(controlRules, userId);
82 return AddAppJumpControlRule(controlRules, userId);
83 }
84
AddAppJumpControlRule(const std::vector<AppJumpControlRule> & controlRules,int32_t userId)85 ErrCode AppJumpInterceptorManagerRdb::AddAppJumpControlRule(const std::vector<AppJumpControlRule> &controlRules,
86 int32_t userId)
87 {
88 int64_t timeStamp = BundleUtil::GetCurrentTime();
89 std::vector<NativeRdb::ValuesBucket> valuesBuckets;
90 for (const auto &controlRule : controlRules) {
91 NativeRdb::ValuesBucket valuesBucket;
92 valuesBucket.PutString(CALLER_PKG, controlRule.callerPkg);
93 valuesBucket.PutString(TARGET_PKG, controlRule.targetPkg);
94 valuesBucket.PutInt(SELECT_STATUS, (int) controlRule.jumpMode);
95 valuesBucket.PutInt(USER_ID, userId);
96 valuesBucket.PutInt(MODIFIED_TIME, timeStamp);
97 valuesBuckets.emplace_back(valuesBucket);
98 }
99 int64_t insertNum = 0;
100 bool ret = rdbDataManager_->BatchInsert(insertNum, valuesBuckets);
101 if (!ret) {
102 LOG_E(BMS_TAG_DEFAULT, "BatchInsert AddAppJumpControlRule failed");
103 return ERR_BUNDLE_MANAGER_APP_CONTROL_INTERNAL_ERROR;
104 }
105 if (valuesBuckets.size() != static_cast<uint64_t>(insertNum)) {
106 LOG_E(BMS_TAG_DEFAULT, "BatchInsert size not expected");
107 return ERR_BUNDLE_MANAGER_APP_CONTROL_INTERNAL_ERROR;
108 }
109 return ERR_OK;
110 }
111
DeleteAppJumpControlRule(const std::vector<AppJumpControlRule> & controlRules,int32_t userId)112 ErrCode AppJumpInterceptorManagerRdb::DeleteAppJumpControlRule(const std::vector<AppJumpControlRule> &controlRules,
113 int32_t userId)
114 {
115 bool result = true;
116 for (auto &rule : controlRules) {
117 NativeRdb::AbsRdbPredicates absRdbPredicates(APP_JUMP_INTERCEPTOR_RDB_TABLE_NAME);
118 absRdbPredicates.EqualTo(CALLER_PKG, rule.callerPkg);
119 absRdbPredicates.EqualTo(TARGET_PKG, rule.targetPkg);
120 absRdbPredicates.EqualTo(USER_ID, std::to_string(userId));
121 bool ret = rdbDataManager_->DeleteData(absRdbPredicates);
122 if (!ret) {
123 LOG_E(BMS_TAG_DEFAULT, "Delete failed caller:%{public}s target:%{public}s userId:%{public}d",
124 rule.callerPkg.c_str(), rule.targetPkg.c_str(), userId);
125 result = false;
126 }
127 }
128 return result ? ERR_OK : ERR_BUNDLE_MANAGER_APP_CONTROL_INTERNAL_ERROR;
129 }
130
DeleteRuleByCallerBundleName(const std::string & callerBundleName,int32_t userId)131 ErrCode AppJumpInterceptorManagerRdb::DeleteRuleByCallerBundleName(const std::string &callerBundleName, int32_t userId)
132 {
133 NativeRdb::AbsRdbPredicates absRdbPredicates(APP_JUMP_INTERCEPTOR_RDB_TABLE_NAME);
134 absRdbPredicates.EqualTo(CALLER_PKG, callerBundleName);
135 absRdbPredicates.EqualTo(USER_ID, std::to_string(userId));
136 bool ret = rdbDataManager_->DeleteData(absRdbPredicates);
137 if (!ret) {
138 LOG_E(BMS_TAG_DEFAULT, "DeleteRuleByCallerBundleName callerBundleName:%{public}s, failed",
139 callerBundleName.c_str());
140 return ERR_BUNDLE_MANAGER_APP_CONTROL_INTERNAL_ERROR;
141 }
142 return ERR_OK;
143 }
144
DeleteRuleByTargetBundleName(const std::string & targetBundleName,int32_t userId)145 ErrCode AppJumpInterceptorManagerRdb::DeleteRuleByTargetBundleName(const std::string &targetBundleName, int32_t userId)
146 {
147 NativeRdb::AbsRdbPredicates absRdbPredicates(APP_JUMP_INTERCEPTOR_RDB_TABLE_NAME);
148 absRdbPredicates.EqualTo(TARGET_PKG, targetBundleName);
149 absRdbPredicates.EqualTo(USER_ID, std::to_string(userId));
150 bool ret = rdbDataManager_->DeleteData(absRdbPredicates);
151 if (!ret) {
152 LOG_E(BMS_TAG_DEFAULT, "DeleteRuleByTargetBundleName targetBundleName:%{public}s, failed",
153 targetBundleName.c_str());
154 return ERR_BUNDLE_MANAGER_APP_CONTROL_INTERNAL_ERROR;
155 }
156 return ERR_OK;
157 }
158
GetAppJumpControlRule(const std::string & callerBundleName,const std::string & targetBundleName,int32_t userId,AppJumpControlRule & controlRule)159 ErrCode AppJumpInterceptorManagerRdb::GetAppJumpControlRule(const std::string &callerBundleName,
160 const std::string &targetBundleName, int32_t userId, AppJumpControlRule &controlRule)
161 {
162 NativeRdb::AbsRdbPredicates absRdbPredicates(APP_JUMP_INTERCEPTOR_RDB_TABLE_NAME);
163 absRdbPredicates.EqualTo(CALLER_PKG, callerBundleName);
164 absRdbPredicates.EqualTo(TARGET_PKG, targetBundleName);
165 absRdbPredicates.EqualTo(USER_ID, std::to_string(userId));
166 absRdbPredicates.OrderByAsc(MODIFIED_TIME); // ascending
167 auto absSharedResultSet = rdbDataManager_->QueryData(absRdbPredicates);
168 if (absSharedResultSet == nullptr) {
169 LOG_E(BMS_TAG_DEFAULT, "QueryData failed");
170 return ERR_BUNDLE_MANAGER_APP_JUMP_INTERCEPTOR_INTERNAL_ERROR;
171 }
172 ScopeGuard stateGuard([absSharedResultSet] { absSharedResultSet->Close(); });
173 int32_t count;
174 int ret = absSharedResultSet->GetRowCount(count);
175 if (ret != NativeRdb::E_OK) {
176 LOG_E(BMS_TAG_DEFAULT, "GetRowCount failed, ret: %{public}d", ret);
177 return ERR_BUNDLE_MANAGER_APP_JUMP_INTERCEPTOR_INTERNAL_ERROR;
178 }
179 if (count == 0) {
180 LOG_E(BMS_TAG_DEFAULT, "GetAppRunningControlRuleResult size 0");
181 return ERR_BUNDLE_MANAGER_BUNDLE_NOT_SET_JUMP_INTERCPTOR;
182 }
183 ret = absSharedResultSet->GoToFirstRow();
184 if (ret != NativeRdb::E_OK) {
185 LOG_E(BMS_TAG_DEFAULT, "GoToFirstRow failed, ret: %{public}d", ret);
186 return ERR_BUNDLE_MANAGER_APP_JUMP_INTERCEPTOR_INTERNAL_ERROR;
187 }
188 std::string callerPkg;
189 if (absSharedResultSet->GetString(CALLER_PKG_INDEX, callerPkg) != NativeRdb::E_OK) {
190 LOG_E(BMS_TAG_DEFAULT, "GetString callerPkg failed, ret: %{public}d", ret);
191 return ERR_BUNDLE_MANAGER_APP_JUMP_INTERCEPTOR_INTERNAL_ERROR;
192 }
193 std::string targetPkg;
194 ret = absSharedResultSet->GetString(TARGET_PKG_INDEX, targetPkg);
195 if (ret != NativeRdb::E_OK) {
196 LOG_W(BMS_TAG_DEFAULT, "GetString targetPkg failed, ret: %{public}d", ret);
197 return ERR_BUNDLE_MANAGER_APP_JUMP_INTERCEPTOR_INTERNAL_ERROR;
198 }
199 int32_t selectStatus;
200 ret = absSharedResultSet->GetInt(SELECT_STATUS_INDEX, selectStatus);
201 if (ret != NativeRdb::E_OK) {
202 LOG_W(BMS_TAG_DEFAULT, "GetInt selectStatus failed, ret: %{public}d", ret);
203 return ERR_BUNDLE_MANAGER_APP_JUMP_INTERCEPTOR_INTERNAL_ERROR;
204 }
205 controlRule.jumpMode = (AppExecFwk::AbilityJumpMode) selectStatus;
206 return ERR_OK;
207 }
208 }
209 }