• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "on_screen_server.h"
17 
18 #include <algorithm>
19 #include <dlfcn.h>
20 #include <vector>
21 
22 #include "accesstoken_kit.h"
23 #include "devicestatus_define.h"
24 #include "tokenid_kit.h"
25 
26 #undef LOG_TAG
27 #define LOG_TAG "OnScreenServer"
28 
29 namespace OHOS {
30 namespace Msdp {
31 namespace DeviceStatus {
32 namespace OnScreen {
33 namespace {
34 const char *LIB_ON_SCREEN_ALGO_PATH = "/system/lib64/libon_screen.z.so";
35 const char *PERMISSION_GET_PAGE_CONTENT = "ohos.permission.GET_SCREEN_CONTENT";
36 const char *PERMISSION_SEND_CONTROL_EVENT = "ohos.permission.SIMULATE_USER_INPUT";
37 constexpr int32_t RET_NO_SUPPORT = 801;
38 constexpr int32_t RET_NO_PERMISSION = 201;
39 constexpr int32_t RET_NO_SYSTEM_CALLING = 202;
40 }
41 
~OnScreenAlgorithmHandle()42 OnScreenAlgorithmHandle::~OnScreenAlgorithmHandle()
43 {
44     Clear();
45 }
46 
Clear()47 void OnScreenAlgorithmHandle::Clear()
48 {
49     handle = nullptr;
50     pAlgorithm = nullptr;
51     create = nullptr;
52     destroy = nullptr;
53 }
54 
~OnScreenServer()55 OnScreenServer::~OnScreenServer()
56 {
57     UnloadAlgoLib();
58 }
59 
GetPageContent(const CallingContext & context,const ContentOption & option,PageContent & pageContent)60 int32_t OnScreenServer::GetPageContent(const CallingContext &context, const ContentOption &option,
61     PageContent &pageContent)
62 {
63     std::lock_guard lockGrd(mtx_);
64     int32_t ret = RET_OK;
65     if (!CheckPermission(context, PERMISSION_GET_PAGE_CONTENT)) {
66         FI_HILOGE("checkpermission failed, premission = %{public}s", PERMISSION_GET_PAGE_CONTENT);
67         return RET_NO_PERMISSION;
68     }
69     if (!IsSystemCalling(context)) {
70         FI_HILOGE("calling is not system calling");
71         return RET_NO_SYSTEM_CALLING;
72     }
73     if (ConnectAlgoLib() != RET_OK) {
74         FI_HILOGE("failed to load algo lib");
75         return RET_NO_SUPPORT;
76     }
77     OnScreenCallingContext onScreenContext {
78         .fullTokenId = context.fullTokenId,
79         .tokenId = context.tokenId,
80         .uid = context.uid,
81         .pid = context.pid,
82     };
83     FI_HILOGI("get page content invoke algo lib");
84     ret = handle_.pAlgorithm->GetPageContent(onScreenContext, option, pageContent);
85     if (ret != RET_OK) {
86         FI_HILOGE("failed to get page content, err=%{public}d", ret);
87         return ret;
88     }
89     return RET_OK;
90 }
91 
SendControlEvent(const CallingContext & context,const ControlEvent & event)92 int32_t OnScreenServer::SendControlEvent(const CallingContext &context, const ControlEvent &event)
93 {
94     std::lock_guard lockGrd(mtx_);
95     int32_t ret = RET_OK;
96     if (!CheckPermission(context, PERMISSION_SEND_CONTROL_EVENT)) {
97         FI_HILOGE("checkpermission failed, premission = %{public}s", PERMISSION_SEND_CONTROL_EVENT);
98         return RET_NO_PERMISSION;
99     }
100     if (!IsSystemCalling(context)) {
101         FI_HILOGE("calling is not system calling");
102         return RET_NO_SYSTEM_CALLING;
103     }
104     if (ConnectAlgoLib() != RET_OK) {
105         FI_HILOGE("failed to load algo lib");
106         return RET_NO_SUPPORT;
107     }
108     OnScreenCallingContext onScreenContext {
109         .fullTokenId = context.fullTokenId,
110         .tokenId = context.tokenId,
111         .uid = context.uid,
112         .pid = context.pid,
113     };
114     FI_HILOGI("send control event invoke algo lib");
115     ret = handle_.pAlgorithm->SendControlEvent(onScreenContext, event);
116     if (ret != RET_OK) {
117         FI_HILOGE("failed to send control event, err=%{public}d", ret);
118         return ret;
119     }
120     return RET_OK;
121 }
122 
ConnectAlgoLib()123 int32_t OnScreenServer::ConnectAlgoLib()
124 {
125     return handle_.pAlgorithm == nullptr ? LoadAlgoLib() : RET_OK;
126 }
127 
LoadAlgoLib()128 int32_t OnScreenServer::LoadAlgoLib()
129 {
130     char libRealPath[PATH_MAX] = { 0 };
131     if (realpath(LIB_ON_SCREEN_ALGO_PATH, libRealPath) == nullptr) {
132         FI_HILOGE("get absolute path failed, ret = %{public}d", errno);
133         return RET_ERR;
134     }
135     handle_.handle = dlopen(libRealPath, RTLD_LAZY);
136     if (handle_.handle == nullptr) {
137         FI_HILOGE("dlopen failed, err:%{public}sn", dlerror());
138         return RET_ERR;
139     }
140     handle_.create = reinterpret_cast<IOnScreenAlgorithm*(*)()>(dlsym(handle_.handle, "Create"));
141     handle_.destroy = reinterpret_cast<void(*)(const IOnScreenAlgorithm*)>(dlsym(handle_.handle, "Destroy"));
142     if (handle_.create == nullptr || handle_.destroy == nullptr) {
143         FI_HILOGE("create is null or destoy is null");
144         return RET_ERR;
145     }
146     if (handle_.pAlgorithm == nullptr) {
147         FI_HILOGI("get on screen algo object");
148         handle_.pAlgorithm = handle_.create();
149         if (handle_.pAlgorithm == nullptr) {
150             FI_HILOGE("create on screen algo object failed");
151             return RET_ERR;
152         }
153     }
154     return RET_OK;
155 }
156 
UnloadAlgoLib()157 int32_t OnScreenServer::UnloadAlgoLib()
158 {
159     FI_HILOGE("unload exit");
160     if (handle_.pAlgorithm != nullptr && handle_.destroy != nullptr) {
161         handle_.destroy(handle_.pAlgorithm);
162         handle_.pAlgorithm = nullptr;
163     }
164     handle_.Clear();
165     return RET_OK;
166 }
167 
CheckPermission(const CallingContext & context,const std::string & permission)168 bool OnScreenServer::CheckPermission(const CallingContext &context, const std::string &permission)
169 {
170     auto type = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(context.tokenId);
171     FI_HILOGD("called tokenType is %{public}d", type);
172     if (type == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) {
173         FI_HILOGD("called tokenType is shell, verify succ");
174     }
175     return Security::AccessToken::AccessTokenKit::VerifyAccessToken(context.tokenId, permission) == RET_OK;
176 }
177 
IsSystemCalling(const CallingContext & context)178 bool OnScreenServer::IsSystemCalling(const CallingContext &context)
179 {
180     if (IsSystemServiceCalling(context)) {
181         return true;
182     }
183     return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(context.fullTokenId);
184 }
185 
IsSystemServiceCalling(const CallingContext & context)186 bool OnScreenServer::IsSystemServiceCalling(const CallingContext &context)
187 {
188     auto flag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(context.tokenId);
189     if ((flag == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) ||
190         (flag == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL)) {
191         FI_HILOGI("system service calling, flag:%{public}u", flag);
192         return true;
193     }
194     return false;
195 }
196 } // namespace OnScreen
197 } // namespace DeviceStatus
198 } // namespace Msdp
199 } // namespace OHOS