1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "permission_record_set.h"
17 #include "accesstoken_common_log.h"
18 #include "constant.h"
19
20 namespace OHOS {
21 namespace Security {
22 namespace AccessToken {
23
RemoveByKey(std::set<ContinusPermissionRecord> & recordList,const ContinusPermissionRecord & record,const IsEqualFunc & isEqualFunc,std::vector<ContinusPermissionRecord> & retList)24 void PermissionRecordSet::RemoveByKey(std::set<ContinusPermissionRecord>& recordList,
25 const ContinusPermissionRecord& record, const IsEqualFunc& isEqualFunc,
26 std::vector<ContinusPermissionRecord>& retList)
27 {
28 for (auto it = recordList.begin(); it != recordList.end();) {
29 if (((*it).*isEqualFunc)(record)) {
30 retList.emplace_back(*it);
31 it = recordList.erase(it);
32 } else {
33 ++it;
34 }
35 }
36 LOGD(PRI_DOMAIN, PRI_TAG, "After removing record List size = %{public}zu, removed size = %{public}zu",
37 recordList.size(), retList.size());
38 }
39
GetInActiveUniqueRecord(const std::set<ContinusPermissionRecord> & recordList,const std::vector<ContinusPermissionRecord> & removedList,std::vector<ContinusPermissionRecord> & retList)40 void PermissionRecordSet::GetInActiveUniqueRecord(const std::set<ContinusPermissionRecord>& recordList,
41 const std::vector<ContinusPermissionRecord>& removedList, std::vector<ContinusPermissionRecord>& retList)
42 {
43 // get unique record with tokenid and opcode
44 uint64_t lastUniqueKey = 0;
45 for (const auto &record: removedList) {
46 uint64_t curUniqueKey = record.GetTokenIdAndPermCode();
47 if (lastUniqueKey != curUniqueKey) {
48 retList.emplace_back(record);
49 lastUniqueKey = curUniqueKey;
50 }
51 }
52 LOGD(PRI_DOMAIN, PRI_TAG, "Unique list size = %{public}zu", retList.size());
53
54 // filter active records with same tokenid and opcode in set
55 auto iterRemoved = retList.begin();
56 auto iterRemain = recordList.begin();
57 uint64_t removeKey;
58 uint64_t remainKey;
59 while (iterRemoved != retList.end() && iterRemain != recordList.end()) {
60 removeKey = iterRemoved->GetTokenIdAndPermCode();
61 remainKey = iterRemain->GetTokenIdAndPermCode();
62 if (removeKey < remainKey) {
63 ++iterRemoved;
64 continue;
65 } else if (removeKey == remainKey) {
66 if (iterRemain->status != PERM_INACTIVE) {
67 iterRemoved = retList.erase(iterRemoved);
68 continue;
69 }
70 }
71 ++iterRemain;
72 }
73 LOGI(PRI_DOMAIN, PRI_TAG, "Get inactive list size = %{public}zu", retList.size());
74 }
75
GetUnusedCameraRecords(const std::set<ContinusPermissionRecord> & recordList,const std::vector<ContinusPermissionRecord> & removedList,std::vector<ContinusPermissionRecord> & retList)76 void PermissionRecordSet::GetUnusedCameraRecords(const std::set<ContinusPermissionRecord>& recordList,
77 const std::vector<ContinusPermissionRecord>& removedList, std::vector<ContinusPermissionRecord>& retList)
78 {
79 if (removedList.empty()) {
80 return;
81 }
82 // filtering irrelevant records
83 uint64_t lastUniqueKey = 0;
84 for (auto iter = removedList.begin(); iter != removedList.end(); ++iter) {
85 if (iter->opCode != Constant::OP_CAMERA) {
86 continue;
87 }
88 uint64_t curUniqueKey = iter->GetTokenIdAndPid();
89 if (lastUniqueKey == curUniqueKey) {
90 continue;
91 }
92 lastUniqueKey = curUniqueKey;
93 retList.emplace_back(*iter);
94 }
95 LOGD(PRI_DOMAIN, PRI_TAG, "Unique list size = %{public}zu", retList.size());
96
97 // filter records with same tokenid, opcode and pid in set
98 auto iterRemoved = retList.begin();
99 auto iterRemain = recordList.begin();
100 uint64_t removeKey;
101 uint64_t remainKey;
102 while (iterRemoved != retList.end() && iterRemain != recordList.end()) {
103 removeKey = iterRemoved->GetTokenIdAndPermCode();
104 remainKey = iterRemain->GetTokenIdAndPermCode();
105 if (removeKey < remainKey) {
106 ++iterRemoved;
107 continue;
108 } else if (removeKey == remainKey) {
109 if (iterRemoved->IsEqualPid(*iterRemain)) {
110 iterRemoved = retList.erase(iterRemoved);
111 continue;
112 } else if (iterRemoved->pid < iterRemain->pid) {
113 ++iterRemoved;
114 } else {
115 ++iterRemain;
116 }
117 } else {
118 ++iterRemain;
119 }
120 }
121 LOGI(PRI_DOMAIN, PRI_TAG, "Get unused camera list size = %{public}zu", retList.size());
122 }
123 } // namespace AccessToken
124 } // namespace Security
125 } // namespace OHOS