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 #include "el5_filekey_manager_client.h"
17
18 #include "el5_filekey_manager_log.h"
19 #include "el5_filekey_manager_proxy.h"
20 #include "iservice_registry.h"
21 #include "refbase.h"
22 #include "system_ability_definition.h"
23 #include "sys_binder.h"
24
25 namespace OHOS {
26 namespace Security {
27 namespace AccessToken {
28 namespace {
29 constexpr int32_t LOAD_SA_TIMEOUT_SECOND = 4;
30 constexpr int32_t LOAD_SA_RETRY_TIMES = 5;
31 static const int32_t SA_REQUEST_RETRY_TIMES = 1;
32 static const int32_t SENDREQ_FAIL_ERR = 32;
33 static const std::vector<int32_t> RETRY_CODE_LIST = { BR_DEAD_REPLY, BR_FAILED_REPLY, SENDREQ_FAIL_ERR };
34 }
El5FilekeyManagerClient()35 El5FilekeyManagerClient::El5FilekeyManagerClient() {}
36
~El5FilekeyManagerClient()37 El5FilekeyManagerClient::~El5FilekeyManagerClient() {}
38
GetInstance()39 El5FilekeyManagerClient &El5FilekeyManagerClient::GetInstance()
40 {
41 static El5FilekeyManagerClient instance;
42 return instance;
43 }
44
AcquireAccess(DataLockType type)45 int32_t El5FilekeyManagerClient::AcquireAccess(DataLockType type)
46 {
47 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
48 return proxy->AcquireAccess(type);
49 };
50 return CallProxyWithRetry(func, __FUNCTION__);
51 }
52
ReleaseAccess(DataLockType type)53 int32_t El5FilekeyManagerClient::ReleaseAccess(DataLockType type)
54 {
55 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
56 return proxy->ReleaseAccess(type);
57 };
58 return CallProxyWithRetry(func, __FUNCTION__);
59 }
60
GenerateAppKey(uint32_t uid,const std::string & bundleName,std::string & keyId)61 int32_t El5FilekeyManagerClient::GenerateAppKey(uint32_t uid, const std::string &bundleName, std::string &keyId)
62 {
63 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
64 return proxy->GenerateAppKey(uid, bundleName, keyId);
65 };
66 return CallProxyWithRetry(func, __FUNCTION__);
67 }
68
DeleteAppKey(const std::string & bundleName,int32_t userId)69 int32_t El5FilekeyManagerClient::DeleteAppKey(const std::string &bundleName, int32_t userId)
70 {
71 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
72 return proxy->DeleteAppKey(bundleName, userId);
73 };
74 return CallProxyWithRetry(func, __FUNCTION__);
75 }
76
GetUserAppKey(int32_t userId,bool getAllFlag,std::vector<std::pair<int32_t,std::string>> & keyInfos)77 int32_t El5FilekeyManagerClient::GetUserAppKey(int32_t userId, bool getAllFlag,
78 std::vector<std::pair<int32_t, std::string>> &keyInfos)
79 {
80 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
81 return proxy->GetUserAppKey(userId, getAllFlag, keyInfos);
82 };
83 return CallProxyWithRetry(func, __FUNCTION__);
84 }
85
ChangeUserAppkeysLoadInfo(int32_t userId,std::vector<std::pair<std::string,bool>> & loadInfos)86 int32_t El5FilekeyManagerClient::ChangeUserAppkeysLoadInfo(int32_t userId,
87 std::vector<std::pair<std::string, bool>> &loadInfos)
88 {
89 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
90 return proxy->ChangeUserAppkeysLoadInfo(userId, loadInfos);
91 };
92 return CallProxyWithRetry(func, __FUNCTION__);
93 }
94
SetFilePathPolicy()95 int32_t El5FilekeyManagerClient::SetFilePathPolicy()
96 {
97 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
98 return proxy->SetFilePathPolicy();
99 };
100 return CallProxyWithRetry(func, __FUNCTION__);
101 }
102
RegisterCallback(const sptr<El5FilekeyCallbackInterface> & callback)103 int32_t El5FilekeyManagerClient::RegisterCallback(const sptr<El5FilekeyCallbackInterface> &callback)
104 {
105 std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> func = [&](sptr<El5FilekeyManagerInterface> &proxy) {
106 return proxy->RegisterCallback(callback);
107 };
108 return CallProxyWithRetry(func, __FUNCTION__);
109 }
110
GetProxy()111 sptr<El5FilekeyManagerInterface> El5FilekeyManagerClient::GetProxy()
112 {
113 std::unique_lock<std::mutex> lock(proxyMutex_);
114 auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
115 if (systemAbilityManager == nullptr) {
116 LOG_ERROR("Get system ability manager failed.");
117 return nullptr;
118 }
119
120 auto el5FilekeyService = systemAbilityManager->CheckSystemAbility(EL5_FILEKEY_MANAGER_SERVICE_ID);
121 if (el5FilekeyService != nullptr) {
122 LOG_INFO("get el5 filekey manager proxy success");
123 return iface_cast<El5FilekeyManagerInterface>(el5FilekeyService);
124 }
125
126 for (int i = 0; i <= LOAD_SA_RETRY_TIMES; i++) {
127 auto el5FilekeyService =
128 systemAbilityManager->LoadSystemAbility(EL5_FILEKEY_MANAGER_SERVICE_ID, LOAD_SA_TIMEOUT_SECOND);
129 if (el5FilekeyService != nullptr) {
130 LOG_INFO("load el5 filekey manager success");
131 return iface_cast<El5FilekeyManagerInterface>(el5FilekeyService);
132 }
133 LOG_INFO("load el5 filekey manager failed, retry count:%{public}d", i);
134 }
135 LOG_ERROR("get el5 filekey manager proxy failed");
136 return nullptr;
137 }
138
CallProxyWithRetry(const std::function<int32_t (sptr<El5FilekeyManagerInterface> &)> & func,const char * funcName)139 int32_t El5FilekeyManagerClient::CallProxyWithRetry(
140 const std::function<int32_t(sptr<El5FilekeyManagerInterface> &)> &func, const char *funcName)
141 {
142 LOG_INFO("call proxy with retry function:%s", funcName);
143 auto proxy = GetProxy();
144 if (proxy != nullptr) {
145 int32_t ret = func(proxy);
146 if (!IsRequestNeedRetry(ret)) {
147 return ret;
148 }
149 LOG_WARN("First try cal %{public}s failed ret:%{public}d. Begin retry", funcName, ret);
150 } else {
151 LOG_WARN("First try call %{public}s failed, proxy is NULL. Begin retry.", funcName);
152 }
153
154 for (int32_t i = 0; i < SA_REQUEST_RETRY_TIMES; i++) {
155 proxy = GetProxy();
156 if (proxy == nullptr) {
157 LOG_WARN("Get proxy %{public}s failed, retry time = %{public}d.", funcName, i);
158 continue;
159 }
160 int32_t ret = func(proxy);
161 if (!IsRequestNeedRetry(ret)) {
162 return ret;
163 }
164 LOG_WARN("Call %{public}s failed, retry time = %{public}d, result = %{public}d", funcName, i, ret);
165 }
166 LOG_ERROR("Retry call service %{public}s error, tried %{public}d times.", funcName, SA_REQUEST_RETRY_TIMES);
167 return EFM_ERR_REMOTE_CONNECTION;
168 }
169
IsRequestNeedRetry(int32_t ret)170 bool El5FilekeyManagerClient::IsRequestNeedRetry(int32_t ret)
171 {
172 auto it = std::find(RETRY_CODE_LIST.begin(), RETRY_CODE_LIST.end(), ret);
173 return it != RETRY_CODE_LIST.end();
174 }
175 } // namespace AccessToken
176 } // namespace Security
177 } // namespace OHOS
178