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 LOG_TAG "UriPermissionManager"
16
17 #include "uri_permission_manager.h"
18
19 #include "log_print.h"
20 #include "preprocess_utils.h"
21 #include "uri_permission_manager_client.h"
22 #include "want.h"
23
24 namespace OHOS {
25 namespace UDMF {
26 constexpr const std::uint32_t GRANT_URI_PERMISSION_MAX_SIZE = 500;
GetInstance()27 UriPermissionManager &UriPermissionManager::GetInstance()
28 {
29 static UriPermissionManager instance;
30 return instance;
31 }
32
GrantUriPermission(const std::vector<Uri> & allUri,uint32_t tokenId,const std::string & queryKey)33 Status UriPermissionManager::GrantUriPermission(
34 const std::vector<Uri> &allUri, uint32_t tokenId, const std::string &queryKey)
35 {
36 std::string bundleName;
37 if (!PreProcessUtils::GetHapBundleNameByToken(tokenId, bundleName)) {
38 ZLOGE("Get BundleName fail, key:%{public}s, tokenId:%{public}u.", queryKey.c_str(), tokenId);
39 return E_ERROR;
40 }
41 int32_t instIndex = -1;
42 if (!PreProcessUtils::GetInstIndex(tokenId, instIndex)) {
43 ZLOGE("Get InstIndex fail, key:%{public}s, tokenId:%{public}u.", queryKey.c_str(), tokenId);
44 return E_ERROR;
45 }
46
47 // GrantUriPermission is time-consuming, need recording the begin,end time in log.
48 ZLOGI("GrantUriPermission begin, url size:%{public}zu, queryKey:%{public}s, instIndex:%{public}d.",
49 allUri.size(), queryKey.c_str(), instIndex);
50 for (size_t index = 0; index < allUri.size(); index += GRANT_URI_PERMISSION_MAX_SIZE) {
51 std::vector<Uri> uriLst(
52 allUri.begin() + index, allUri.begin() + std::min(index + GRANT_URI_PERMISSION_MAX_SIZE, allUri.size()));
53 auto status = AAFwk::UriPermissionManagerClient::GetInstance().GrantUriPermissionPrivileged(
54 uriLst, AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION, bundleName, instIndex);
55 if (status != ERR_OK) {
56 ZLOGE("GrantUriPermission failed, status:%{public}d, queryKey:%{public}s, instIndex:%{public}d.",
57 status, queryKey.c_str(), instIndex);
58 return E_NO_PERMISSION;
59 }
60 auto time = std::chrono::steady_clock::now() + std::chrono::minutes(INTERVAL);
61 std::for_each(uriLst.begin(), uriLst.end(), [&](const Uri &uri) {
62 auto times = std::make_pair(uri.ToString(), tokenId);
63 uriTimeout_.Insert(times, time);
64 });
65 }
66 ZLOGI("GrantUriPermission end, url size:%{public}zu, queryKey:%{public}s.", allUri.size(), queryKey.c_str());
67
68 std::unique_lock<std::mutex> lock(taskMutex_);
69 if (taskId_ == ExecutorPool::INVALID_TASK_ID && executorPool_ != nullptr) {
70 taskId_ = executorPool_->Schedule(
71 std::chrono::minutes(INTERVAL), std::bind(&UriPermissionManager::RevokeUriPermission, this));
72 }
73 return E_OK;
74 }
75
RevokeUriPermission()76 void UriPermissionManager::RevokeUriPermission()
77 {
78 auto current = std::chrono::steady_clock::now();
79 uriTimeout_.EraseIf([&](const auto &key, const Time &time) {
80 if (time > current) {
81 return false;
82 }
83 Uri uri(key.first);
84 uint32_t tokenId = key.second;
85 std::string bundleName;
86 if (!PreProcessUtils::GetHapBundleNameByToken(tokenId, bundleName)) {
87 ZLOGE("Get BundleName fail, tokenId:%{public}u.", tokenId);
88 return true;
89 }
90 int32_t instIndex = -1;
91 if (!PreProcessUtils::GetInstIndex(tokenId, instIndex)) {
92 ZLOGE("Get InstIndex fail, tokenId:%{public}u.", tokenId);
93 return true;
94 }
95 int status = AAFwk::UriPermissionManagerClient::GetInstance().RevokeUriPermissionManually(
96 uri, bundleName, instIndex);
97 if (status != E_OK) {
98 ZLOGE("RevokeUriPermission error, permissionCode:%{public}d, bundleName:%{public}s, instIndex:%{public}d",
99 status, bundleName.c_str(), instIndex);
100 }
101 return true;
102 });
103
104 std::unique_lock<std::mutex> lock(taskMutex_);
105 if (!uriTimeout_.Empty() && executorPool_ != nullptr) {
106 ZLOGD("RevokeUriPermission, uriTimeout size:%{public}zu", uriTimeout_.Size());
107 taskId_ = executorPool_->Schedule(
108 std::chrono::minutes(INTERVAL), std::bind(&UriPermissionManager::RevokeUriPermission, this));
109 } else {
110 taskId_ = ExecutorPool::INVALID_TASK_ID;
111 }
112 }
113
SetThreadPool(std::shared_ptr<ExecutorPool> executors)114 void UriPermissionManager::SetThreadPool(std::shared_ptr<ExecutorPool> executors)
115 {
116 executorPool_ = executors;
117 }
118 } // namespace UDMF
119 } // namespace OHOS
120