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.intentresolver 18 19 import com.google.common.truth.Truth.assertThat 20 import org.junit.Test 21 22 /** 23 * Unit tests for the various implementations of {@link TargetPresentationGetter}. 24 * 25 * TODO: consider expanding to cover icon logic (not just labels/sublabels). 26 * TODO: these are conceptually "acceptance tests" that provide comprehensive coverage of the 27 * apparent variations in the legacy implementation. The tests probably don't have to be so 28 * exhaustive if we're able to impose a simpler design on the implementation. 29 */ 30 class TargetPresentationGetterTest { makeResolveInfoPresentationGetternull31 fun makeResolveInfoPresentationGetter( 32 withSubstitutePermission: Boolean, 33 appLabel: String, 34 activityLabel: String, 35 resolveInfoLabel: String, 36 ): TargetPresentationGetter { 37 val testPackageInfo = 38 ResolverDataProvider.createPackageManagerMockedInfo( 39 withSubstitutePermission, 40 appLabel, 41 activityLabel, 42 resolveInfoLabel, 43 ) 44 val factory = 45 TargetPresentationGetter.Factory( 46 { SimpleIconFactory.obtain(testPackageInfo.ctx) }, 47 testPackageInfo.ctx.packageManager, 48 100, 49 ) 50 return factory.makePresentationGetter(testPackageInfo.resolveInfo) 51 } 52 makeActivityInfoPresentationGetternull53 fun makeActivityInfoPresentationGetter( 54 withSubstitutePermission: Boolean, 55 appLabel: String?, 56 activityLabel: String?, 57 ): TargetPresentationGetter { 58 val testPackageInfo = 59 ResolverDataProvider.createPackageManagerMockedInfo( 60 withSubstitutePermission, 61 appLabel, 62 activityLabel, 63 "", 64 ) 65 val factory = 66 TargetPresentationGetter.Factory( 67 { SimpleIconFactory.obtain(testPackageInfo.ctx) }, 68 testPackageInfo.ctx.packageManager, 69 100, 70 ) 71 return factory.makePresentationGetter(testPackageInfo.activityInfo) 72 } 73 74 @Test testActivityInfoLabels_noSubstitutePermission_distinctRequestedLabelAndSublabelnull75 fun testActivityInfoLabels_noSubstitutePermission_distinctRequestedLabelAndSublabel() { 76 val presentationGetter = 77 makeActivityInfoPresentationGetter(false, "app_label", "activity_label") 78 assertThat(presentationGetter.getLabel()).isEqualTo("app_label") 79 assertThat(presentationGetter.getSubLabel()).isEqualTo("activity_label") 80 } 81 82 @Test testActivityInfoLabels_noSubstitutePermission_sameRequestedLabelAndSublabelnull83 fun testActivityInfoLabels_noSubstitutePermission_sameRequestedLabelAndSublabel() { 84 val presentationGetter = makeActivityInfoPresentationGetter(false, "app_label", "app_label") 85 assertThat(presentationGetter.getLabel()).isEqualTo("app_label") 86 // Without the substitute permission, there's no logic to dedupe the labels. 87 // TODO: this matches our observations in the legacy code, but is it the right behavior? It 88 // seems like {@link ResolverListAdapter.ViewHolder#bindLabel()} has some logic to dedupe in 89 // the UI at least, but maybe that logic should be pulled back to the "presentation"? 90 assertThat(presentationGetter.getSubLabel()).isEqualTo("app_label") 91 } 92 93 @Test testActivityInfoLabels_noSubstitutePermission_nullRequestedLabelnull94 fun testActivityInfoLabels_noSubstitutePermission_nullRequestedLabel() { 95 val presentationGetter = makeActivityInfoPresentationGetter(false, null, "activity_label") 96 assertThat(presentationGetter.getLabel()).isNull() 97 assertThat(presentationGetter.getSubLabel()).isEqualTo("activity_label") 98 } 99 100 @Test testActivityInfoLabels_noSubstitutePermission_emptyRequestedLabelnull101 fun testActivityInfoLabels_noSubstitutePermission_emptyRequestedLabel() { 102 val presentationGetter = makeActivityInfoPresentationGetter(false, "", "activity_label") 103 assertThat(presentationGetter.getLabel()).isEqualTo("") 104 assertThat(presentationGetter.getSubLabel()).isEqualTo("activity_label") 105 } 106 107 @Test testActivityInfoLabels_noSubstitutePermission_emptyRequestedSublabelnull108 fun testActivityInfoLabels_noSubstitutePermission_emptyRequestedSublabel() { 109 val presentationGetter = makeActivityInfoPresentationGetter(false, "app_label", "") 110 assertThat(presentationGetter.getLabel()).isEqualTo("app_label") 111 // Without the substitute permission, empty sublabels are passed through as-is. 112 assertThat(presentationGetter.getSubLabel()).isEqualTo("") 113 } 114 115 @Test testActivityInfoLabels_withSubstitutePermission_distinctRequestedLabelAndSublabelnull116 fun testActivityInfoLabels_withSubstitutePermission_distinctRequestedLabelAndSublabel() { 117 val presentationGetter = 118 makeActivityInfoPresentationGetter(true, "app_label", "activity_label") 119 assertThat(presentationGetter.getLabel()).isEqualTo("activity_label") 120 // With the substitute permission, the same ("activity") label is requested as both the 121 // label 122 // and sublabel, even though the other value ("app_label") was distinct. Thus this behaves 123 // the 124 // same as a dupe. 125 assertThat(presentationGetter.getSubLabel()).isEqualTo(null) 126 } 127 128 @Test testActivityInfoLabels_withSubstitutePermission_sameRequestedLabelAndSublabelnull129 fun testActivityInfoLabels_withSubstitutePermission_sameRequestedLabelAndSublabel() { 130 val presentationGetter = makeActivityInfoPresentationGetter(true, "app_label", "app_label") 131 assertThat(presentationGetter.getLabel()).isEqualTo("app_label") 132 // With the substitute permission, duped sublabels get converted to nulls. 133 assertThat(presentationGetter.getSubLabel()).isNull() 134 } 135 136 @Test testActivityInfoLabels_withSubstitutePermission_nullRequestedLabelnull137 fun testActivityInfoLabels_withSubstitutePermission_nullRequestedLabel() { 138 val presentationGetter = makeActivityInfoPresentationGetter(true, "app_label", null) 139 assertThat(presentationGetter.getLabel()).isEqualTo("app_label") 140 // With the substitute permission, null inputs are a special case that produces null outputs 141 // (i.e., they're not simply passed-through from the inputs). 142 assertThat(presentationGetter.getSubLabel()).isNull() 143 } 144 145 @Test testActivityInfoLabels_withSubstitutePermission_emptyRequestedLabelnull146 fun testActivityInfoLabels_withSubstitutePermission_emptyRequestedLabel() { 147 val presentationGetter = makeActivityInfoPresentationGetter(true, "app_label", "") 148 // Empty "labels" are taken as-is and (unlike nulls) don't prompt a fallback to the 149 // sublabel. 150 // Thus (as in the previous case with substitute permission & "distinct" labels), this is 151 // treated as a dupe. 152 assertThat(presentationGetter.getLabel()).isEqualTo("") 153 assertThat(presentationGetter.getSubLabel()).isNull() 154 } 155 156 @Test testActivityInfoLabels_withSubstitutePermission_emptyRequestedSublabelnull157 fun testActivityInfoLabels_withSubstitutePermission_emptyRequestedSublabel() { 158 val presentationGetter = makeActivityInfoPresentationGetter(true, "", "activity_label") 159 assertThat(presentationGetter.getLabel()).isEqualTo("activity_label") 160 // With the substitute permission, empty sublabels get converted to nulls. 161 assertThat(presentationGetter.getSubLabel()).isNull() 162 } 163 164 @Test testResolveInfoLabels_noSubstitutePermission_distinctRequestedLabelAndSublabelnull165 fun testResolveInfoLabels_noSubstitutePermission_distinctRequestedLabelAndSublabel() { 166 val presentationGetter = 167 makeResolveInfoPresentationGetter( 168 false, 169 "app_label", 170 "activity_label", 171 "resolve_info_label", 172 ) 173 assertThat(presentationGetter.getLabel()).isEqualTo("app_label") 174 assertThat(presentationGetter.getSubLabel()).isEqualTo("resolve_info_label") 175 } 176 177 @Test testResolveInfoLabels_noSubstitutePermission_sameRequestedLabelAndSublabelnull178 fun testResolveInfoLabels_noSubstitutePermission_sameRequestedLabelAndSublabel() { 179 val presentationGetter = 180 makeResolveInfoPresentationGetter(false, "app_label", "activity_label", "app_label") 181 assertThat(presentationGetter.getLabel()).isEqualTo("app_label") 182 // Without the substitute permission, there's no logic to dedupe the labels. 183 // TODO: this matches our observations in the legacy code, but is it the right behavior? It 184 // seems like {@link ResolverListAdapter.ViewHolder#bindLabel()} has some logic to dedupe in 185 // the UI at least, but maybe that logic should be pulled back to the "presentation"? 186 assertThat(presentationGetter.getSubLabel()).isEqualTo("app_label") 187 } 188 189 @Test testResolveInfoLabels_noSubstitutePermission_emptyRequestedSublabelnull190 fun testResolveInfoLabels_noSubstitutePermission_emptyRequestedSublabel() { 191 val presentationGetter = 192 makeResolveInfoPresentationGetter(false, "app_label", "activity_label", "") 193 assertThat(presentationGetter.getLabel()).isEqualTo("app_label") 194 // Without the substitute permission, empty sublabels are passed through as-is. 195 assertThat(presentationGetter.getSubLabel()).isEqualTo("") 196 } 197 198 @Test testResolveInfoLabels_withSubstitutePermission_distinctRequestedLabelAndSublabelnull199 fun testResolveInfoLabels_withSubstitutePermission_distinctRequestedLabelAndSublabel() { 200 val presentationGetter = 201 makeResolveInfoPresentationGetter( 202 true, 203 "app_label", 204 "activity_label", 205 "resolve_info_label", 206 ) 207 assertThat(presentationGetter.getLabel()).isEqualTo("activity_label") 208 assertThat(presentationGetter.getSubLabel()).isEqualTo("resolve_info_label") 209 } 210 211 @Test testResolveInfoLabels_withSubstitutePermission_sameRequestedLabelAndSublabelnull212 fun testResolveInfoLabels_withSubstitutePermission_sameRequestedLabelAndSublabel() { 213 val presentationGetter = 214 makeResolveInfoPresentationGetter(true, "app_label", "activity_label", "activity_label") 215 assertThat(presentationGetter.getLabel()).isEqualTo("activity_label") 216 // With the substitute permission, duped sublabels get converted to nulls. 217 assertThat(presentationGetter.getSubLabel()).isNull() 218 } 219 220 @Test testResolveInfoLabels_withSubstitutePermission_emptyRequestedSublabelnull221 fun testResolveInfoLabels_withSubstitutePermission_emptyRequestedSublabel() { 222 val presentationGetter = 223 makeResolveInfoPresentationGetter(true, "app_label", "activity_label", "") 224 assertThat(presentationGetter.getLabel()).isEqualTo("activity_label") 225 // With the substitute permission, empty sublabels get converted to nulls. 226 assertThat(presentationGetter.getSubLabel()).isNull() 227 } 228 229 @Test testResolveInfoLabels_withSubstitutePermission_emptyRequestedLabelAndSublabelnull230 fun testResolveInfoLabels_withSubstitutePermission_emptyRequestedLabelAndSublabel() { 231 val presentationGetter = makeResolveInfoPresentationGetter(true, "app_label", "", "") 232 assertThat(presentationGetter.getLabel()).isEqualTo("") 233 // With the substitute permission, empty sublabels get converted to nulls. 234 assertThat(presentationGetter.getSubLabel()).isNull() 235 } 236 } 237