• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "uri_permission_manager_client.h"
17 
18 #include "ability_manager_errors.h"
19 #include "hilog_wrapper.h"
20 #include "if_system_ability_manager.h"
21 #include "iservice_registry.h"
22 #include "system_ability_definition.h"
23 #include "uri_permission_load_callback.h"
24 
25 namespace OHOS {
26 namespace AAFwk {
27 namespace {
28 const int LOAD_SA_TIMEOUT_MS = 4 * 1000;
29 } // namespace
GetInstance()30 UriPermissionManagerClient& UriPermissionManagerClient::GetInstance()
31 {
32     static UriPermissionManagerClient instance;
33     return instance;
34 }
35 
GrantUriPermission(const Uri & uri,unsigned int flag,const std::string targetBundleName,int autoremove,int32_t appIndex)36 int UriPermissionManagerClient::GrantUriPermission(const Uri &uri, unsigned int flag,
37     const std::string targetBundleName, int autoremove, int32_t appIndex)
38 {
39     HILOG_DEBUG("targetBundleName :%{public}s", targetBundleName.c_str());
40     auto uriPermMgr = ConnectUriPermService();
41     if (uriPermMgr) {
42         return uriPermMgr->GrantUriPermission(uri, flag, targetBundleName, autoremove, appIndex);
43     }
44 
45     return INNER_ERR;
46 }
47 
RevokeUriPermission(const Security::AccessToken::AccessTokenID tokenId)48 void UriPermissionManagerClient::RevokeUriPermission(const Security::AccessToken::AccessTokenID tokenId)
49 {
50     HILOG_DEBUG("UriPermissionManagerClient::RevokeUriPermission is called.");
51     auto uriPermMgr = ConnectUriPermService();
52     if (uriPermMgr) {
53         return uriPermMgr->RevokeUriPermission(tokenId);
54     }
55 }
56 
RevokeAllUriPermissions(const Security::AccessToken::AccessTokenID tokenId)57 int UriPermissionManagerClient::RevokeAllUriPermissions(const Security::AccessToken::AccessTokenID tokenId)
58 {
59     HILOG_DEBUG("UriPermissionManagerClient::RevokeAllUriPermissions is called.");
60     auto uriPermMgr = ConnectUriPermService();
61     if (uriPermMgr) {
62         return uriPermMgr->RevokeAllUriPermissions(tokenId);
63     }
64     return INNER_ERR;
65 }
66 
RevokeUriPermissionManually(const Uri & uri,const std::string bundleName)67 int UriPermissionManagerClient::RevokeUriPermissionManually(const Uri &uri, const std::string bundleName)
68 {
69     HILOG_DEBUG("UriPermissionManagerClient::RevokeUriPermissionManually is called.");
70     auto uriPermMgr = ConnectUriPermService();
71     if (uriPermMgr) {
72         return uriPermMgr->RevokeUriPermissionManually(uri, bundleName);
73     }
74     return INNER_ERR;
75 }
76 
CheckPersistableUriPermissionProxy(const Uri & uri,uint32_t flag,uint32_t tokenId)77 bool UriPermissionManagerClient::CheckPersistableUriPermissionProxy(const Uri& uri, uint32_t flag, uint32_t tokenId)
78 {
79     auto uriPermMgr = ConnectUriPermService();
80     if (uriPermMgr) {
81         return uriPermMgr->CheckPersistableUriPermissionProxy(uri, flag, tokenId);
82     }
83     return false;
84 }
85 
VerifyUriPermission(const Uri & uri,uint32_t flag,uint32_t tokenId)86 bool UriPermissionManagerClient::VerifyUriPermission(const Uri& uri, uint32_t flag, uint32_t tokenId)
87 {
88     auto uriPermMgr = ConnectUriPermService();
89     if (uriPermMgr) {
90         return uriPermMgr->VerifyUriPermission(uri, flag, tokenId);
91     }
92     return false;
93 }
94 
ConnectUriPermService()95 sptr<IUriPermissionManager> UriPermissionManagerClient::ConnectUriPermService()
96 {
97     HILOG_DEBUG("UriPermissionManagerClient::ConnectUriPermService is called.");
98     auto uriPermMgr = GetUriPermMgr();
99     if (uriPermMgr == nullptr) {
100         if (!LoadUriPermService()) {
101             HILOG_ERROR("Load uri permission manager service failed.");
102             return nullptr;
103         }
104         uriPermMgr = GetUriPermMgr();
105         if (uriPermMgr == nullptr || uriPermMgr->AsObject() == nullptr) {
106             HILOG_ERROR("Failed to get uri permission manager.");
107             return nullptr;
108         }
109         const auto& onClearProxyCallback = [] {
110             UriPermissionManagerClient::GetInstance().ClearProxy();
111         };
112         sptr<UpmsDeathRecipient> recipient(new UpmsDeathRecipient(onClearProxyCallback));
113         uriPermMgr->AsObject()->AddDeathRecipient(recipient);
114     }
115     HILOG_DEBUG("End UriPermissionManagerClient::ConnectUriPermService.");
116     return uriPermMgr;
117 }
118 
LoadUriPermService()119 bool UriPermissionManagerClient::LoadUriPermService()
120 {
121     HILOG_DEBUG("UriPermissionManagerClient::LoadUriPermService is called.");
122     auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
123     if (systemAbilityMgr == nullptr) {
124         HILOG_ERROR("Failed to get SystemAbilityManager.");
125         return false;
126     }
127 
128     sptr<UriPermissionLoadCallback> loadCallback = new (std::nothrow) UriPermissionLoadCallback();
129     if (loadCallback == nullptr) {
130         HILOG_ERROR("Create load callback failed.");
131         return false;
132     }
133 
134     auto ret = systemAbilityMgr->LoadSystemAbility(URI_PERMISSION_MGR_SERVICE_ID, loadCallback);
135     if (ret != 0) {
136         HILOG_ERROR("Load system ability %{public}d failed with %{public}d.", URI_PERMISSION_MGR_SERVICE_ID, ret);
137         return false;
138     }
139 
140     {
141         std::unique_lock<std::mutex> lock(saLoadMutex_);
142         auto waitStatus = loadSaVariable_.wait_for(lock, std::chrono::milliseconds(LOAD_SA_TIMEOUT_MS),
143             [this]() {
144                 return saLoadFinished_;
145             });
146         if (!waitStatus) {
147             HILOG_ERROR("Wait for load sa timeout.");
148             return false;
149         }
150     }
151     return true;
152 }
153 
GetUriPermMgr()154 sptr<IUriPermissionManager> UriPermissionManagerClient::GetUriPermMgr()
155 {
156     std::lock_guard<std::mutex> lock(mutex_);
157     return uriPermMgr_;
158 }
159 
SetUriPermMgr(const sptr<IRemoteObject> & remoteObject)160 void UriPermissionManagerClient::SetUriPermMgr(const sptr<IRemoteObject> &remoteObject)
161 {
162     HILOG_DEBUG("UriPermissionManagerClient::SetUriPermMgr is called.");
163     std::lock_guard<std::mutex> lock(mutex_);
164     uriPermMgr_ = iface_cast<IUriPermissionManager>(remoteObject);
165 }
166 
OnLoadSystemAbilitySuccess(const sptr<IRemoteObject> & remoteObject)167 void UriPermissionManagerClient::OnLoadSystemAbilitySuccess(const sptr<IRemoteObject> &remoteObject)
168 {
169     HILOG_DEBUG("UriPermissionManagerClient::OnLoadSystemAbilitySuccess is called.");
170     SetUriPermMgr(remoteObject);
171     std::unique_lock<std::mutex> lock(saLoadMutex_);
172     saLoadFinished_ = true;
173     loadSaVariable_.notify_one();
174 }
175 
OnLoadSystemAbilityFail()176 void UriPermissionManagerClient::OnLoadSystemAbilityFail()
177 {
178     HILOG_DEBUG("UriPermissionManagerClient::OnLoadSystemAbilityFail is called.");
179     SetUriPermMgr(nullptr);
180     std::unique_lock<std::mutex> lock(saLoadMutex_);
181     saLoadFinished_ = true;
182     loadSaVariable_.notify_one();
183 }
184 
ClearProxy()185 void UriPermissionManagerClient::ClearProxy()
186 {
187     HILOG_DEBUG("UriPermissionManagerClient::ClearProxy is called.");
188     std::lock_guard<std::mutex> lock(mutex_);
189     uriPermMgr_ = nullptr;
190 }
191 
OnRemoteDied(const wptr<IRemoteObject> & remote)192 void UriPermissionManagerClient::UpmsDeathRecipient::OnRemoteDied([[maybe_unused]] const wptr<IRemoteObject>& remote)
193 {
194     HILOG_ERROR("upms stub died.");
195     proxy_();
196 }
197 }  // namespace AAFwk
198 }  // namespace OHOS
199