1 /*
2 * Copyright (c) 2022 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 "permission_record_manager.h"
17
18 #include <algorithm>
19 #include <cinttypes>
20 #include <numeric>
21
22 #include "ability_manager_privacy_client.h"
23 #include "accesstoken_kit.h"
24 #include "accesstoken_log.h"
25 #include "active_status_callback_manager.h"
26 #include "app_manager_privacy_client.h"
27 #include "audio_manager_privacy_client.h"
28 #include "camera_manager_privacy_client.h"
29 #include "constant.h"
30 #include "constant_common.h"
31 #include "data_translator.h"
32 #include "i_state_change_callback.h"
33 #include "iservice_registry.h"
34 #include "permission_record_repository.h"
35 #include "permission_used_record_cache.h"
36 #include "privacy_error.h"
37 #include "privacy_field_const.h"
38 #include "state_change_callback_proxy.h"
39 #include "system_ability_definition.h"
40 #include "time_util.h"
41 #include "want.h"
42 #include "window_manager_privacy_client.h"
43
44 namespace OHOS {
45 namespace Security {
46 namespace AccessToken {
47 namespace {
48 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
49 LOG_CORE, SECURITY_DOMAIN_PRIVACY, "PermissionRecordManager"
50 };
51 static const std::string DEFAULT_DEVICEID = "0";
52 static const std::string FIELD_COUNT_NUMBER = "count";
53 constexpr const char* CAMERA_PERMISSION_NAME = "ohos.permission.CAMERA";
54 constexpr const char* MICROPHONE_PERMISSION_NAME = "ohos.permission.MICROPHONE";
55 static const std::string PERMISSION_MANAGER_BUNDLE_NAME = "com.ohos.permissionmanager";
56 static const std::string PERMISSION_MANAGER_DIALOG_ABILITY = "com.ohos.permissionmanager.GlobalExtAbility";
57 static const std::string RESOURCE_KEY = "ohos.sensitive.resource";
58 }
GetInstance()59 PermissionRecordManager& PermissionRecordManager::GetInstance()
60 {
61 static PermissionRecordManager instance;
62 return instance;
63 }
64
PermissionRecordManager()65 PermissionRecordManager::PermissionRecordManager() : deleteTaskWorker_("DeleteRecord"), hasInited_(false) {}
66
~PermissionRecordManager()67 PermissionRecordManager::~PermissionRecordManager()
68 {
69 if (!hasInited_) {
70 return;
71 }
72 deleteTaskWorker_.Stop();
73 hasInited_ = false;
74 Unregister();
75 }
76
AddRecord(const PermissionRecord & record)77 void PermissionRecordManager::AddRecord(const PermissionRecord& record)
78 {
79 Utils::UniqueWriteGuard<Utils::RWLock> lk(this->rwLock_);
80 ACCESSTOKEN_LOG_INFO(LABEL,
81 "add record: tokenId %{public}d, opCode %{public}d, status: %{public}d, timestamp: %{public}" PRId64,
82 record.tokenId, record.opCode, record.status, record.timestamp);
83 PermissionUsedRecordCache::GetInstance().AddRecordToBuffer(record);
84 }
85
GetPermissionRecord(AccessTokenID tokenId,const std::string & permissionName,int32_t successCount,int32_t failCount,PermissionRecord & record)86 int32_t PermissionRecordManager::GetPermissionRecord(AccessTokenID tokenId, const std::string& permissionName,
87 int32_t successCount, int32_t failCount, PermissionRecord& record)
88 {
89 HapTokenInfo tokenInfo;
90 if (AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo) != Constant::SUCCESS) {
91 ACCESSTOKEN_LOG_ERROR(LABEL, "invalid tokenId(%{public}d)", tokenId);
92 return PrivacyError::ERR_TOKENID_NOT_EXIST;
93 }
94 int32_t opCode;
95 if (!Constant::TransferPermissionToOpcode(permissionName, opCode)) {
96 ACCESSTOKEN_LOG_ERROR(LABEL, "invalid (%{public}s)", permissionName.c_str());
97 return PrivacyError::ERR_PERMISSION_NOT_EXIST;
98 }
99 if (successCount == 0 && failCount == 0) {
100 record.status = PERM_INACTIVE;
101 } else {
102 record.status = GetAppStatus(tokenId);
103 }
104 record.tokenId = tokenId;
105 record.accessCount = successCount;
106 record.rejectCount = failCount;
107 record.opCode = opCode;
108 record.timestamp = TimeUtil::GetCurrentTimestamp();
109 record.accessDuration = 0;
110 ACCESSTOKEN_LOG_DEBUG(LABEL, "record status: %{public}d", record.status);
111 return Constant::SUCCESS;
112 }
113
AddPermissionUsedRecord(AccessTokenID tokenId,const std::string & permissionName,int32_t successCount,int32_t failCount)114 int32_t PermissionRecordManager::AddPermissionUsedRecord(AccessTokenID tokenId, const std::string& permissionName,
115 int32_t successCount, int32_t failCount)
116 {
117 ExecuteDeletePermissionRecordTask();
118
119 PermissionRecord record;
120 int32_t result = GetPermissionRecord(tokenId, permissionName, successCount, failCount, record);
121 if (result != Constant::SUCCESS) {
122 return result;
123 }
124
125 if (record.status == PERM_INACTIVE) {
126 return PrivacyError::ERR_PARAM_INVALID;
127 }
128
129 AddRecord(record);
130 return Constant::SUCCESS;
131 }
132
RemovePermissionUsedRecords(AccessTokenID tokenId,const std::string & deviceID)133 void PermissionRecordManager::RemovePermissionUsedRecords(AccessTokenID tokenId, const std::string& deviceID)
134 {
135 // only support remove by tokenId(local)
136 std::string device = GetDeviceId(tokenId);
137 if (device.empty()) {
138 ACCESSTOKEN_LOG_ERROR(LABEL, "invalid tokenId = %{public}d", tokenId);
139 return;
140 }
141
142 if (!deviceID.empty() && device != deviceID) {
143 ACCESSTOKEN_LOG_ERROR(LABEL, "deviceID mismatch");
144 return;
145 }
146
147 Utils::UniqueWriteGuard<Utils::RWLock> lk(this->rwLock_);
148 PermissionUsedRecordCache::GetInstance().RemoveRecords(tokenId); // remove from cache and database
149 }
150
GetPermissionUsedRecords(const PermissionUsedRequest & request,PermissionUsedResult & result)151 int32_t PermissionRecordManager::GetPermissionUsedRecords(
152 const PermissionUsedRequest& request, PermissionUsedResult& result)
153 {
154 ExecuteDeletePermissionRecordTask();
155
156 if (!request.isRemote && !GetRecordsFromLocalDB(request, result)) {
157 ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to GetRecordsFromLocalDB");
158 return PrivacyError::ERR_PARAM_INVALID;
159 }
160 return Constant::SUCCESS;
161 }
162
GetPermissionUsedRecordsAsync(const PermissionUsedRequest & request,const sptr<OnPermissionUsedRecordCallback> & callback)163 int32_t PermissionRecordManager::GetPermissionUsedRecordsAsync(
164 const PermissionUsedRequest& request, const sptr<OnPermissionUsedRecordCallback>& callback)
165 {
166 auto task = [request, callback]() {
167 ACCESSTOKEN_LOG_INFO(LABEL, "GetPermissionUsedRecordsAsync task called");
168 PermissionUsedResult result;
169 int32_t retCode = PermissionRecordManager::GetInstance().GetPermissionUsedRecords(request, result);
170 callback->OnQueried(retCode, result);
171 };
172 std::thread recordThread(task);
173 recordThread.detach();
174 return Constant::SUCCESS;
175 }
176
GetLocalRecordTokenIdList(std::set<AccessTokenID> & tokenIdList)177 void PermissionRecordManager::GetLocalRecordTokenIdList(std::set<AccessTokenID>& tokenIdList)
178 {
179 std::vector<GenericValues> results;
180 {
181 Utils::UniqueReadGuard<Utils::RWLock> lk(this->rwLock_);
182 // find tokenId from cache
183 PermissionUsedRecordCache::GetInstance().FindTokenIdList(tokenIdList);
184 // find tokenId from database
185 PermissionRecordRepository::GetInstance().GetAllRecordValuesByKey(PrivacyFiledConst::FIELD_TOKEN_ID, results);
186 }
187 for (const auto& res : results) {
188 tokenIdList.emplace(res.GetInt(PrivacyFiledConst::FIELD_TOKEN_ID));
189 }
190 }
191
GetRecordsFromLocalDB(const PermissionUsedRequest & request,PermissionUsedResult & result)192 bool PermissionRecordManager::GetRecordsFromLocalDB(const PermissionUsedRequest& request, PermissionUsedResult& result)
193 {
194 GenericValues andConditionValues;
195 GenericValues orConditionValues;
196 if (DataTranslator::TranslationIntoGenericValues(request, andConditionValues)
197 != Constant::SUCCESS) {
198 ACCESSTOKEN_LOG_ERROR(LABEL, "query time or flag is invalid");
199 return false;
200 }
201
202 std::set<AccessTokenID> tokenIdList;
203 if (request.tokenId == 0) {
204 GetLocalRecordTokenIdList(tokenIdList);
205 } else {
206 tokenIdList.emplace(request.tokenId);
207 }
208 ACCESSTOKEN_LOG_DEBUG(LABEL, "GetLocalRecordTokenIdList.size = %{public}zu", tokenIdList.size());
209 Utils::UniqueReadGuard<Utils::RWLock> lk(this->rwLock_);
210 for (const auto& tokenId : tokenIdList) {
211 andConditionValues.Put(PrivacyFiledConst::FIELD_TOKEN_ID, static_cast<int32_t>(tokenId));
212 std::vector<GenericValues> findRecordsValues;
213 PermissionUsedRecordCache::GetInstance().GetRecords(request.permissionList,
214 andConditionValues, findRecordsValues); // find records from cache and database
215 andConditionValues.Remove(PrivacyFiledConst::FIELD_TOKEN_ID);
216 BundleUsedRecord bundleRecord;
217 if (!CreateBundleUsedRecord(tokenId, bundleRecord)) {
218 continue;
219 }
220 if (!findRecordsValues.empty()) {
221 GetRecords(request.flag, findRecordsValues, bundleRecord, result);
222 }
223 if (!bundleRecord.permissionRecords.empty()) {
224 result.bundleRecords.emplace_back(bundleRecord);
225 }
226 }
227 return true;
228 }
229
CreateBundleUsedRecord(const AccessTokenID tokenId,BundleUsedRecord & bundleRecord)230 bool PermissionRecordManager::CreateBundleUsedRecord(const AccessTokenID tokenId, BundleUsedRecord& bundleRecord)
231 {
232 HapTokenInfo tokenInfo;
233 if (AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo) != Constant::SUCCESS) {
234 ACCESSTOKEN_LOG_ERROR(LABEL, "GetHapTokenInfo failed");
235 return false;
236 }
237 bundleRecord.tokenId = tokenId;
238 bundleRecord.isRemote = false;
239 bundleRecord.deviceId = GetDeviceId(tokenId);
240 bundleRecord.bundleName = tokenInfo.bundleName;
241 return true;
242 }
243
GetRecords(int32_t flag,std::vector<GenericValues> recordValues,BundleUsedRecord & bundleRecord,PermissionUsedResult & result)244 void PermissionRecordManager::GetRecords(
245 int32_t flag, std::vector<GenericValues> recordValues, BundleUsedRecord& bundleRecord, PermissionUsedResult& result)
246 {
247 std::vector<PermissionUsedRecord> permissionRecords;
248 for (auto it = recordValues.rbegin(); it != recordValues.rend(); ++it) {
249 GenericValues record = *it;
250 PermissionUsedRecord tmpPermissionRecord;
251 int64_t timestamp = record.GetInt64(PrivacyFiledConst::FIELD_TIMESTAMP);
252 result.beginTimeMillis = ((result.beginTimeMillis == 0) || (timestamp < result.beginTimeMillis)) ?
253 timestamp : result.beginTimeMillis;
254 result.endTimeMillis = (timestamp > result.endTimeMillis) ? timestamp : result.endTimeMillis;
255
256 record.Put(PrivacyFiledConst::FIELD_FLAG, flag);
257 if (DataTranslator::TranslationGenericValuesIntoPermissionUsedRecord(record, tmpPermissionRecord)
258 != Constant::SUCCESS) {
259 ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to transform opcode(%{public}d) into permission",
260 record.GetInt(PrivacyFiledConst::FIELD_OP_CODE));
261 continue;
262 }
263
264 auto iter = std::find_if(permissionRecords.begin(), permissionRecords.end(),
265 [tmpPermissionRecord](const PermissionUsedRecord& rec) {
266 return tmpPermissionRecord.permissionName == rec.permissionName;
267 });
268 if (iter != permissionRecords.end()) {
269 UpdateRecords(flag, tmpPermissionRecord, *iter);
270 } else {
271 permissionRecords.emplace_back(tmpPermissionRecord);
272 }
273 }
274 bundleRecord.permissionRecords = permissionRecords;
275 }
276
UpdateRecords(int32_t flag,const PermissionUsedRecord & inBundleRecord,PermissionUsedRecord & outBundleRecord)277 void PermissionRecordManager::UpdateRecords(
278 int32_t flag, const PermissionUsedRecord& inBundleRecord, PermissionUsedRecord& outBundleRecord)
279 {
280 outBundleRecord.accessCount += inBundleRecord.accessCount;
281 outBundleRecord.rejectCount += inBundleRecord.rejectCount;
282 if (inBundleRecord.lastAccessTime > outBundleRecord.lastAccessTime) {
283 outBundleRecord.lastAccessTime = inBundleRecord.lastAccessTime;
284 outBundleRecord.lastAccessDuration = inBundleRecord.lastAccessDuration;
285 }
286 outBundleRecord.lastRejectTime = (inBundleRecord.lastRejectTime > outBundleRecord.lastRejectTime) ?
287 inBundleRecord.lastRejectTime : outBundleRecord.lastRejectTime;
288
289 if (flag == 0) {
290 return;
291 }
292 if (inBundleRecord.lastAccessTime > 0 && outBundleRecord.accessRecords.size() < Constant::MAX_DETAIL_RECORD) {
293 outBundleRecord.accessRecords.emplace_back(inBundleRecord.accessRecords[0]);
294 }
295 if (inBundleRecord.lastRejectTime > 0 && outBundleRecord.rejectRecords.size() < Constant::MAX_DETAIL_RECORD) {
296 outBundleRecord.rejectRecords.emplace_back(inBundleRecord.rejectRecords[0]);
297 }
298 }
299
ExecuteDeletePermissionRecordTask()300 void PermissionRecordManager::ExecuteDeletePermissionRecordTask()
301 {
302 if (deleteTaskWorker_.GetCurTaskNum() > 1) {
303 ACCESSTOKEN_LOG_INFO(LABEL, "Already has delete task!");
304 return;
305 }
306
307 auto deleteRecordsTask = [this]() {
308 ACCESSTOKEN_LOG_DEBUG(LABEL, "DeletePermissionRecord task called");
309 DeletePermissionRecord(Constant::RECORD_DELETE_TIME);
310 };
311 deleteTaskWorker_.AddTask(deleteRecordsTask);
312 }
313
DeletePermissionRecord(int64_t days)314 int32_t PermissionRecordManager::DeletePermissionRecord(int64_t days)
315 {
316 Utils::UniqueWriteGuard<Utils::RWLock> lk(this->rwLock_);
317 GenericValues countValue;
318 PermissionRecordRepository::GetInstance().CountRecordValues(countValue);
319 int64_t total = countValue.GetInt64(FIELD_COUNT_NUMBER);
320 if (total > Constant::MAX_TOTAL_RECORD) {
321 uint32_t excessiveSize = total - Constant::MAX_TOTAL_RECORD;
322 if (!PermissionRecordRepository::GetInstance().DeleteExcessiveSizeRecordValues(excessiveSize)) {
323 return Constant::FAILURE;
324 }
325 }
326 GenericValues andConditionValues;
327 int64_t deleteTimestamp = TimeUtil::GetCurrentTimestamp() - days;
328 andConditionValues.Put(PrivacyFiledConst::FIELD_TIMESTAMP_END, deleteTimestamp);
329 if (!PermissionRecordRepository::GetInstance().DeleteExpireRecordsValues(andConditionValues)) {
330 return Constant::FAILURE;
331 }
332 return Constant::SUCCESS;
333 }
334
AddRecordIfNotStarted(const PermissionRecord & record)335 bool PermissionRecordManager::AddRecordIfNotStarted(const PermissionRecord& record)
336 {
337 std::lock_guard<std::mutex> lock(startRecordListMutex_);
338 bool hasStarted = std::any_of(startRecordList_.begin(), startRecordList_.end(),
339 [record](const auto& rec) { return (rec.opCode == record.opCode) && (rec.tokenId == record.tokenId); });
340 if (hasStarted) {
341 ACCESSTOKEN_LOG_ERROR(LABEL, "tokenId(%{public}d), opCode(%{public}d) has been started.",
342 record.tokenId, record.opCode);
343 } else {
344 ACCESSTOKEN_LOG_DEBUG(LABEL, "tokenId(%{public}d), opCode(%{public}d) add record.",
345 record.tokenId, record.opCode);
346 startRecordList_.emplace_back(record);
347 AddRecord(record); // when start using permission, add a instananeous record which accessDuration is 0
348 }
349 return hasStarted;
350 }
351
FindRecordsToUpdateAndExecuted(uint32_t tokenId,ActiveChangeType status)352 void PermissionRecordManager::FindRecordsToUpdateAndExecuted(uint32_t tokenId, ActiveChangeType status)
353 {
354 std::lock_guard<std::mutex> lock(startRecordListMutex_);
355 std::vector<std::string> permList;
356 std::vector<std::string> camPermList;
357 for (auto it = startRecordList_.begin(); it != startRecordList_.end(); ++it) {
358 if ((it->tokenId == tokenId) && ((it->status) != status)) {
359 std::string perm;
360 Constant::TransferOpcodeToPermission(it->opCode, perm);
361 if (!GetGlobalSwitchStatus(perm)) {
362 continue;
363 }
364
365 // app use camera background without float window
366 bool isShow = IsFlowWindowShow(tokenId);
367 if ((perm == CAMERA_PERMISSION_NAME) && (status == PERM_ACTIVE_IN_BACKGROUND) && (!isShow)) {
368 ACCESSTOKEN_LOG_INFO(LABEL, "camera float window is close!");
369 camPermList.emplace_back(perm);
370 continue;
371 }
372 permList.emplace_back(perm);
373 int64_t curStamp = TimeUtil::GetCurrentTimestamp();
374 // update accessDuration and store in database
375 it->accessDuration = curStamp - it->timestamp;
376 AddRecord(*it);
377
378 // update status to input, accessDuration to 0 and timestamp to now in cache
379 it->status = status;
380 it->accessDuration = 0;
381 it->timestamp = curStamp;
382 ACCESSTOKEN_LOG_DEBUG(LABEL, "tokenId %{public}d get target permission %{public}s.", tokenId, perm.c_str());
383 }
384 }
385 if (!camPermList.empty()) {
386 ExecuteCameraCallbackAsync(tokenId);
387 }
388 // each permission sends a status change notice
389 for (const auto& perm : permList) {
390 CallbackExecute(tokenId, perm, status);
391 }
392 }
393
394 /*
395 * when foreground change background or background change foreground,change accessDuration and store in database,
396 * change status and accessDuration and timestamp in cache
397 */
NotifyAppStateChange(AccessTokenID tokenId,ActiveChangeType status)398 void PermissionRecordManager::NotifyAppStateChange(AccessTokenID tokenId, ActiveChangeType status)
399 {
400 ACCESSTOKEN_LOG_INFO(LABEL, "tokenId %{public}d, status %{public}d", tokenId, status);
401 // find permissions from startRecordList_ by tokenId which status diff from currStatus
402 FindRecordsToUpdateAndExecuted(tokenId, status);
403 }
404
RemoveRecordFromStartList(const PermissionRecord & record)405 void PermissionRecordManager::RemoveRecordFromStartList(const PermissionRecord& record)
406 {
407 ACCESSTOKEN_LOG_DEBUG(LABEL, "tokenId %{public}d, opCode %{public}d", record.tokenId, record.opCode);
408 std::lock_guard<std::mutex> lock(startRecordListMutex_);
409 for (auto it = startRecordList_.begin(); it != startRecordList_.end(); ++it) {
410 if ((it->opCode == record.opCode) && (it->tokenId == record.tokenId)) {
411 startRecordList_.erase(it);
412 return;
413 }
414 }
415 }
416
UpdateRecord(const PermissionRecord & record)417 void PermissionRecordManager::UpdateRecord(const PermissionRecord& record)
418 {
419 ACCESSTOKEN_LOG_DEBUG(LABEL, "tokenId %{public}d, opCode %{public}d", record.tokenId, record.opCode);
420 std::lock_guard<std::mutex> lock(startRecordListMutex_);
421 for (auto it = startRecordList_.begin(); it != startRecordList_.end(); ++it) {
422 if ((it->opCode == record.opCode) && (it->tokenId == record.tokenId)) {
423 it->status = record.status;
424 return;
425 }
426 }
427 }
428
GetRecordFromStartList(uint32_t tokenId,int32_t opCode,PermissionRecord & record)429 bool PermissionRecordManager::GetRecordFromStartList(uint32_t tokenId, int32_t opCode, PermissionRecord& record)
430 {
431 std::lock_guard<std::mutex> lock(startRecordListMutex_);
432 for (auto it = startRecordList_.begin(); it != startRecordList_.end(); ++it) {
433 if ((it->opCode == opCode) && (it->tokenId == tokenId)) {
434 record = *it;
435 record.accessDuration = TimeUtil::GetCurrentTimestamp() - record.timestamp;
436 startRecordList_.erase(it);
437 return true;
438 }
439 }
440 return false;
441 }
442
CallbackExecute(AccessTokenID tokenId,const std::string & permissionName,int32_t status)443 void PermissionRecordManager::CallbackExecute(
444 AccessTokenID tokenId, const std::string& permissionName, int32_t status)
445 {
446 ACCESSTOKEN_LOG_INFO(LABEL, "entry ExecuteCallbackAsync, int32_t status is %{public}d", status);
447 ActiveStatusCallbackManager::GetInstance().ExecuteCallbackAsync(
448 tokenId, permissionName, GetDeviceId(tokenId), (ActiveChangeType)status);
449 }
450
GetGlobalSwitchStatus(const std::string & permissionName)451 bool PermissionRecordManager::GetGlobalSwitchStatus(const std::string& permissionName)
452 {
453 bool isOpen = true;
454 // only manage camera and microphone global switch now, other default true
455 if (permissionName == MICROPHONE_PERMISSION_NAME) {
456 isOpen = !AudioManagerPrivacyClient::GetInstance().IsMicrophoneMute();
457 } else if (permissionName == CAMERA_PERMISSION_NAME) {
458 isOpen = !CameraManagerPrivacyClient::GetInstance().IsCameraMuted();
459 }
460
461 ACCESSTOKEN_LOG_INFO(LABEL, "permission is %{public}s, status is %{public}d", permissionName.c_str(), isOpen);
462 return isOpen;
463 }
464
465 /*
466 * StartUsing when close and choose open, update status to foreground or background from inactive
467 * StartUsing when open and choose close, update status to inactive and store in database
468 */
SavePermissionRecords(const std::string & permissionName,PermissionRecord & record,bool switchStatus)469 void PermissionRecordManager::SavePermissionRecords(
470 const std::string& permissionName, PermissionRecord& record, bool switchStatus)
471 {
472 int64_t curStamp = TimeUtil::GetCurrentTimestamp();
473 if (switchStatus) {
474 ACCESSTOKEN_LOG_INFO(LABEL, "global switch is open, update record from inactive");
475 // no need to store in database when status from inactive to foreground or background
476 record.status = GetAppStatus(record.tokenId);
477 record.timestamp = curStamp;
478 } else {
479 ACCESSTOKEN_LOG_INFO(LABEL, "global switch is close, update record to inactive");
480 if (record.status != PERM_INACTIVE) {
481 // update accessDuration and store in database
482 record.accessDuration = curStamp - record.timestamp;
483 AddRecord(record);
484 // update status to input, accessDuration to 0 and timestamp to now in cache
485 record.status = PERM_INACTIVE;
486 record.accessDuration = 0;
487 record.timestamp = curStamp;
488 }
489 }
490 CallbackExecute(record.tokenId, permissionName, record.status);
491 }
492
NotifyMicChange(bool switchStatus)493 void PermissionRecordManager::NotifyMicChange(bool switchStatus)
494 {
495 ACCESSTOKEN_LOG_INFO(LABEL, "===========OnMicStateChange(%{public}d)", switchStatus);
496 std::lock_guard<std::mutex> lock(startRecordListMutex_);
497 for (auto it = startRecordList_.begin(); it != startRecordList_.end(); ++it) {
498 if ((it->opCode) != Constant::OP_MICROPHONE) {
499 continue;
500 }
501 SavePermissionRecords("ohos.permission.MICROPHONE", *it, switchStatus);
502 }
503 }
504
NotifyCameraChange(bool switchStatus)505 void PermissionRecordManager::NotifyCameraChange(bool switchStatus)
506 {
507 ACCESSTOKEN_LOG_INFO(LABEL, "=========OnCameraStateChange(%{public}d)", switchStatus);
508 std::lock_guard<std::mutex> lock(startRecordListMutex_);
509 for (auto it = startRecordList_.begin(); it != startRecordList_.end(); ++it) {
510 if ((it->opCode) != Constant::OP_CAMERA) {
511 continue;
512 }
513 SavePermissionRecords("ohos.permission.CAMERA", *it, switchStatus);
514 }
515 }
516
ShowGlobalDialog(const std::string & permissionName)517 bool PermissionRecordManager::ShowGlobalDialog(const std::string& permissionName)
518 {
519 std::string resource;
520 if (permissionName == CAMERA_PERMISSION_NAME) {
521 resource = "camera";
522 } else if (permissionName == MICROPHONE_PERMISSION_NAME) {
523 resource = "microphone";
524 } else {
525 ACCESSTOKEN_LOG_INFO(LABEL, "invalid permissionName(%{public}s).", permissionName.c_str());
526 return true;
527 }
528
529 AAFwk::Want want;
530 want.SetElementName(PERMISSION_MANAGER_BUNDLE_NAME, PERMISSION_MANAGER_DIALOG_ABILITY);
531 want.SetParam(RESOURCE_KEY, resource);
532 ErrCode err = AbilityManagerPrivacyClient::GetInstance().StartAbility(want, nullptr);
533 if (err != ERR_OK) {
534 ACCESSTOKEN_LOG_ERROR(LABEL, "Fail to StartAbility, err:%{public}d", err);
535 return false;
536 }
537 return true;
538 }
539
StartUsingPermission(AccessTokenID tokenId,const std::string & permissionName)540 int32_t PermissionRecordManager::StartUsingPermission(AccessTokenID tokenId, const std::string& permissionName)
541 {
542 if (!Register()) {
543 return PrivacyError::ERR_MALLOC_FAILED;
544 }
545 int32_t accessCount = 1;
546 int32_t failCount = 0;
547
548 PermissionRecord record = { 0 };
549 int32_t result = GetPermissionRecord(tokenId, permissionName, accessCount, failCount, record);
550 if (result != Constant::SUCCESS) {
551 return result;
552 }
553
554 if (AddRecordIfNotStarted(record)) {
555 return PrivacyError::ERR_PERMISSION_ALREADY_START_USING;
556 }
557
558 if (!GetGlobalSwitchStatus(permissionName)) {
559 if (!ShowGlobalDialog(permissionName)) {
560 ACCESSTOKEN_LOG_ERROR(LABEL, "show permission dialog failed.");
561 RemoveRecordFromStartList(record);
562 return ERR_SERVICE_ABNORMAL;
563 }
564 record.status = PERM_INACTIVE;
565 } else {
566 CallbackExecute(tokenId, permissionName, record.status);
567 }
568 UpdateRecord(record);
569 return Constant::SUCCESS;
570 }
571
SetCameraCallback(sptr<IRemoteObject> callback)572 void PermissionRecordManager::SetCameraCallback(sptr<IRemoteObject> callback)
573 {
574 std::lock_guard<std::mutex> lock(cameraMutex_);
575 cameraCallback_ = callback;
576 }
577
ExecuteCameraCallbackAsync(AccessTokenID tokenId)578 void PermissionRecordManager::ExecuteCameraCallbackAsync(AccessTokenID tokenId)
579 {
580 ACCESSTOKEN_LOG_DEBUG(LABEL, "entry");
581 auto task = [tokenId, this]() {
582 ACCESSTOKEN_LOG_INFO(LABEL, "ExecuteCameraCallbackAsync task called");
583 sptr<IRemoteObject> cameraCallback = nullptr;
584 {
585 std::lock_guard<std::mutex> lock(this->cameraMutex_);
586 cameraCallback = this->cameraCallback_;
587 if (cameraCallback == nullptr) {
588 ACCESSTOKEN_LOG_ERROR(LABEL, "cameraCallback is null");
589 return;
590 }
591 }
592 auto callback = iface_cast<IStateChangeCallback>(cameraCallback);
593 if (callback != nullptr) {
594 ACCESSTOKEN_LOG_INFO(LABEL, "callback excute changeType %{public}d", PERM_INACTIVE);
595 callback->StateChangeNotify(tokenId, false);
596 SetCameraCallback(nullptr);
597 }
598 };
599 std::thread executeThread(task);
600 executeThread.detach();
601 ACCESSTOKEN_LOG_DEBUG(LABEL, "The callback execution is complete");
602 }
603
604 /*
605 * when camera float window is not show, notice camera service to use StopUsingPermission
606 */
NotifyCameraFloatWindowChange(AccessTokenID tokenId,bool isShowing)607 void PermissionRecordManager::NotifyCameraFloatWindowChange(AccessTokenID tokenId, bool isShowing)
608 {
609 camFloatWindowShowing_ = isShowing;
610 floatWindowTokenId_ = tokenId;
611 if ((GetAppStatus(tokenId) == ActiveChangeType::PERM_ACTIVE_IN_BACKGROUND) && !isShowing) {
612 ACCESSTOKEN_LOG_INFO(LABEL, "camera float window is close!");
613 ExecuteCameraCallbackAsync(tokenId);
614 } else {
615 ACCESSTOKEN_LOG_INFO(LABEL, "camera float window is show!");
616 }
617 }
618
StartUsingPermission(AccessTokenID tokenId,const std::string & permissionName,const sptr<IRemoteObject> & callback)619 int32_t PermissionRecordManager::StartUsingPermission(AccessTokenID tokenId, const std::string& permissionName,
620 const sptr<IRemoteObject>& callback)
621 {
622 if (permissionName != CAMERA_PERMISSION_NAME) {
623 ACCESSTOKEN_LOG_ERROR(LABEL, "ERR_PARAM_INVALID is null.");
624 return PrivacyError::ERR_PARAM_INVALID;
625 }
626 if (!Register()) {
627 return PrivacyError::ERR_MALLOC_FAILED;
628 }
629
630 int32_t accessCount = 1;
631 int32_t failCount = 0;
632
633 PermissionRecord record = { 0 };
634 int32_t result = GetPermissionRecord(tokenId, permissionName, accessCount, failCount, record);
635 if (result != Constant::SUCCESS) {
636 return result;
637 }
638
639 if (AddRecordIfNotStarted(record)) {
640 return PrivacyError::ERR_PERMISSION_ALREADY_START_USING;
641 }
642
643 if (!GetGlobalSwitchStatus(permissionName)) {
644 if (!ShowGlobalDialog(permissionName)) {
645 ACCESSTOKEN_LOG_ERROR(LABEL, "show permission dialog failed.");
646 RemoveRecordFromStartList(record);
647 return ERR_SERVICE_ABNORMAL;
648 }
649 record.status = PERM_INACTIVE;
650 } else {
651 CallbackExecute(tokenId, permissionName, record.status);
652 }
653 SetCameraCallback(callback);
654 UpdateRecord(record);
655 return Constant::SUCCESS;
656 }
657
StopUsingPermission(AccessTokenID tokenId,const std::string & permissionName)658 int32_t PermissionRecordManager::StopUsingPermission(AccessTokenID tokenId, const std::string& permissionName)
659 {
660 ExecuteDeletePermissionRecordTask();
661
662 if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) {
663 ACCESSTOKEN_LOG_ERROR(LABEL, "invalid tokenId(%{public}d)", tokenId);
664 return PrivacyError::ERR_TOKENID_NOT_EXIST;
665 }
666 int32_t opCode;
667 if (!Constant::TransferPermissionToOpcode(permissionName, opCode)) {
668 ACCESSTOKEN_LOG_ERROR(LABEL, "invalid permission(%{public}s)", permissionName.c_str());
669 return PrivacyError::ERR_PERMISSION_NOT_EXIST;
670 }
671
672 PermissionRecord record;
673 if (!GetRecordFromStartList(tokenId, opCode, record)) {
674 return PrivacyError::ERR_PERMISSION_NOT_START_USING;
675 }
676
677 if (record.status != PERM_INACTIVE) {
678 AddRecord(record);
679 CallbackExecute(tokenId, permissionName, PERM_INACTIVE);
680 }
681 return Constant::SUCCESS;
682 }
683
PermListToString(const std::vector<std::string> & permList)684 void PermissionRecordManager::PermListToString(const std::vector<std::string>& permList)
685 {
686 std::string permStr;
687 permStr = accumulate(permList.begin(), permList.end(), std::string(" "));
688
689 ACCESSTOKEN_LOG_INFO(LABEL, "permStr =%{public}s", permStr.c_str());
690 }
691
PermissionListFilter(const std::vector<std::string> & listSrc,std::vector<std::string> & listRes)692 int32_t PermissionRecordManager::PermissionListFilter(
693 const std::vector<std::string>& listSrc, std::vector<std::string>& listRes)
694 {
695 PermissionDef permissionDef;
696 std::set<std::string> permSet;
697 for (const auto& permissionName : listSrc) {
698 if (AccessTokenKit::GetDefPermission(permissionName, permissionDef) == Constant::SUCCESS &&
699 permSet.count(permissionName) == 0) {
700 listRes.emplace_back(permissionName);
701 permSet.insert(permissionName);
702 continue;
703 }
704 ACCESSTOKEN_LOG_ERROR(LABEL, "permission %{public}s invalid!", permissionName.c_str());
705 }
706 if ((listRes.empty()) && (!listSrc.empty())) {
707 ACCESSTOKEN_LOG_ERROR(LABEL, "valid permission size is 0!");
708 return PrivacyError::ERR_PARAM_INVALID;
709 }
710 PermListToString(listRes);
711 return Constant::SUCCESS;
712 }
713
IsAllowedUsingPermission(AccessTokenID tokenId,const std::string & permissionName)714 bool PermissionRecordManager::IsAllowedUsingPermission(AccessTokenID tokenId, const std::string& permissionName)
715 {
716 // when app in foreground, return true, only for camera and microphone
717 if ((permissionName != CAMERA_PERMISSION_NAME) && (permissionName != MICROPHONE_PERMISSION_NAME)) {
718 return false;
719 }
720
721 HapTokenInfo tokenInfo;
722 if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) {
723 ACCESSTOKEN_LOG_ERROR(LABEL, "invalid tokenId(%{public}d)", tokenId);
724 return false;
725 }
726
727 int32_t status = GetAppStatus(tokenId);
728 ACCESSTOKEN_LOG_INFO(LABEL, "tokenId %{public}d, status is %{public}d", tokenId, status);
729
730 if (status == ActiveChangeType::PERM_ACTIVE_IN_FOREGROUND) {
731 return true;
732 } else if (permissionName == CAMERA_PERMISSION_NAME) {
733 return IsFlowWindowShow(tokenId);
734 }
735 return false;
736 }
737
RegisterPermActiveStatusCallback(const std::vector<std::string> & permList,const sptr<IRemoteObject> & callback)738 int32_t PermissionRecordManager::RegisterPermActiveStatusCallback(
739 const std::vector<std::string>& permList, const sptr<IRemoteObject>& callback)
740 {
741 std::vector<std::string> permListRes;
742 int32_t res = PermissionListFilter(permList, permListRes);
743 if (res != Constant::SUCCESS) {
744 return res;
745 }
746 return ActiveStatusCallbackManager::GetInstance().AddCallback(permListRes, callback);
747 }
748
UnRegisterPermActiveStatusCallback(const sptr<IRemoteObject> & callback)749 int32_t PermissionRecordManager::UnRegisterPermActiveStatusCallback(const sptr<IRemoteObject>& callback)
750 {
751 return ActiveStatusCallbackManager::GetInstance().RemoveCallback(callback);
752 }
753
GetDeviceId(AccessTokenID tokenId)754 std::string PermissionRecordManager::GetDeviceId(AccessTokenID tokenId)
755 {
756 HapTokenInfo tokenInfo;
757 if (AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo) != Constant::SUCCESS) {
758 return "";
759 }
760 if (tokenInfo.deviceID == DEFAULT_DEVICEID) { // local
761 return ConstantCommon::GetLocalDeviceId();
762 }
763 return tokenInfo.deviceID;
764 }
765
GetAppStatus(AccessTokenID tokenId)766 int32_t PermissionRecordManager::GetAppStatus(AccessTokenID tokenId)
767 {
768 int32_t status = PERM_INACTIVE;
769 HapTokenInfo tokenInfo;
770 if (AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo) != Constant::SUCCESS) {
771 ACCESSTOKEN_LOG_ERROR(LABEL, "invalid tokenId(%{public}d)", tokenId);
772 return status;
773 }
774 status = PERM_ACTIVE_IN_BACKGROUND;
775 std::vector<AppStateData> foreGroundAppList;
776 AppManagerPrivacyClient::GetInstance().GetForegroundApplications(foreGroundAppList);
777 if (std::any_of(foreGroundAppList.begin(), foreGroundAppList.end(),
778 [=](const auto& foreGroundApp) { return foreGroundApp.bundleName == tokenInfo.bundleName; })) {
779 status = PERM_ACTIVE_IN_FOREGROUND;
780 std::vector<AppStateData> foreGroundAppList;
781 AppManagerPrivacyClient::GetInstance().GetForegroundApplications(foreGroundAppList);
782 }
783 return status;
784 }
785
IsFlowWindowShow(AccessTokenID tokenId)786 bool PermissionRecordManager::IsFlowWindowShow(AccessTokenID tokenId)
787 {
788 return floatWindowTokenId_ == tokenId && camFloatWindowShowing_;
789 }
790
Register()791 bool PermissionRecordManager::Register()
792 {
793 // microphone mute
794 {
795 std::lock_guard<std::mutex> lock(micMuteMutex_);
796 if (micMuteCallback_ == nullptr) {
797 micMuteCallback_ = new(std::nothrow) AudioRoutingManagerListenerStub();
798 if (micMuteCallback_ == nullptr) {
799 ACCESSTOKEN_LOG_ERROR(LABEL, "register micMuteCallback failed.");
800 return false;
801 }
802 AudioManagerPrivacyClient::GetInstance().SetMicStateChangeCallback(micMuteCallback_);
803 }
804 }
805
806 // camera mute
807 {
808 std::lock_guard<std::mutex> lock(camMuteMutex_);
809 if (camMuteCallback_ == nullptr) {
810 camMuteCallback_ = new(std::nothrow) CameraServiceCallbackStub();
811 if (camMuteCallback_ == nullptr) {
812 ACCESSTOKEN_LOG_ERROR(LABEL, "register camMuteCallback failed.");
813 return false;
814 }
815 CameraManagerPrivacyClient::GetInstance().SetMuteCallback(camMuteCallback_);
816 }
817 }
818
819 // app state change callback register
820 {
821 std::lock_guard<std::mutex> lock(appStateMutex_);
822 if (appStateCallback_ == nullptr) {
823 appStateCallback_ = new(std::nothrow) ApplicationStateObserverStub();
824 if (appStateCallback_ == nullptr) {
825 ACCESSTOKEN_LOG_ERROR(LABEL, "register appStateCallback failed.");
826 return false;
827 }
828 AppManagerPrivacyClient::GetInstance().RegisterApplicationStateObserver(appStateCallback_);
829 }
830 }
831
832 // float window status change callback register
833 {
834 std::lock_guard<std::mutex> lock(floatWinMutex_);
835 if (floatWindowCallback_ == nullptr) {
836 floatWindowCallback_ = new(std::nothrow) WindowManagerPrivacyAgent();
837 if (floatWindowCallback_ == nullptr) {
838 ACCESSTOKEN_LOG_ERROR(LABEL, "register floatWindowCallback failed.");
839 return false;
840 }
841 WindowManagerPrivacyClient::GetInstance().RegisterWindowManagerAgent(
842 WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_CAMERA_FLOAT, floatWindowCallback_);
843 }
844 }
845
846 return true;
847 }
848
Unregister()849 void PermissionRecordManager::Unregister()
850 {
851 // app state change callback unregister
852 {
853 std::lock_guard<std::mutex> lock(appStateMutex_);
854 if (appStateCallback_ != nullptr) {
855 AppManagerPrivacyClient::GetInstance().UnregisterApplicationStateObserver(appStateCallback_);
856 appStateCallback_= nullptr;
857 }
858 }
859
860 // float window status change callback unregister
861 {
862 std::lock_guard<std::mutex> lock(floatWinMutex_);
863 if (floatWindowCallback_ != nullptr) {
864 WindowManagerPrivacyClient::GetInstance().UnregisterWindowManagerAgent(
865 WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_CAMERA_FLOAT, floatWindowCallback_);
866 floatWindowCallback_ = nullptr;
867 }
868 }
869 }
870
OnAppMgrRemoteDiedHandle()871 void PermissionRecordManager::OnAppMgrRemoteDiedHandle()
872 {
873 std::lock_guard<std::mutex> lock(appStateMutex_);
874 appStateCallback_ = nullptr;
875 }
876
OnAudioMgrRemoteDiedHandle()877 void PermissionRecordManager::OnAudioMgrRemoteDiedHandle()
878 {
879 std::lock_guard<std::mutex> lock(micMuteMutex_);
880 micMuteCallback_ = nullptr;
881 }
882
OnCameraMgrRemoteDiedHandle()883 void PermissionRecordManager::OnCameraMgrRemoteDiedHandle()
884 {
885 std::lock_guard<std::mutex> lock(camMuteMutex_);
886 camMuteCallback_ = nullptr;
887 }
888
OnWindowMgrRemoteDiedHandle()889 void PermissionRecordManager::OnWindowMgrRemoteDiedHandle()
890 {
891 std::lock_guard<std::mutex> lock(floatWinMutex_);
892 floatWindowCallback_ = nullptr;
893 }
894
Init()895 void PermissionRecordManager::Init()
896 {
897 if (hasInited_) {
898 return;
899 }
900 ACCESSTOKEN_LOG_INFO(LABEL, "init");
901 deleteTaskWorker_.Start(1);
902 hasInited_ = true;
903 }
904 } // namespace AccessToken
905 } // namespace Security
906 } // namespace OHOS