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 
36 import android.app.Activity;
37 
38 import com.android.managedprovisioning.common.RetryLaunchActivity;
39 import com.android.managedprovisioning.finalization.FinalizationInsideSuwActivity;
40 import com.android.managedprovisioning.networkconnection.EstablishNetworkConnectionActivity;
41 import com.android.managedprovisioning.preprovisioning.DownloadRoleHolderActivity;
42 import com.android.managedprovisioning.preprovisioning.EncryptDeviceActivity;
43 import com.android.managedprovisioning.preprovisioning.PostEncryptionActivity;
44 import com.android.managedprovisioning.preprovisioning.PreProvisioningActivity;
45 import com.android.managedprovisioning.preprovisioning.PreProvisioningActivityViaNfc;
46 import com.android.managedprovisioning.preprovisioning.WebActivity;
47 import com.android.managedprovisioning.preprovisioning.terms.TermsActivity;
48 import com.android.managedprovisioning.provisioning.AdminIntegratedFlowPrepareActivity;
49 import com.android.managedprovisioning.provisioning.FinancedDeviceLandingActivity;
50 import com.android.managedprovisioning.provisioning.LandingActivity;
51 import com.android.managedprovisioning.provisioning.ProvisioningActivity;
52 import com.android.managedprovisioning.provisioning.ResetAndReturnDeviceActivity;
53 import com.android.managedprovisioning.provisioning.ResetDeviceActivity;
54 
55 import java.util.HashMap;
56 import java.util.Map;
57 
58 /**
59  * A manager for the mapping between {@link ManagedProvisioningScreens} and {@link Activity}.
60  *
61  * <p>By default, all {@link ManagedProvisioningScreens} map to the base {@code ManagedProvisioning}
62  * screens. {@code ManagedProvisioning} inheritors can call {@link
63  * #setOverrideActivity(ManagedProvisioningScreens, Class)} if they want the screens to map to
64  * their own {@link Activity} implementations.
65  */
66 public final class ScreenManager {
67     static final Map<ManagedProvisioningScreens, Class<? extends Activity>>
68             DEFAULT_SCREEN_TO_ACTIVITY_MAP = createBaseScreenMap();
69 
70     private final Map<ManagedProvisioningScreens, Class<? extends Activity>> mScreenToActivityMap;
71 
ScreenManager(Map<ManagedProvisioningScreens, Class<? extends Activity>> screenToActivityMap)72     ScreenManager(Map<ManagedProvisioningScreens, Class<? extends Activity>> screenToActivityMap) {
73         mScreenToActivityMap = new HashMap<>(screenToActivityMap);
74         validateEachScreenHasMapping();
75     }
76 
77     /**
78      * Maps the provided {@code screen} to the provided {@code activityClass}.
79      *
80      * <p>When ManagedProvisioning wants to launch any of the screens in {@link
81      * ManagedProvisioningScreens}, instead of its base {@link Activity} implementation, it will
82      * launch the class provided here.
83      */
setOverrideActivity(ManagedProvisioningScreens screen, Class<? extends Activity> newClass)84     public void setOverrideActivity(ManagedProvisioningScreens screen,
85             Class<? extends Activity> newClass) {
86         mScreenToActivityMap.put(screen, newClass);
87     }
88 
89     /**
90      * Retrieves the {@link Activity} class associated with the provided {@code screen}.
91      *
92      * <p>If no screens were set via {@link #setOverrideActivity(ManagedProvisioningScreens,
93      * Class)}, the base ManagedProvisioning {@link Activity} implementation will be returned.
94      */
getActivityClassForScreen(ManagedProvisioningScreens screen)95     public Class<? extends Activity> getActivityClassForScreen(ManagedProvisioningScreens screen) {
96         return mScreenToActivityMap.get(screen);
97     }
98 
99     private static Map<ManagedProvisioningScreens, Class<? extends Activity>>
createBaseScreenMap()100             createBaseScreenMap() {
101         Map<ManagedProvisioningScreens, Class<? extends Activity>> map =
102                 new HashMap<>(ManagedProvisioningScreens.values().length);
103         map.put(LANDING, LandingActivity.class);
104         map.put(PRE_PROVISIONING, PreProvisioningActivity.class);
105         map.put(PRE_PROVISIONING_VIA_NFC, PreProvisioningActivityViaNfc.class);
106         map.put(PROVISIONING, ProvisioningActivity.class);
107         map.put(ADMIN_INTEGRATED_PREPARE, AdminIntegratedFlowPrepareActivity.class);
108         map.put(RESET_AND_RETURN_DEVICE, ResetAndReturnDeviceActivity.class);
109         map.put(RESET_DEVICE, ResetDeviceActivity.class);
110         map.put(WEB, WebActivity.class);
111         map.put(ENCRYPT, EncryptDeviceActivity.class);
112         map.put(POST_ENCRYPT, PostEncryptionActivity.class);
113         map.put(FINALIZATION_INSIDE_SUW, FinalizationInsideSuwActivity.class);
114         map.put(TERMS, TermsActivity.class);
115         map.put(FINANCED_DEVICE_LANDING, FinancedDeviceLandingActivity.class);
116         map.put(RETRY_LAUNCH, RetryLaunchActivity.class);
117         map.put(DOWNLOAD_ROLE_HOLDER, DownloadRoleHolderActivity.class);
118         map.put(ESTABLISH_NETWORK_CONNECTION, EstablishNetworkConnectionActivity.class);
119         return map;
120     }
121 
122     /**
123      * Makes sure that each entry in {@link ManagedProvisioningScreens} has a corresponding entry
124      * in the map.
125      */
validateEachScreenHasMapping()126     private void validateEachScreenHasMapping() {
127         for (ManagedProvisioningScreens screen : ManagedProvisioningScreens.values()) {
128             if (!mScreenToActivityMap.containsKey(screen)) {
129                 throw new IllegalStateException("Screen " + screen + " has no mapping.");
130             }
131         }
132     }
133 }
134