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 #ifndef OHOS_ABILITY_ACCESS_AT_MANAGER_IMPL_H
17 #define OHOS_ABILITY_ACCESS_AT_MANAGER_IMPL_H
18 
19 #include <cstdint>
20 #include <cstdio>
21 #include <cstring>
22 #include <pthread.h>
23 #include <unistd.h>
24 #include <thread>
25 
26 #include "accesstoken_kit.h"
27 #include "cj_common_ffi.h"
28 #include "cj_lambda.h"
29 #include "ffi_remote_data.h"
30 #include "permission_grant_info.h"
31 #include "token_callback_stub.h"
32 #include "ui_content.h"
33 #include "ui_extension_context.h"
34 
35 struct CPermissionRequestResult {
36     CArrString permissions;
37     CArrI32 authResults;
38 };
39 
40 struct RetDataCPermissionRequestResult {
41     int32_t code;
42     CPermissionRequestResult data;
43 };
44 
45 namespace OHOS {
46 namespace CJSystemapi {
47 
48 using namespace OHOS::Security::AccessToken;
49 
50 const int AT_PERM_OPERA_FAIL = -1;
51 const int AT_PERM_OPERA_SUCC = 0;
52 const int32_t PARAM_DEFAULT_VALUE = -1;
53 
54 struct PermissionStatusCache {
55     int32_t status;
56     std::string paramValue;
57 };
58 
59 struct PermissionParamCache {
60     long long sysCommitIdCache = PARAM_DEFAULT_VALUE;
61     int32_t commitIdCache = PARAM_DEFAULT_VALUE;
62     int32_t handle = PARAM_DEFAULT_VALUE;
63     std::string sysParamCache;
64 };
65 
66 struct CPermStateChangeInfo {
67     int32_t permStateChangeType;
68     AccessTokenID tokenID;
69     char* permissionName;
70 };
71 
72 struct RequestAsyncContext {
73     AccessTokenID tokenId = 0;
74     bool needDynamicRequest = true;
75     int32_t result = AT_PERM_OPERA_SUCC;
76     std::vector<std::string> permissionList;
77     std::vector<int32_t> permissionsState;
78     PermissionGrantInfo info;
79     std::shared_ptr<AbilityRuntime::AbilityContext> abilityContext;
80     std::shared_ptr<AbilityRuntime::UIExtensionContext> uiExtensionContext;
81     bool uiAbilityFlag = false;
82     std::function<void(RetDataCPermissionRequestResult)> callbackRef =  nullptr;
83 };
84 
85 class UIExtensionCallback {
86 public:
87     explicit UIExtensionCallback(const std::shared_ptr<RequestAsyncContext>& reqContext);
88     ~UIExtensionCallback();
89     void SetSessionId(int32_t sessionId);
90     void OnRelease(int32_t releaseCode);
91     void OnResult(int32_t resultCode, const OHOS::AAFwk::Want& result);
92     void OnReceive(const OHOS::AAFwk::WantParams& request);
93     void OnError(int32_t code, const std::string& name, const std::string& message);
94     void OnRemoteReady(const std::shared_ptr<OHOS::Ace::ModalUIExtensionProxy>& uiProxy);
95     void OnDestroy();
96     void ReleaseOrErrorHandle(int32_t code);
97 
98 private:
99     int32_t sessionId_ = 0;
100     std::shared_ptr<RequestAsyncContext> reqContext_ = nullptr;
101 };
102 
103 class AuthorizationResult : public Security::AccessToken::TokenCallbackStub {
104 public:
AuthorizationResult(std::function<void (RetDataCPermissionRequestResult)> callbackRef)105     explicit AuthorizationResult(std::function<void(RetDataCPermissionRequestResult)> callbackRef)
106         : callbackRef_(callbackRef) {}
107     ~AuthorizationResult() override = default;
108     void GrantResultsCallback(const std::vector<std::string>& permissions,
109         const std::vector<int>& grantResults) override;
110 
111 private:
112     std::function<void(RetDataCPermissionRequestResult)> callbackRef_;
113 };
114 
115 class RegisterPermStateChangeScopePtr : public std::enable_shared_from_this<RegisterPermStateChangeScopePtr>,
116     public PermStateChangeCallbackCustomize {
117 public:
118     explicit RegisterPermStateChangeScopePtr(const PermStateChangeScope& subscribeInfo);
119     ~RegisterPermStateChangeScopePtr() override;
120     void PermStateChangeCallback(PermStateChangeInfo& result) override;
121     void SetCallbackRef(const std::function<void(CPermStateChangeInfo)>& ref);
122     void SetValid(bool valid);
123 
124 private:
125     std::function<void(CPermStateChangeInfo)> ref_;
126     bool valid_ = true;
127     std::mutex validMutex_;
128 };
129 
130 struct PermStateChangeContext {
131     virtual ~PermStateChangeContext();
132     int64_t callbackRef =  0;
133     int32_t errCode = 0;
134     std::string permStateChangeType;
135     AccessTokenKit* accessTokenKit = nullptr;
136     std::thread::id threadId;
137     std::shared_ptr<RegisterPermStateChangeScopePtr> subscriber = nullptr;
138 };
139 
140 typedef PermStateChangeContext RegisterPermStateChangeInfo;
141 
142 struct UnregisterPermStateChangeInfo : public PermStateChangeContext {
143     PermStateChangeScope scopeInfo;
144 };
145 
146 typedef enum {
147     CJ_OK = 0,
148     CJ_ERROR_PERMISSION_DENIED = 201,
149     CJ_ERROR_NOT_SYSTEM_APP = 202,
150     CJ_ERROR_PARAM_ILLEGAL = 401,
151     CJ_ERROR_SYSTEM_CAPABILITY_NOT_SUPPORT = 801,
152     CJ_ERROR_PARAM_INVALID = 12100001,
153     CJ_ERROR_TOKENID_NOT_EXIST,
154     CJ_ERROR_PERMISSION_NOT_EXIST,
155     CJ_ERROR_NOT_USE_TOGETHER,
156     CJ_ERROR_REGISTERS_EXCEED_LIMITATION,
157     CJ_ERROR_PERMISSION_OPERATION_NOT_ALLOWED,
158     CJ_ERROR_SERVICE_NOT_RUNNING,
159     CJ_ERROR_OUT_OF_MEMORY,
160     CJ_ERROR_INNER,
161 } CjErrorCode;
162 
163 class AtManagerImpl {
164 public:
165     static int32_t VerifyAccessTokenSync(unsigned int tokenID, const char* cPermissionName);
166     static int32_t GrantUserGrantedPermission(unsigned int tokenID, const char* cPermissionName,
167     unsigned int permissionFlags);
168     static int32_t RevokeUserGrantedPermission(unsigned int tokenID, const char* cPermissionName,
169     unsigned int permissionFlags);
170     static int32_t RegisterPermStateChangeCallback(
171         const char* cType,
172         CArrUI32 cTokenIDList,
173         CArrString cPermissionList,
174         int64_t callbackRef);
175     static int32_t UnregisterPermStateChangeCallback(
176         const char* cType, CArrUI32 cTokenIDList,
177         CArrString cPermissionList,
178         int64_t callbackRef);
179     static void RequestPermissionsFromUser(OHOS::AbilityRuntime::Context* context, CArrString cPermissionList,
180         const std::function<void(RetDataCPermissionRequestResult)>& callbackRef);
181 private:
182     static std::string GetPermParamValue();
183     static int32_t FillPermStateChangeInfo(
184         const std::string& type,
185         CArrUI32 cTokenIDList,
186         CArrString cPermissionList,
187         int64_t callback,
188         RegisterPermStateChangeInfo& registerPermStateChangeInfo);
189     static int32_t FillUnregisterPermStateChangeInfo(
190         const std::string& type,
191         CArrUI32 cTokenIDList,
192         CArrString cPermissionList,
193         int64_t callback,
194         UnregisterPermStateChangeInfo& unregisterPermStateChangeInfo);
195     static bool IsExistRegister(const RegisterPermStateChangeInfo* registerPermStateChangeInfo);
196     static bool IsDynamicRequest(const std::vector<std::string>& permissions,
197         std::vector<int32_t>& permissionsState, PermissionGrantInfo& info);
198     static bool FindAndGetSubscriberInVector(UnregisterPermStateChangeInfo* unregisterPermStateChangeInfo,
199         std::vector<RegisterPermStateChangeInfo*>& batchPermStateChangeRegisters);
200     static void DeleteRegisterFromVector(const PermStateChangeScope& scopeInfo, int64_t subscriberRef);
201     static bool ParseRequestPermissionFromUser(OHOS::AbilityRuntime::Context* context, CArrString cPermissionList,
202         const std::function<void(RetDataCPermissionRequestResult)>& callbackRef,
203         const std::shared_ptr<RequestAsyncContext>& asyncContext);
204 };
205 }
206 }
207 
208 #endif