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