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