• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.onboarding.versions.testing
2 
3 import com.android.onboarding.versions.ComplianceDate
4 import com.android.onboarding.versions.OnboardingChanges
5 import com.android.onboarding.versions.annotations.ChangeId
6 import com.android.onboarding.versions.annotations.ChangeRadius
7 import com.android.onboarding.versions.changes.ALL_CHANGE_IDS
8 import java.lang.IllegalArgumentException
9 import java.lang.IllegalStateException
10 import java.lang.UnsupportedOperationException
11 
12 /** Fake implementation of [OnboardingChanges]. */
13 class FakeOnboardingChanges(private val component: String) : OnboardingChanges {
14 
15   private val supportedChanges = mutableMapOf<String, MutableMap<Long, Boolean>>()
16   private val packageComplianceDates = mutableMapOf<String, ComplianceDate>()
17 
18   /** Set the compliance date of a component. Defaults to [ComplianceDate.EARLIEST]. */
setComplianceDatenull19   fun setComplianceDate(component: String, complianceDate: ComplianceDate) {
20     packageComplianceDates[extractPackageFromComponent(component)] = complianceDate
21   }
22 
23   /** Get the compliance date of a component. Defaults to [ComplianceDate.EARLIEST]. */
getComplianceDatenull24   fun getComplianceDate(component: String) =
25     packageComplianceDates.computeIfAbsent(extractPackageFromComponent(component)) {
26       ComplianceDate.EARLIEST
27     }
28 
29   /** The compliance date of the executing component. */
30   var complianceDate: ComplianceDate
31     get() = getComplianceDate(extractPackageFromComponent(component))
32     set(value) {
33       setComplianceDate(extractPackageFromComponent(component), value)
34     }
35 
36   /** Forces a change to be enabled. */
enableChangenull37   fun enableChange(changeId: Long) {
38     enableChange(component, changeId)
39   }
40 
41   /** Forces a change to be enabled. */
enableChangenull42   fun enableChange(component: String, changeId: Long) {
43     supportedChanges
44       .computeIfAbsent(extractPackageFromComponent(component)) { mutableMapOf() }[changeId] = true
45   }
46 
47   /** Forces a change to be disabled. */
disableChangenull48   fun disableChange(changeId: Long) {
49     disableChange(component, changeId)
50   }
51 
52   /** Forces a change to be disabled. */
disableChangenull53   fun disableChange(component: String, changeId: Long) {
54     supportedChanges
55       .computeIfAbsent(extractPackageFromComponent(component)) { mutableMapOf() }[changeId] = false
56   }
57 
58   /** Resets a change's availability to whatever is correct for the [complianceDate]. */
resetChangenull59   fun resetChange(changeId: Long) {
60     resetChange(component, changeId)
61   }
62 
63   /** Resets a change's availability to whatever is correct for the [complianceDate]. */
resetChangenull64   fun resetChange(component: String, changeId: Long) {
65     supportedChanges
66       .computeIfAbsent(extractPackageFromComponent(component)) { mutableMapOf() }
67       .remove(changeId)
68   }
69 
currentProcessSupportsChangenull70   override fun currentProcessSupportsChange(changeId: Long): Boolean {
71     return componentSupportsChange(component, changeId)
72   }
73 
requireCurrentProcessSupportsChangenull74   override fun requireCurrentProcessSupportsChange(changeId: Long) {
75     if (currentProcessSupportsChange(changeId)) {
76       return
77     }
78 
79     // currentProcessSupportsChange will throw if this is null
80     val changeData = ALL_CHANGE_IDS[changeId]!!
81 
82     if (changeData.available == ChangeId.NOT_AVAILABLE) {
83       throw UnsupportedOperationException(
84         "This API is not available. The change ($changeId) is set to not available. See OnboardingChanges for options for enabling this change during test and development."
85       )
86     }
87 
88     throw UnsupportedOperationException(
89       "This API is not available. The change ($changeId) is available as of ${changeData.available} but the compliance date of this package is ${complianceDate}"
90     )
91   }
92 
93   /** This is non-functional on the fake. Set compliance dates directly. */
loadSupportedChangesnull94   override fun loadSupportedChanges(component: String) {}
95 
componentSupportsChangenull96   override fun componentSupportsChange(component: String, changeId: Long): Boolean {
97     val packageName = extractPackageFromComponent(component)
98 
99     val changeData =
100       ALL_CHANGE_IDS[changeId]
101         ?: throw IllegalStateException(
102           "Invalid change ID $changeId - this should have been blocked by the conformance checker"
103         )
104 
105     if (
106       changeData.changeRadius == ChangeRadius.SINGLE_COMPONENT &&
107         packageName != extractPackageFromComponent(this.component)
108     ) {
109       // This should be blocked by conformance
110       throw IllegalArgumentException(
111         "You cannot query changes which are SINGLE_COMPONENT across process boundaries."
112       )
113     }
114 
115     val overrideSupport = supportedChanges[packageName]?.get(changeId)
116     if (overrideSupport != null) {
117       return overrideSupport
118     }
119 
120     // (this call should be blocked by conformance)
121     if (changeData.released != ChangeId.NOT_RELEASED) {
122       return true
123     }
124 
125     // The fake does not support the "if it cannot be found then we assume no support" functionality
126 
127     return getComplianceDate(packageName).isAvailable(changeData)
128   }
129 
extractPackageFromComponentnull130   private fun extractPackageFromComponent(component: String) = component.split("/", limit = 2)[0]
131 }
132