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 }