• 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 "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     for (auto it = startRecordList_.begin(); it != startRecordList_.end(); ++it) {
497         if ((it->opCode) != Constant::OP_MICROPHONE) {
498             continue;
499         }
500         SavePermissionRecords("ohos.permission.MICROPHONE", *it, switchStatus);
501     }
502 }
503 
NotifyCameraChange(bool switchStatus)504 void PermissionRecordManager::NotifyCameraChange(bool switchStatus)
505 {
506     ACCESSTOKEN_LOG_INFO(LABEL, "=========OnCameraStateChange(%{public}d)", switchStatus);
507     for (auto it = startRecordList_.begin(); it != startRecordList_.end(); ++it) {
508         if ((it->opCode) != Constant::OP_CAMERA) {
509             continue;
510         }
511         SavePermissionRecords("ohos.permission.CAMERA", *it, switchStatus);
512     }
513 }
514 
ShowGlobalDialog(const std::string & permissionName)515 bool PermissionRecordManager::ShowGlobalDialog(const std::string& permissionName)
516 {
517     std::string resource;
518     if (permissionName == CAMERA_PERMISSION_NAME) {
519         resource = "camera";
520     } else if (permissionName == MICROPHONE_PERMISSION_NAME) {
521         resource = "microphone";
522     } else {
523         ACCESSTOKEN_LOG_INFO(LABEL, "invalid permissionName(%{public}s).", permissionName.c_str());
524         return true;
525     }
526 
527     AAFwk::Want want;
528     want.SetElementName(PERMISSION_MANAGER_BUNDLE_NAME, PERMISSION_MANAGER_DIALOG_ABILITY);
529     want.SetParam(RESOURCE_KEY, resource);
530     ErrCode err = AbilityManagerPrivacyClient::GetInstance().StartAbility(want, nullptr);
531     if (err != ERR_OK) {
532         ACCESSTOKEN_LOG_ERROR(LABEL, "Fail to StartAbility, err:%{public}d", err);
533         return false;
534     }
535     return true;
536 }
537 
StartUsingPermission(AccessTokenID tokenId,const std::string & permissionName)538 int32_t PermissionRecordManager::StartUsingPermission(AccessTokenID tokenId, const std::string& permissionName)
539 {
540     if (!Register()) {
541         return PrivacyError::ERR_MALLOC_FAILED;
542     }
543     int32_t accessCount = 1;
544     int32_t failCount = 0;
545 
546     PermissionRecord record = { 0 };
547     int32_t result = GetPermissionRecord(tokenId, permissionName, accessCount, failCount, record);
548     if (result != Constant::SUCCESS) {
549         return result;
550     }
551 
552     if (AddRecordIfNotStarted(record)) {
553         return PrivacyError::ERR_PERMISSION_ALREADY_START_USING;
554     }
555 
556     if (!GetGlobalSwitchStatus(permissionName)) {
557         if (!ShowGlobalDialog(permissionName)) {
558             ACCESSTOKEN_LOG_ERROR(LABEL, "show permission dialog failed.");
559             RemoveRecordFromStartList(record);
560             return ERR_SERVICE_ABNORMAL;
561         }
562         record.status = PERM_INACTIVE;
563     } else {
564         CallbackExecute(tokenId, permissionName, record.status);
565     }
566     UpdateRecord(record);
567     return Constant::SUCCESS;
568 }
569 
SetCameraCallback(sptr<IRemoteObject> callback)570 void PermissionRecordManager::SetCameraCallback(sptr<IRemoteObject> callback)
571 {
572     std::lock_guard<std::mutex> lock(cameraMutex_);
573     cameraCallback_ = callback;
574 }
575 
ExecuteCameraCallbackAsync(AccessTokenID tokenId)576 void PermissionRecordManager::ExecuteCameraCallbackAsync(AccessTokenID tokenId)
577 {
578     ACCESSTOKEN_LOG_DEBUG(LABEL, "entry");
579     auto task = [tokenId, this]() {
580         ACCESSTOKEN_LOG_INFO(LABEL, "ExecuteCameraCallbackAsync task called");
581         sptr<IRemoteObject> cameraCallback = nullptr;
582         {
583             std::lock_guard<std::mutex> lock(this->cameraMutex_);
584             cameraCallback = this->cameraCallback_;
585             if (cameraCallback == nullptr) {
586                 ACCESSTOKEN_LOG_ERROR(LABEL, "cameraCallback is null");
587                 return;
588             }
589         }
590         auto callback = iface_cast<IStateChangeCallback>(cameraCallback);
591         if (callback != nullptr) {
592             ACCESSTOKEN_LOG_INFO(LABEL, "callback excute changeType %{public}d", PERM_INACTIVE);
593             callback->StateChangeNotify(tokenId, false);
594             SetCameraCallback(nullptr);
595         }
596     };
597     std::thread executeThread(task);
598     executeThread.detach();
599     ACCESSTOKEN_LOG_DEBUG(LABEL, "The callback execution is complete");
600 }
601 
602 /*
603  * when camera float window is not show, notice camera service to use StopUsingPermission
604  */
NotifyCameraFloatWindowChange(AccessTokenID tokenId,bool isShowing)605 void PermissionRecordManager::NotifyCameraFloatWindowChange(AccessTokenID tokenId, bool isShowing)
606 {
607     camFloatWindowShowing_ = isShowing;
608     floatWindowTokenId_ = tokenId;
609     if ((GetAppStatus(tokenId) == ActiveChangeType::PERM_ACTIVE_IN_BACKGROUND) && !isShowing) {
610         ACCESSTOKEN_LOG_INFO(LABEL, "camera float window is close!");
611         ExecuteCameraCallbackAsync(tokenId);
612     } else {
613         ACCESSTOKEN_LOG_INFO(LABEL, "camera float window is show!");
614     }
615 }
616 
StartUsingPermission(AccessTokenID tokenId,const std::string & permissionName,const sptr<IRemoteObject> & callback)617 int32_t PermissionRecordManager::StartUsingPermission(AccessTokenID tokenId, const std::string& permissionName,
618     const sptr<IRemoteObject>& callback)
619 {
620     if (permissionName != CAMERA_PERMISSION_NAME) {
621         ACCESSTOKEN_LOG_ERROR(LABEL, "ERR_PARAM_INVALID is null.");
622         return PrivacyError::ERR_PARAM_INVALID;
623     }
624     if (!Register()) {
625         return PrivacyError::ERR_MALLOC_FAILED;
626     }
627 
628     int32_t accessCount = 1;
629     int32_t failCount = 0;
630 
631     PermissionRecord record = { 0 };
632     int32_t result = GetPermissionRecord(tokenId, permissionName, accessCount, failCount, record);
633     if (result != Constant::SUCCESS) {
634         return result;
635     }
636 
637     if (AddRecordIfNotStarted(record)) {
638         return PrivacyError::ERR_PERMISSION_ALREADY_START_USING;
639     }
640 
641     if (!GetGlobalSwitchStatus(permissionName)) {
642         if (!ShowGlobalDialog(permissionName)) {
643             ACCESSTOKEN_LOG_ERROR(LABEL, "show permission dialog failed.");
644             RemoveRecordFromStartList(record);
645             return ERR_SERVICE_ABNORMAL;
646         }
647         record.status = PERM_INACTIVE;
648     } else {
649         CallbackExecute(tokenId, permissionName, record.status);
650     }
651     SetCameraCallback(callback);
652     UpdateRecord(record);
653     return Constant::SUCCESS;
654 }
655 
StopUsingPermission(AccessTokenID tokenId,const std::string & permissionName)656 int32_t PermissionRecordManager::StopUsingPermission(AccessTokenID tokenId, const std::string& permissionName)
657 {
658     ExecuteDeletePermissionRecordTask();
659 
660     if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) {
661         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid tokenId(%{public}d)", tokenId);
662         return PrivacyError::ERR_TOKENID_NOT_EXIST;
663     }
664     int32_t opCode;
665     if (!Constant::TransferPermissionToOpcode(permissionName, opCode)) {
666         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid permission(%{public}s)", permissionName.c_str());
667         return PrivacyError::ERR_PERMISSION_NOT_EXIST;
668     }
669 
670     PermissionRecord record;
671     if (!GetRecordFromStartList(tokenId, opCode, record)) {
672         return PrivacyError::ERR_PERMISSION_NOT_START_USING;
673     }
674 
675     if (record.status != PERM_INACTIVE) {
676         AddRecord(record);
677         CallbackExecute(tokenId, permissionName, PERM_INACTIVE);
678     }
679     return Constant::SUCCESS;
680 }
681 
PermListToString(const std::vector<std::string> & permList)682 void PermissionRecordManager::PermListToString(const std::vector<std::string>& permList)
683 {
684     std::string permStr;
685     permStr = accumulate(permList.begin(), permList.end(), std::string(" "));
686 
687     ACCESSTOKEN_LOG_INFO(LABEL, "permStr =%{public}s", permStr.c_str());
688 }
689 
PermissionListFilter(const std::vector<std::string> & listSrc,std::vector<std::string> & listRes)690 int32_t PermissionRecordManager::PermissionListFilter(
691     const std::vector<std::string>& listSrc, std::vector<std::string>& listRes)
692 {
693     PermissionDef permissionDef;
694     std::set<std::string> permSet;
695     for (const auto& permissionName : listSrc) {
696         if (AccessTokenKit::GetDefPermission(permissionName, permissionDef) == Constant::SUCCESS &&
697             permSet.count(permissionName) == 0) {
698             listRes.emplace_back(permissionName);
699             permSet.insert(permissionName);
700             continue;
701         }
702         ACCESSTOKEN_LOG_ERROR(LABEL, "permission %{public}s invalid!", permissionName.c_str());
703     }
704     if ((listRes.empty()) && (!listSrc.empty())) {
705         ACCESSTOKEN_LOG_ERROR(LABEL, "valid permission size is 0!");
706         return PrivacyError::ERR_PARAM_INVALID;
707     }
708     PermListToString(listRes);
709     return Constant::SUCCESS;
710 }
711 
IsAllowedUsingPermission(AccessTokenID tokenId,const std::string & permissionName)712 bool PermissionRecordManager::IsAllowedUsingPermission(AccessTokenID tokenId, const std::string& permissionName)
713 {
714     // when app in foreground, return true, only for camera and microphone
715     if ((permissionName != CAMERA_PERMISSION_NAME) && (permissionName != MICROPHONE_PERMISSION_NAME)) {
716         return false;
717     }
718 
719     HapTokenInfo tokenInfo;
720     if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) {
721         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid tokenId(%{public}d)", tokenId);
722         return false;
723     }
724 
725     int32_t status = GetAppStatus(tokenId);
726     ACCESSTOKEN_LOG_INFO(LABEL, "tokenId %{public}d, status is %{public}d", tokenId, status);
727 
728     if (status == ActiveChangeType::PERM_ACTIVE_IN_FOREGROUND) {
729         return true;
730     } else if (permissionName == CAMERA_PERMISSION_NAME) {
731         return IsFlowWindowShow(tokenId);
732     }
733     return false;
734 }
735 
RegisterPermActiveStatusCallback(const std::vector<std::string> & permList,const sptr<IRemoteObject> & callback)736 int32_t PermissionRecordManager::RegisterPermActiveStatusCallback(
737     const std::vector<std::string>& permList, const sptr<IRemoteObject>& callback)
738 {
739     std::vector<std::string> permListRes;
740     int32_t res = PermissionListFilter(permList, permListRes);
741     if (res != Constant::SUCCESS) {
742         return res;
743     }
744     return ActiveStatusCallbackManager::GetInstance().AddCallback(permListRes, callback);
745 }
746 
UnRegisterPermActiveStatusCallback(const sptr<IRemoteObject> & callback)747 int32_t PermissionRecordManager::UnRegisterPermActiveStatusCallback(const sptr<IRemoteObject>& callback)
748 {
749     return ActiveStatusCallbackManager::GetInstance().RemoveCallback(callback);
750 }
751 
GetDeviceId(AccessTokenID tokenId)752 std::string PermissionRecordManager::GetDeviceId(AccessTokenID tokenId)
753 {
754     HapTokenInfo tokenInfo;
755     if (AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo) != Constant::SUCCESS) {
756         return "";
757     }
758     if (tokenInfo.deviceID == DEFAULT_DEVICEID) { // local
759         return ConstantCommon::GetLocalDeviceId();
760     }
761     return tokenInfo.deviceID;
762 }
763 
GetAppStatus(AccessTokenID tokenId)764 int32_t PermissionRecordManager::GetAppStatus(AccessTokenID tokenId)
765 {
766     int32_t status = PERM_INACTIVE;
767     HapTokenInfo tokenInfo;
768     if (AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo) != Constant::SUCCESS) {
769         ACCESSTOKEN_LOG_ERROR(LABEL, "invalid tokenId(%{public}d)", tokenId);
770         return status;
771     }
772     status = PERM_ACTIVE_IN_BACKGROUND;
773     std::vector<AppStateData> foreGroundAppList;
774     AppManagerPrivacyClient::GetInstance().GetForegroundApplications(foreGroundAppList);
775     if (std::any_of(foreGroundAppList.begin(), foreGroundAppList.end(),
776         [=](const auto& foreGroundApp) { return foreGroundApp.bundleName == tokenInfo.bundleName; })) {
777         status = PERM_ACTIVE_IN_FOREGROUND;
778         std::vector<AppStateData> foreGroundAppList;
779         AppManagerPrivacyClient::GetInstance().GetForegroundApplications(foreGroundAppList);
780     }
781     return status;
782 }
783 
IsFlowWindowShow(AccessTokenID tokenId)784 bool PermissionRecordManager::IsFlowWindowShow(AccessTokenID tokenId)
785 {
786     return floatWindowTokenId_ == tokenId && camFloatWindowShowing_;
787 }
788 
Register()789 bool PermissionRecordManager::Register()
790 {
791     // microphone mute
792     {
793         std::lock_guard<std::mutex> lock(micMuteMutex_);
794         if (micMuteCallback_ == nullptr) {
795             micMuteCallback_ = new(std::nothrow) AudioRoutingManagerListenerStub();
796             if (micMuteCallback_ == nullptr) {
797                 ACCESSTOKEN_LOG_ERROR(LABEL, "register micMuteCallback failed.");
798                 return false;
799             }
800             AudioManagerPrivacyClient::GetInstance().SetMicStateChangeCallback(micMuteCallback_);
801         }
802     }
803 
804     // camera mute
805     {
806         std::lock_guard<std::mutex> lock(camMuteMutex_);
807         if (camMuteCallback_ == nullptr) {
808             camMuteCallback_ = new(std::nothrow) CameraServiceCallbackStub();
809             if (camMuteCallback_ == nullptr) {
810                 ACCESSTOKEN_LOG_ERROR(LABEL, "register camMuteCallback failed.");
811                 return false;
812             }
813             CameraManagerPrivacyClient::GetInstance().SetMuteCallback(camMuteCallback_);
814         }
815     }
816 
817     // app state change callback register
818     {
819         std::lock_guard<std::mutex> lock(appStateMutex_);
820         if (appStateCallback_ == nullptr) {
821             appStateCallback_ = new(std::nothrow) ApplicationStateObserverStub();
822             if (appStateCallback_ == nullptr) {
823                 ACCESSTOKEN_LOG_ERROR(LABEL, "register appStateCallback failed.");
824                 return false;
825             }
826             AppManagerPrivacyClient::GetInstance().RegisterApplicationStateObserver(appStateCallback_);
827         }
828     }
829 
830     // float window status change callback register
831     {
832         std::lock_guard<std::mutex> lock(floatWinMutex_);
833         if (floatWindowCallback_ == nullptr) {
834             floatWindowCallback_ = new(std::nothrow) WindowManagerPrivacyAgent();
835             if (floatWindowCallback_ == nullptr) {
836                 ACCESSTOKEN_LOG_ERROR(LABEL, "register floatWindowCallback failed.");
837                 return false;
838             }
839             WindowManagerPrivacyClient::GetInstance().RegisterWindowManagerAgent(
840                 WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_CAMERA_FLOAT, floatWindowCallback_);
841         }
842     }
843 
844     return true;
845 }
846 
Unregister()847 void PermissionRecordManager::Unregister()
848 {
849     // app state change callback unregister
850     {
851         std::lock_guard<std::mutex> lock(appStateMutex_);
852         if (appStateCallback_ != nullptr) {
853             AppManagerPrivacyClient::GetInstance().UnregisterApplicationStateObserver(appStateCallback_);
854             appStateCallback_= nullptr;
855         }
856     }
857 
858     // float window status change callback unregister
859     {
860         std::lock_guard<std::mutex> lock(floatWinMutex_);
861         if (floatWindowCallback_ != nullptr) {
862             WindowManagerPrivacyClient::GetInstance().UnregisterWindowManagerAgent(
863                 WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_CAMERA_FLOAT, floatWindowCallback_);
864             floatWindowCallback_ = nullptr;
865         }
866     }
867 }
868 
OnAppMgrRemoteDiedHandle()869 void PermissionRecordManager::OnAppMgrRemoteDiedHandle()
870 {
871     std::lock_guard<std::mutex> lock(appStateMutex_);
872     appStateCallback_ = nullptr;
873 }
874 
OnAudioMgrRemoteDiedHandle()875 void PermissionRecordManager::OnAudioMgrRemoteDiedHandle()
876 {
877     std::lock_guard<std::mutex> lock(micMuteMutex_);
878     micMuteCallback_ = nullptr;
879 }
880 
OnCameraMgrRemoteDiedHandle()881 void PermissionRecordManager::OnCameraMgrRemoteDiedHandle()
882 {
883     std::lock_guard<std::mutex> lock(camMuteMutex_);
884     camMuteCallback_ = nullptr;
885 }
886 
OnWindowMgrRemoteDiedHandle()887 void PermissionRecordManager::OnWindowMgrRemoteDiedHandle()
888 {
889     std::lock_guard<std::mutex> lock(floatWinMutex_);
890     floatWindowCallback_ = nullptr;
891 }
892 
Init()893 void PermissionRecordManager::Init()
894 {
895     if (hasInited_) {
896         return;
897     }
898     ACCESSTOKEN_LOG_INFO(LABEL, "init");
899     deleteTaskWorker_.Start(1);
900     hasInited_ = true;
901 }
902 } // namespace AccessToken
903 } // namespace Security
904 } // namespace OHOS