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