Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 54a17ad3 authored by Stanislav Zholnin's avatar Stanislav Zholnin
Browse files

Deduplicate discrete operation before delivering result.

Before returning result from the API, we go through the list
of all AttributedOpEntries and those which have the same
timestamp are merged into single AttributedOpEntry without
losing any information (it is still possible to query
AttributedOpEntry with different flags / uidstates and get
all the same information).

This CL addresses issue with duplication due to accesses
with different flags / uidstates.

Test: in development
Bug: 176965672
Bug: 183961838
Change-Id: I319dd321a3bfddf0855c10213c49824e9599eb66
parent 41b21288
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
@@ -6996,6 +6996,20 @@ public class AppOpsManager {
            }
            result.add(entry);
        }
        nAccesses = result.size();
        int i = 0;
        for (int j = 0, k = 0; j < nAccesses; i++, j = k) {
            long currentAccessTime = result.get(j).getLastAccessTime(OP_FLAGS_ALL);
            k = j + 1;
            while(k < nAccesses &&
                    result.get(k).getLastAccessTime(OP_FLAGS_ALL) == currentAccessTime) {
                k++;
            }
            result.set(i, mergeAttributedOpEntries(result.subList(j, k)));
        }
        for (; i < nAccesses; i++) {
            result.remove(result.size() - 1);
        }
        return result;
    }

@@ -9819,4 +9833,35 @@ public class AppOpsManager {
            }
        }
    }

    private static AttributedOpEntry mergeAttributedOpEntries(List<AttributedOpEntry> opEntries) {
        if (opEntries.size() == 1) {
            return opEntries.get(0);
        }
        LongSparseArray<AppOpsManager.NoteOpEvent> accessEvents = new LongSparseArray<>();
        LongSparseArray<AppOpsManager.NoteOpEvent> rejectEvents = new LongSparseArray<>();
        int opCount = opEntries.size();
        for (int i = 0; i < opCount; i++) {
            AttributedOpEntry a = opEntries.get(i);
            ArraySet<Long> keys = a.collectKeys();
            final int keyCount = keys.size();
            for (int k = 0; k < keyCount; k++) {
                final long key = keys.valueAt(k);

                final int uidState = extractUidStateFromKey(key);
                final int flags = extractFlagsFromKey(key);

                NoteOpEvent access = a.getLastAccessEvent(uidState, uidState, flags);
                NoteOpEvent reject = a.getLastRejectEvent(uidState, uidState, flags);

                if (access != null) {
                    accessEvents.append(key, access);
                }
                if (reject != null) {
                    rejectEvents.append(key, reject);
                }
            }
        }
        return new AttributedOpEntry(opEntries.get(0).mOp, false, accessEvents, rejectEvents);
    }
}