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 #define private public
16 #define protected public
17 #include "enable_ime_data_parser.h"
18 #include "settings_data_utils.h"
19 #undef private
20
21 #include <unistd.h>
22
23 #include <csignal>
24 #include <cstdint>
25 #include <sstream>
26 #include <string>
27 #include <vector>
28
29 #include "accesstoken_kit.h"
30 #include "datashare_helper.h"
31 #include "global.h"
32 #include "if_system_ability_manager.h"
33 #include "iservice_registry.h"
34 #include "nativetoken_kit.h"
35 #include "os_account_manager.h"
36 #include "system_ability.h"
37 #include "system_ability_definition.h"
38 #include "tdd_util.h"
39 #include "token_setproc.h"
40
41 namespace OHOS {
42 namespace MiscServices {
43 using namespace OHOS::Security::AccessToken;
44 using namespace OHOS::AccountSA;
45 using namespace Rosen;
46 constexpr int32_t INVALID_USER_ID = -1;
47 constexpr int32_t MAIN_USER_ID = 100;
48 constexpr const uint16_t EACH_LINE_LENGTH = 500;
49 constexpr int32_t BUFF_LENGTH = 10;
50 constexpr int32_t PERMISSION_NUM = 2;
51 constexpr const char *CMD_PIDOF_IMS = "pidof inputmethod_ser";
52 constexpr const char *SETTING_COLUMN_KEYWORD = "KEYWORD";
53 constexpr const char *SETTING_COLUMN_VALUE = "VALUE";
54 static constexpr int32_t MAX_TIMEOUT_WAIT_FOCUS = 2000;
55 uint64_t TddUtil::selfTokenID_ = 0;
56 int32_t TddUtil::userID_ = INVALID_USER_ID;
57 sptr<Window> TddUtil::WindowManager::window_ = nullptr;
58 int32_t TddUtil::WindowManager::currentWindowId_ = 0;
59 std::shared_ptr<BlockData<bool>> FocusChangedListenerTestImpl::isFocused_ =
60 std::make_shared<BlockData<bool>>(MAX_TIMEOUT_WAIT_FOCUS, false);
61 std::shared_ptr<BlockData<bool>> FocusChangedListenerTestImpl::unFocused_ =
62 std::make_shared<BlockData<bool>>(MAX_TIMEOUT_WAIT_FOCUS, false);
OnFocused(const sptr<Rosen::FocusChangeInfo> & focusChangeInfo)63 void FocusChangedListenerTestImpl::OnFocused(const sptr<Rosen::FocusChangeInfo> &focusChangeInfo)
64 {
65 IMSA_HILOGI("get onFocus information from window manager.");
66 if (focusChangeInfo->windowId_ == TddUtil::WindowManager::currentWindowId_) {
67 getFocus_ = true;
68 isFocused_->SetValue(getFocus_);
69 unFocused_->Clear(false);
70 }
71 }
72
OnUnfocused(const sptr<Rosen::FocusChangeInfo> & focusChangeInfo)73 void FocusChangedListenerTestImpl::OnUnfocused(const sptr<Rosen::FocusChangeInfo> &focusChangeInfo)
74 {
75 IMSA_HILOGI("get unfocus information from window manager.");
76 if (focusChangeInfo->windowId_ == TddUtil::WindowManager::currentWindowId_) {
77 getFocus_ = false;
78 isFocused_->Clear(false);
79 bool unFocus = !getFocus_;
80 unFocused_->SetValue(unFocus);
81 }
82 }
83
GetCurrentUserId()84 int32_t TddUtil::GetCurrentUserId()
85 {
86 if (userID_ != INVALID_USER_ID) {
87 return userID_;
88 }
89 std::vector<int32_t> userIds;
90 auto ret = OsAccountManager::QueryActiveOsAccountIds(userIds);
91 if (ret != ErrorCode::NO_ERROR || userIds.empty()) {
92 IMSA_HILOGE("query active os account id failed");
93 return MAIN_USER_ID;
94 }
95 return userIds[0];
96 }
StorageSelfTokenID()97 void TddUtil::StorageSelfTokenID()
98 {
99 selfTokenID_ = GetSelfTokenID();
100 }
101
AllocTestTokenID(bool isSystemApp,const std::string & bundleName,const std::vector<std::string> & premission)102 uint64_t TddUtil::AllocTestTokenID(
103 bool isSystemApp, const std::string &bundleName, const std::vector<std::string> &premission)
104 {
105 IMSA_HILOGI("bundleName: %{public}s", bundleName.c_str());
106 HapInfoParams infoParams = { .userID = GetCurrentUserId(),
107 .bundleName = bundleName,
108 .instIndex = 0,
109 .appIDDesc = bundleName,
110 .isSystemApp = isSystemApp };
111 std::vector<PermissionStateFull> permStateList;
112 for (const auto &prem : premission) {
113 PermissionStateFull permissionState = { .permissionName = prem,
114 .isGeneral = true,
115 .resDeviceID = { "local" },
116 .grantStatus = { PermissionState::PERMISSION_GRANTED },
117 .grantFlags = { 1 } };
118 permStateList.push_back(permissionState);
119 }
120 HapPolicyParams policyParams = {
121 .apl = APL_NORMAL, .domain = bundleName, .permList = {}, .permStateList = permStateList
122 };
123 if (premission.empty()) {
124 policyParams = { .apl = APL_NORMAL, .domain = bundleName, .permList = {}, .permStateList = {} };
125 }
126 auto tokenInfo = AccessTokenKit::AllocHapToken(infoParams, policyParams);
127 return tokenInfo.tokenIDEx;
128 }
129
GetTestTokenID(const std::string & bundleName)130 uint64_t TddUtil::GetTestTokenID(const std::string &bundleName)
131 {
132 HapInfoParams infoParams = { .userID = GetUserIdByBundleName(bundleName, GetCurrentUserId()),
133 .bundleName = bundleName,
134 .instIndex = 0,
135 .appIDDesc = "ohos.inputmethod_test.demo" };
136 return AccessTokenKit::GetHapTokenID(infoParams.userID, infoParams.bundleName, infoParams.instIndex);
137 }
138
DeleteTestTokenID(uint64_t tokenId)139 void TddUtil::DeleteTestTokenID(uint64_t tokenId)
140 {
141 AccessTokenKit::DeleteToken(tokenId);
142 }
143
SetTestTokenID(uint64_t tokenId)144 void TddUtil::SetTestTokenID(uint64_t tokenId)
145 {
146 auto ret = SetSelfTokenID(tokenId);
147 IMSA_HILOGI("SetSelfTokenID ret: %{public}d", ret);
148 }
149
RestoreSelfTokenID()150 void TddUtil::RestoreSelfTokenID()
151 {
152 auto ret = SetSelfTokenID(selfTokenID_);
153 IMSA_HILOGI("SetSelfTokenID ret = %{public}d", ret);
154 }
155
ExecuteCmd(const std::string & cmd,std::string & result)156 bool TddUtil::ExecuteCmd(const std::string &cmd, std::string &result)
157 {
158 char buff[EACH_LINE_LENGTH] = { 0x00 };
159 std::stringstream output;
160 FILE *ptr = popen(cmd.c_str(), "r");
161 if (ptr != nullptr) {
162 while (fgets(buff, sizeof(buff), ptr) != nullptr) {
163 output << buff;
164 }
165 pclose(ptr);
166 ptr = nullptr;
167 } else {
168 return false;
169 }
170 result = output.str();
171 return true;
172 }
173
GetImsaPid()174 pid_t TddUtil::GetImsaPid()
175 {
176 char buff[BUFF_LENGTH] = { 0 };
177 FILE *fp = popen(CMD_PIDOF_IMS, "r");
178 if (fp == nullptr) {
179 IMSA_HILOGI("get pid failed.");
180 return -1;
181 }
182 fgets(buff, sizeof(buff), fp);
183 pid_t pid = atoi(buff);
184 pclose(fp);
185 fp = nullptr;
186 return pid;
187 }
188
KillImsaProcess()189 void TddUtil::KillImsaProcess()
190 {
191 pid_t pid = GetImsaPid();
192 if (pid == -1) {
193 IMSA_HILOGE("Pid of Imsa is not exist.");
194 return;
195 }
196 auto ret = kill(pid, SIGTERM);
197 if (ret != 0) {
198 IMSA_HILOGE("Kill failed, ret: %{public}d", ret);
199 return;
200 }
201 IMSA_HILOGI("Kill success.");
202 }
203
GetBundleMgr()204 sptr<OHOS::AppExecFwk::IBundleMgr> TddUtil::GetBundleMgr()
205 {
206 sptr<ISystemAbilityManager> systemAbilityManager =
207 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
208 if (systemAbilityManager == nullptr) {
209 IMSA_HILOGE("systemAbilityManager is nullptr");
210 return nullptr;
211 }
212 sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
213 if (remoteObject == nullptr) {
214 IMSA_HILOGE("remoteObject is nullptr");
215 return nullptr;
216 }
217 return iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
218 }
219
GetUserIdByBundleName(const std::string & bundleName,const int currentUserId)220 int TddUtil::GetUserIdByBundleName(const std::string &bundleName, const int currentUserId)
221 {
222 auto bundleMgr = TddUtil::GetBundleMgr();
223 if (bundleMgr == nullptr) {
224 IMSA_HILOGE("Get bundleMgr failed.");
225 return -1;
226 }
227 auto uid = bundleMgr->GetUidByBundleName(bundleName, currentUserId);
228 if (uid == -1) {
229 IMSA_HILOGE("failed to get information and the parameters may be wrong.");
230 return -1;
231 }
232 // 200000 means userId = uid / 200000.
233 return uid / 200000;
234 }
235
GrantNativePermission()236 void TddUtil::GrantNativePermission()
237 {
238 const char **perms = new const char *[PERMISSION_NUM];
239 perms[0] = "ohos.permission.MANAGE_SECURE_SETTINGS";
240 perms[1] = "ohos.permission.CONNECT_IME_ABILITY";
241 TokenInfoParams infoInstance = {
242 .dcapsNum = 0,
243 .permsNum = PERMISSION_NUM,
244 .aclsNum = 0,
245 .dcaps = nullptr,
246 .perms = perms,
247 .acls = nullptr,
248 .processName = "imf_test",
249 .aplStr = "system_core",
250 };
251 uint64_t tokenId = GetAccessTokenId(&infoInstance);
252 int res = SetSelfTokenID(tokenId);
253 if (res == 0) {
254 IMSA_HILOGI("SetSelfTokenID success!");
255 } else {
256 IMSA_HILOGE("SetSelfTokenID fail!");
257 }
258 AccessTokenKit::ReloadNativeTokenInfo();
259 delete[] perms;
260 }
261
PushEnableImeValue(const std::string & key,const std::string & value)262 void TddUtil::PushEnableImeValue(const std::string &key, const std::string &value)
263 {
264 auto helper = SettingsDataUtils::GetInstance()->CreateDataShareHelper();
265 if (helper == nullptr) {
266 IMSA_HILOGE("helper is nullptr.");
267 return;
268 }
269 DataShare::DataShareValueObject keyObj(key);
270 DataShare::DataShareValueObject valueObj(value);
271 DataShare::DataShareValuesBucket bucket;
272 bucket.Put(SETTING_COLUMN_KEYWORD, keyObj);
273 bucket.Put(SETTING_COLUMN_VALUE, valueObj);
274 DataShare::DataSharePredicates predicates;
275 predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
276 Uri uri(SettingsDataUtils::GetInstance()->GenerateTargetUri(key));
277 if (helper->Update(uri, predicates, bucket) <= 0) {
278 IMSA_HILOGD("no data exist, insert one row");
279 helper->Insert(uri, bucket);
280 }
281 SettingsDataUtils::GetInstance()->ReleaseDataShareHelper(helper);
282 }
283
GetEnableData(std::string & value)284 int32_t TddUtil::GetEnableData(std::string &value)
285 {
286 return SettingsDataUtils::GetInstance()->GetStringValue(EnableImeDataParser::ENABLE_IME, value);
287 }
288
InitWindow(bool isShow)289 void TddUtil::InitWindow(bool isShow)
290 {
291 WindowManager::RegisterFocusChangeListener();
292 WindowManager::CreateWindow();
293 if (!isShow) {
294 return;
295 }
296 WindowManager::ShowWindow();
297 bool isFocused = FocusChangedListenerTestImpl::isFocused_->GetValue();
298 IMSA_HILOGI("getFocus end, isFocused = %{public}d", isFocused);
299 }
300
DestroyWindow()301 void TddUtil::DestroyWindow()
302 {
303 WindowManager::HideWindow();
304 WindowManager::DestroyWindow();
305 }
306
GetFocused()307 bool TddUtil::GetFocused()
308 {
309 WindowManager::ShowWindow();
310 bool isFocused = FocusChangedListenerTestImpl::isFocused_->GetValue();
311 IMSA_HILOGI("getFocus end, isFocused = %{public}d", isFocused);
312 return isFocused;
313 }
314
GetUnfocused()315 bool TddUtil::GetUnfocused()
316 {
317 WindowManager::HideWindow();
318 bool unFocused = FocusChangedListenerTestImpl::unFocused_->GetValue();
319 IMSA_HILOGI("unFocused end, unFocused = %{public}d", unFocused);
320 return unFocused;
321 }
322
CreateWindow()323 void TddUtil::WindowManager::CreateWindow()
324 {
325 std::string windowName = "inputmethod_test_window";
326 sptr<WindowOption> winOption = new OHOS::Rosen::WindowOption();
327 winOption->SetWindowType(WindowType::WINDOW_TYPE_FLOAT);
328 winOption->SetFocusable(true);
329 std::shared_ptr<AbilityRuntime::Context> context = nullptr;
330 WMError wmError = WMError::WM_OK;
331 window_ = Window::Create(windowName, winOption, context, wmError);
332 IMSA_HILOGI("Create window ret:%{public}d", wmError);
333 currentWindowId_ = window_->GetWindowId();
334 }
335
ShowWindow()336 void TddUtil::WindowManager::ShowWindow()
337 {
338 if (window_ == nullptr) {
339 IMSA_HILOGE("window is not exist.");
340 return;
341 }
342 auto ret = window_->Show();
343 IMSA_HILOGI("Show window end, ret = %{public}d", ret);
344 }
345
HideWindow()346 void TddUtil::WindowManager::HideWindow()
347 {
348 if (window_ == nullptr) {
349 IMSA_HILOGE("window is not exist.");
350 return;
351 }
352 auto ret = window_->Hide();
353 IMSA_HILOGI("Hide window end, ret = %{public}d", ret);
354 }
355
DestroyWindow()356 void TddUtil::WindowManager::DestroyWindow()
357 {
358 if (window_ != nullptr) {
359 window_->Destroy();
360 }
361 }
362
RegisterFocusChangeListener()363 void TddUtil::WindowManager::RegisterFocusChangeListener()
364 {
365 auto listener = new (std::nothrow) FocusChangedListenerTestImpl();
366 WMError ret = Rosen::WindowManager::GetInstance().RegisterFocusChangedListener(listener);
367 IMSA_HILOGI("register focus changed listener ret: %{public}d", ret);
368 }
369 } // namespace MiscServices
370 } // namespace OHOS
371