xref: /aosp_15_r20/system/chre/util/duplicate_message_detector.cc (revision 84e339476a462649f82315436d70fd732297a399)
1*84e33947SAndroid Build Coastguard Worker /*
2*84e33947SAndroid Build Coastguard Worker  * Copyright (C) 2024 The Android Open Source Project
3*84e33947SAndroid Build Coastguard Worker  *
4*84e33947SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*84e33947SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*84e33947SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*84e33947SAndroid Build Coastguard Worker  *
8*84e33947SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*84e33947SAndroid Build Coastguard Worker  *
10*84e33947SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*84e33947SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*84e33947SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*84e33947SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*84e33947SAndroid Build Coastguard Worker  * limitations under the License.
15*84e33947SAndroid Build Coastguard Worker  */
16*84e33947SAndroid Build Coastguard Worker 
17*84e33947SAndroid Build Coastguard Worker #include "chre/util/duplicate_message_detector.h"
18*84e33947SAndroid Build Coastguard Worker 
19*84e33947SAndroid Build Coastguard Worker #include "chre/platform/system_time.h"
20*84e33947SAndroid Build Coastguard Worker 
21*84e33947SAndroid Build Coastguard Worker #include <cstdint>
22*84e33947SAndroid Build Coastguard Worker 
23*84e33947SAndroid Build Coastguard Worker namespace chre {
24*84e33947SAndroid Build Coastguard Worker 
findOrAdd(uint32_t messageSequenceNumber,uint16_t hostEndpoint,bool * outIsDuplicate)25*84e33947SAndroid Build Coastguard Worker Optional<chreError> DuplicateMessageDetector::findOrAdd(
26*84e33947SAndroid Build Coastguard Worker     uint32_t messageSequenceNumber, uint16_t hostEndpoint,
27*84e33947SAndroid Build Coastguard Worker     bool *outIsDuplicate) {
28*84e33947SAndroid Build Coastguard Worker   DuplicateMessageDetector::ReliableMessageRecord *record =
29*84e33947SAndroid Build Coastguard Worker       findLocked(messageSequenceNumber, hostEndpoint);
30*84e33947SAndroid Build Coastguard Worker   if (outIsDuplicate != nullptr) {
31*84e33947SAndroid Build Coastguard Worker     *outIsDuplicate = record != nullptr;
32*84e33947SAndroid Build Coastguard Worker   }
33*84e33947SAndroid Build Coastguard Worker 
34*84e33947SAndroid Build Coastguard Worker   if (record == nullptr) {
35*84e33947SAndroid Build Coastguard Worker     record = addLocked(messageSequenceNumber, hostEndpoint);
36*84e33947SAndroid Build Coastguard Worker     if (record == nullptr) {
37*84e33947SAndroid Build Coastguard Worker       LOG_OOM();
38*84e33947SAndroid Build Coastguard Worker       if (outIsDuplicate != nullptr) {
39*84e33947SAndroid Build Coastguard Worker         *outIsDuplicate = true;
40*84e33947SAndroid Build Coastguard Worker       }
41*84e33947SAndroid Build Coastguard Worker       return CHRE_ERROR_NO_MEMORY;
42*84e33947SAndroid Build Coastguard Worker     }
43*84e33947SAndroid Build Coastguard Worker   }
44*84e33947SAndroid Build Coastguard Worker   return record->error;
45*84e33947SAndroid Build Coastguard Worker }
46*84e33947SAndroid Build Coastguard Worker 
findAndSetError(uint32_t messageSequenceNumber,uint16_t hostEndpoint,chreError error)47*84e33947SAndroid Build Coastguard Worker bool DuplicateMessageDetector::findAndSetError(uint32_t messageSequenceNumber,
48*84e33947SAndroid Build Coastguard Worker                                                uint16_t hostEndpoint,
49*84e33947SAndroid Build Coastguard Worker                                                chreError error) {
50*84e33947SAndroid Build Coastguard Worker   DuplicateMessageDetector::ReliableMessageRecord *record =
51*84e33947SAndroid Build Coastguard Worker       findLocked(messageSequenceNumber, hostEndpoint);
52*84e33947SAndroid Build Coastguard Worker   if (record == nullptr) {
53*84e33947SAndroid Build Coastguard Worker     return false;
54*84e33947SAndroid Build Coastguard Worker   }
55*84e33947SAndroid Build Coastguard Worker 
56*84e33947SAndroid Build Coastguard Worker   record->error = error;
57*84e33947SAndroid Build Coastguard Worker   return true;
58*84e33947SAndroid Build Coastguard Worker }
59*84e33947SAndroid Build Coastguard Worker 
removeOldEntries()60*84e33947SAndroid Build Coastguard Worker void DuplicateMessageDetector::removeOldEntries() {
61*84e33947SAndroid Build Coastguard Worker   Nanoseconds now = SystemTime::getMonotonicTime();
62*84e33947SAndroid Build Coastguard Worker   while (!mReliableMessageRecordQueue.empty()) {
63*84e33947SAndroid Build Coastguard Worker     ReliableMessageRecord &record = mReliableMessageRecordQueue.top();
64*84e33947SAndroid Build Coastguard Worker     if (record.timestamp + kTimeout <= now) {
65*84e33947SAndroid Build Coastguard Worker       mReliableMessageRecordQueue.pop();
66*84e33947SAndroid Build Coastguard Worker     } else {
67*84e33947SAndroid Build Coastguard Worker       break;
68*84e33947SAndroid Build Coastguard Worker     }
69*84e33947SAndroid Build Coastguard Worker   }
70*84e33947SAndroid Build Coastguard Worker }
71*84e33947SAndroid Build Coastguard Worker 
72*84e33947SAndroid Build Coastguard Worker DuplicateMessageDetector::ReliableMessageRecord*
addLocked(uint32_t messageSequenceNumber,uint16_t hostEndpoint)73*84e33947SAndroid Build Coastguard Worker     DuplicateMessageDetector::addLocked(
74*84e33947SAndroid Build Coastguard Worker         uint32_t messageSequenceNumber,
75*84e33947SAndroid Build Coastguard Worker         uint16_t hostEndpoint) {
76*84e33947SAndroid Build Coastguard Worker   bool success = mReliableMessageRecordQueue.push(
77*84e33947SAndroid Build Coastguard Worker       ReliableMessageRecord{
78*84e33947SAndroid Build Coastguard Worker           .timestamp = SystemTime::getMonotonicTime(),
79*84e33947SAndroid Build Coastguard Worker           .messageSequenceNumber = messageSequenceNumber,
80*84e33947SAndroid Build Coastguard Worker           .hostEndpoint = hostEndpoint,
81*84e33947SAndroid Build Coastguard Worker           .error = Optional<chreError>()});
82*84e33947SAndroid Build Coastguard Worker   return success
83*84e33947SAndroid Build Coastguard Worker       ? findLocked(messageSequenceNumber, hostEndpoint, /* reverse= */ true)
84*84e33947SAndroid Build Coastguard Worker       : nullptr;
85*84e33947SAndroid Build Coastguard Worker }
86*84e33947SAndroid Build Coastguard Worker 
87*84e33947SAndroid Build Coastguard Worker DuplicateMessageDetector::ReliableMessageRecord*
findLocked(uint32_t messageSequenceNumber,uint16_t hostEndpoint,bool reverse)88*84e33947SAndroid Build Coastguard Worker   DuplicateMessageDetector::findLocked(uint32_t messageSequenceNumber,
89*84e33947SAndroid Build Coastguard Worker                                        uint16_t hostEndpoint,
90*84e33947SAndroid Build Coastguard Worker                                        bool reverse) {
91*84e33947SAndroid Build Coastguard Worker   for (size_t i = 0; i < mReliableMessageRecordQueue.size(); ++i) {
92*84e33947SAndroid Build Coastguard Worker     size_t index = reverse ? mReliableMessageRecordQueue.size() - i - 1 : i;
93*84e33947SAndroid Build Coastguard Worker     ReliableMessageRecord &record = mReliableMessageRecordQueue[index];
94*84e33947SAndroid Build Coastguard Worker     if (record.messageSequenceNumber == messageSequenceNumber &&
95*84e33947SAndroid Build Coastguard Worker         record.hostEndpoint == hostEndpoint) {
96*84e33947SAndroid Build Coastguard Worker       return &record;
97*84e33947SAndroid Build Coastguard Worker     }
98*84e33947SAndroid Build Coastguard Worker   }
99*84e33947SAndroid Build Coastguard Worker   return nullptr;
100*84e33947SAndroid Build Coastguard Worker }
101*84e33947SAndroid Build Coastguard Worker 
102*84e33947SAndroid Build Coastguard Worker }  // namespace chre
103