1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.android.libraries.pcc.chronicle.analysis
18
19 import com.android.libraries.pcc.chronicle.api.ManagementStrategy
20 import com.android.libraries.pcc.chronicle.api.StorageMedia
21 import com.android.libraries.pcc.chronicle.api.policy.PolicyTarget
22 import com.android.libraries.pcc.chronicle.api.policy.StorageMedium
23 import java.time.Duration
24
25 /** Finds the most restrained [ManagementStrategy] from the receiving list. */
mostRestrainednull26 fun List<ManagementStrategy>.mostRestrained(): ManagementStrategy {
27 // Use minOfWith, because comparators order in ascending order, and our comparator gives
28 // more-restrained strategies a negative value (placing them towards the front of the order).
29 return minOfWith(ManagementStrategyComparator) { it }
30 }
31
32 /**
33 * Analysis-specific comparator for [ManagementStrategies][ManagementStrategy].
34 *
35 * Applies a lexicographic ordering to the components of a [ManagementStrategy], implying that more
36 * restrained strategies come before more liberal strategies. From most significant to least
37 * significant, the components are:
38 *
39 * 1. [StorageMedia], as characterized by that media's [danger][StorageMedia.danger] level.
40 * 1. Whether or not the storage will be [encrypted].
41 * 1. The [time to live][StorageMedia.ttl].
42 *
43 * **Note:** [PassThru][ManagementStrategy.PassThru] strategies are considered the most restrained
44 * of all, and are interpreted as being zero danger storage (because nothing is stored).
45 */
46 object ManagementStrategyComparator : Comparator<ManagementStrategy?> {
comparenull47 override fun compare(a: ManagementStrategy?, b: ManagementStrategy?): Int {
48 if (a == b) return 0
49 if (a == null) return 1
50 if (b == null) return -1
51
52 if (a is ManagementStrategy.PassThru) return -1
53 if (b is ManagementStrategy.PassThru) return 1
54
55 a as ManagementStrategy.Stored
56 b as ManagementStrategy.Stored
57
58 if (a.media != b.media) return a.media.danger - b.media.danger
59 if (a.encrypted != b.encrypted) {
60 if (a.encrypted) return -1
61 return 1
62 }
63 return (a.ttl ?: Duration.ZERO).compareTo(b.ttl ?: Duration.ZERO)
64 }
65 }
66
67 /**
68 * Converts a [PolicyTarget's][PolicyTarget] retentions and max age into a list of
69 * [ManagementStrategies][ManagementStrategy].
70 */
PolicyTargetnull71 fun PolicyTarget.retentionsAsManagementStrategies(): List<ManagementStrategy> {
72 if (maxAgeMs == 0L) return listOf(ManagementStrategy.PassThru)
73
74 return retentions.map {
75 ManagementStrategy.Stored(
76 it.encryptionRequired,
77 when (it.medium) {
78 StorageMedium.RAM -> StorageMedia.MEMORY
79 StorageMedium.DISK -> StorageMedia.LOCAL_DISK
80 },
81 Duration.ofMillis(maxAgeMs)
82 )
83 }
84 }
85