1 /* 2 * Copyright (C) 2021 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.managedprovisioning; 18 19 import static com.android.managedprovisioning.ManagedProvisioningScreens.ADMIN_INTEGRATED_PREPARE; 20 import static com.android.managedprovisioning.ManagedProvisioningScreens.DOWNLOAD_ROLE_HOLDER; 21 import static com.android.managedprovisioning.ManagedProvisioningScreens.ENCRYPT; 22 import static com.android.managedprovisioning.ManagedProvisioningScreens.ESTABLISH_NETWORK_CONNECTION; 23 import static com.android.managedprovisioning.ManagedProvisioningScreens.FINALIZATION_INSIDE_SUW; 24 import static com.android.managedprovisioning.ManagedProvisioningScreens.FINANCED_DEVICE_LANDING; 25 import static com.android.managedprovisioning.ManagedProvisioningScreens.LANDING; 26 import static com.android.managedprovisioning.ManagedProvisioningScreens.POST_ENCRYPT; 27 import static com.android.managedprovisioning.ManagedProvisioningScreens.PRE_PROVISIONING; 28 import static com.android.managedprovisioning.ManagedProvisioningScreens.PRE_PROVISIONING_VIA_NFC; 29 import static com.android.managedprovisioning.ManagedProvisioningScreens.PROVISIONING; 30 import static com.android.managedprovisioning.ManagedProvisioningScreens.RESET_AND_RETURN_DEVICE; 31 import static com.android.managedprovisioning.ManagedProvisioningScreens.RESET_DEVICE; 32 import static com.android.managedprovisioning.ManagedProvisioningScreens.RETRY_LAUNCH; 33 import static com.android.managedprovisioning.ManagedProvisioningScreens.TERMS; 34 import static com.android.managedprovisioning.ManagedProvisioningScreens.WEB; 35 import static com.google.common.truth.Truth.assertThat; 36 import static org.junit.Assert.assertThrows; 37 38 import android.app.Activity; 39 import android.content.Context; 40 import android.content.pm.PackageInfo; 41 import android.content.pm.PackageManager; 42 43 import androidx.test.InstrumentationRegistry; 44 import androidx.test.filters.SmallTest; 45 46 import com.android.managedprovisioning.common.RetryLaunchActivity; 47 import com.android.managedprovisioning.finalization.FinalizationForwarderActivity; 48 import com.android.managedprovisioning.finalization.FinalizationInsideSuwActivity; 49 import com.android.managedprovisioning.networkconnection.EstablishNetworkConnectionActivity; 50 import com.android.managedprovisioning.preprovisioning.DownloadRoleHolderActivity; 51 import com.android.managedprovisioning.preprovisioning.EncryptDeviceActivity; 52 import com.android.managedprovisioning.preprovisioning.PostEncryptionActivity; 53 import com.android.managedprovisioning.preprovisioning.PreProvisioningActivity; 54 import com.android.managedprovisioning.preprovisioning.PreProvisioningActivityViaNfc; 55 import com.android.managedprovisioning.preprovisioning.WebActivity; 56 import com.android.managedprovisioning.preprovisioning.terms.TermsActivity; 57 import com.android.managedprovisioning.provisioning.AdminIntegratedFlowPrepareActivity; 58 import com.android.managedprovisioning.provisioning.FinancedDeviceLandingActivity; 59 import com.android.managedprovisioning.provisioning.LandingActivity; 60 import com.android.managedprovisioning.provisioning.ProvisioningActivity; 61 import com.android.managedprovisioning.provisioning.ResetAndReturnDeviceActivity; 62 import com.android.managedprovisioning.provisioning.ResetDeviceActivity; 63 64 import org.junit.Test; 65 66 import java.util.Arrays; 67 import java.util.Collection; 68 import java.util.HashMap; 69 import java.util.HashSet; 70 import java.util.List; 71 import java.util.Map; 72 import java.util.Objects; 73 import java.util.Set; 74 import java.util.stream.Collectors; 75 76 @SmallTest 77 public final class ScreenManagerTest { 78 private static final int EXPECTED_NUMBER_OF_SCREENS = 16; 79 private static final Map<ManagedProvisioningScreens, Class<? extends Activity>> 80 TEST_SCREEN_TO_ACTIVITY_MAP = createTestScreenToActivityMap(); 81 private static final Map<ManagedProvisioningScreens, Class<? extends Activity>> 82 TEST_INVALID_SCREEN_TO_ACTIVITY_MAP = createInvalidTestScreenToActivityMap(); 83 private static final Set<String> NON_OVERRIDABLE_ACTIVITIES = new HashSet<>(Arrays.asList( 84 // The following activity aliases target PreProvisioningActivity 85 "com.android.managedprovisioning.PreProvisioningActivityAfterEncryption", 86 "com.android.managedprovisioning.PreProvisioningActivityViaTrustedApp", 87 "com.android.managedprovisioning.PreProvisioningActivityViaNfc", 88 FinalizationForwarderActivity.class.getName(), 89 TrampolineActivity.class.getName() 90 )); 91 92 private final Context mContext = InstrumentationRegistry.getTargetContext(); 93 94 @Test getActivityClassForScreen_withDefaultMap_success()95 public void getActivityClassForScreen_withDefaultMap_success() { 96 ScreenManager screenManager = 97 new ScreenManager(ScreenManager.DEFAULT_SCREEN_TO_ACTIVITY_MAP); 98 99 assertThat(screenManager.getActivityClassForScreen(LANDING)) 100 .isEqualTo(LandingActivity.class); 101 assertThat(screenManager.getActivityClassForScreen(PRE_PROVISIONING)) 102 .isEqualTo(PreProvisioningActivity.class); 103 assertThat(screenManager.getActivityClassForScreen(PRE_PROVISIONING_VIA_NFC)) 104 .isEqualTo(PreProvisioningActivityViaNfc.class); 105 assertThat(screenManager.getActivityClassForScreen(PROVISIONING)) 106 .isEqualTo(ProvisioningActivity.class); 107 assertThat(screenManager.getActivityClassForScreen(ADMIN_INTEGRATED_PREPARE)) 108 .isEqualTo(AdminIntegratedFlowPrepareActivity.class); 109 assertThat(screenManager.getActivityClassForScreen(RESET_AND_RETURN_DEVICE)) 110 .isEqualTo(ResetAndReturnDeviceActivity.class); 111 assertThat(screenManager.getActivityClassForScreen(RESET_DEVICE)) 112 .isEqualTo(ResetDeviceActivity.class); 113 assertThat(screenManager.getActivityClassForScreen(WEB)) 114 .isEqualTo(WebActivity.class); 115 assertThat(screenManager.getActivityClassForScreen(ENCRYPT)) 116 .isEqualTo(EncryptDeviceActivity.class); 117 assertThat(screenManager.getActivityClassForScreen(POST_ENCRYPT)) 118 .isEqualTo(PostEncryptionActivity.class); 119 assertThat(screenManager.getActivityClassForScreen(FINALIZATION_INSIDE_SUW)) 120 .isEqualTo(FinalizationInsideSuwActivity.class); 121 assertThat(screenManager.getActivityClassForScreen(TERMS)) 122 .isEqualTo(TermsActivity.class); 123 assertThat(screenManager.getActivityClassForScreen(FINANCED_DEVICE_LANDING)) 124 .isEqualTo(FinancedDeviceLandingActivity.class); 125 assertThat(screenManager.getActivityClassForScreen(RETRY_LAUNCH)) 126 .isEqualTo(RetryLaunchActivity.class); 127 assertThat(screenManager.getActivityClassForScreen(DOWNLOAD_ROLE_HOLDER)) 128 .isEqualTo(DownloadRoleHolderActivity.class); 129 assertThat(screenManager.getActivityClassForScreen(ESTABLISH_NETWORK_CONNECTION)) 130 .isEqualTo(EstablishNetworkConnectionActivity.class); 131 } 132 133 @Test defaultScreenToActivityMap_hasExpectedSize()134 public void defaultScreenToActivityMap_hasExpectedSize() { 135 assertThat(ScreenManager.DEFAULT_SCREEN_TO_ACTIVITY_MAP.size()) 136 .isEqualTo(EXPECTED_NUMBER_OF_SCREENS); 137 } 138 139 @Test getActivityClassForScreen_withCustomMap_success()140 public void getActivityClassForScreen_withCustomMap_success() { 141 ScreenManager screenManager = new ScreenManager(TEST_SCREEN_TO_ACTIVITY_MAP); 142 143 assertThat(screenManager.getActivityClassForScreen(LANDING)).isEqualTo(Activity.class); 144 } 145 146 @Test setOverrideActivity_success()147 public void setOverrideActivity_success() { 148 ScreenManager screenManager = 149 new ScreenManager(ScreenManager.DEFAULT_SCREEN_TO_ACTIVITY_MAP); 150 151 screenManager.setOverrideActivity( 152 ManagedProvisioningScreens.LANDING, 153 Activity.class); 154 155 assertThat(screenManager.getActivityClassForScreen(LANDING)).isEqualTo(Activity.class); 156 } 157 158 @Test constructObject_withInvalidMap_throwsException()159 public void constructObject_withInvalidMap_throwsException() { 160 assertThrows(IllegalStateException.class, 161 () -> new ScreenManager(TEST_INVALID_SCREEN_TO_ACTIVITY_MAP)); 162 } 163 164 @Test verifyEveryActivityIsMapped()165 public void verifyEveryActivityIsMapped() throws PackageManager.NameNotFoundException { 166 List<String> activities = getManagedProvisioningActivityNames(); 167 168 List<String> unmappedActivities = getUnmappedOverridableActivities(activities); 169 170 assertThat(unmappedActivities).isEmpty(); 171 } 172 getUnmappedOverridableActivities(List<String> activities)173 private List<String> getUnmappedOverridableActivities(List<String> activities) { 174 return activities 175 .stream() 176 .filter(activityName -> !isActivityMapped(activityName)) 177 .filter(this::isActivityOverridable) 178 .collect(Collectors.toList()); 179 } 180 isActivityOverridable(String activityName)181 private boolean isActivityOverridable(String activityName) { 182 return !NON_OVERRIDABLE_ACTIVITIES.contains(activityName); 183 } 184 isActivityMapped(String activityName)185 private boolean isActivityMapped(String activityName) { 186 Collection<Class<? extends Activity>> mappedActivities = 187 ScreenManager.DEFAULT_SCREEN_TO_ACTIVITY_MAP.values(); 188 return mappedActivities 189 .stream() 190 .anyMatch(activityClass -> activityClass.getName().equals(activityName)); 191 } 192 getManagedProvisioningActivityNames()193 private List<String> getManagedProvisioningActivityNames() 194 throws PackageManager.NameNotFoundException { 195 PackageManager packageManager = mContext.getPackageManager(); 196 PackageInfo packageInfo = packageManager.getPackageInfo( 197 mContext.getPackageName(), 198 PackageManager.GET_ACTIVITIES); 199 return Arrays.stream(packageInfo.activities) 200 .map(activityInfo -> activityInfo.name) 201 .filter(name -> !Objects.equals(name, "com.android.onboarding.bedsteadonboarding.activities.TrampolineActivity")) 202 .collect(Collectors.toList()); 203 } 204 205 private static Map<ManagedProvisioningScreens, Class<? extends Activity>> createTestScreenToActivityMap()206 createTestScreenToActivityMap() { 207 Map<ManagedProvisioningScreens, Class<? extends Activity>> map = new HashMap<>(); 208 map.put(LANDING, Activity.class); 209 map.put(PRE_PROVISIONING, Activity.class); 210 map.put(PRE_PROVISIONING_VIA_NFC, Activity.class); 211 map.put(PROVISIONING, Activity.class); 212 map.put(ADMIN_INTEGRATED_PREPARE, Activity.class); 213 map.put(RESET_AND_RETURN_DEVICE, Activity.class); 214 map.put(RESET_DEVICE, Activity.class); 215 map.put(WEB, Activity.class); 216 map.put(ENCRYPT, Activity.class); 217 map.put(POST_ENCRYPT, Activity.class); 218 map.put(FINALIZATION_INSIDE_SUW, Activity.class); 219 map.put(TERMS, Activity.class); 220 map.put(FINANCED_DEVICE_LANDING, Activity.class); 221 map.put(RETRY_LAUNCH, Activity.class); 222 map.put(DOWNLOAD_ROLE_HOLDER, Activity.class); 223 map.put(ESTABLISH_NETWORK_CONNECTION, Activity.class); 224 return map; 225 } 226 227 private static Map<ManagedProvisioningScreens, Class<? extends Activity>> createInvalidTestScreenToActivityMap()228 createInvalidTestScreenToActivityMap() { 229 return Map.of(LANDING, LandingActivity.class); 230 } 231 } 232