1 /* 2 * Copyright 2019, 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.provisioning; 18 19 import static android.stats.devicepolicy.DevicePolicyEnums.PROVISIONING_PREPARE_TOTAL_TIME_MS; 20 import static com.android.internal.util.Preconditions.checkNotNull; 21 import static com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker.CANCELLED_DURING_PROVISIONING_PREPARE; 22 23 import static java.util.Objects.requireNonNull; 24 25 import android.content.Context; 26 import android.os.UserHandle; 27 28 import com.android.internal.annotations.GuardedBy; 29 import com.android.internal.annotations.VisibleForTesting; 30 import com.android.managedprovisioning.analytics.MetricsWriterFactory; 31 import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker; 32 import com.android.managedprovisioning.analytics.TimeLogger; 33 import com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences; 34 import com.android.managedprovisioning.common.ProvisionLogger; 35 import com.android.managedprovisioning.common.SettingsFacade; 36 import com.android.managedprovisioning.common.Utils; 37 import com.android.managedprovisioning.model.ProvisioningParams; 38 39 import com.google.android.setupcompat.logging.ScreenKey; 40 import com.google.android.setupcompat.logging.SetupMetric; 41 import com.google.android.setupcompat.logging.SetupMetricsLogger; 42 43 import java.util.Objects; 44 45 /** 46 * Singleton instance that provides communications between the ongoing admin integrated flow 47 * preparing process and the UI layer. 48 */ 49 // TODO(b/123288153): Rearrange provisioning activity, manager, controller classes. 50 class AdminIntegratedFlowPrepareManager implements ProvisioningControllerCallback, 51 ProvisioningManagerInterface { 52 53 private static AdminIntegratedFlowPrepareManager sInstance; 54 55 private final Context mContext; 56 private final ProvisioningManagerHelper mHelper; 57 private final ProvisioningAnalyticsTracker mProvisioningAnalyticsTracker; 58 private final TimeLogger mTimeLogger; 59 private final Utils mUtils; 60 private final SettingsFacade mSettingsFacade; 61 private final ScreenKey mScreenKey; 62 private static String setupMetricScreenName = "AdminIntegratedProvisioningScreen"; 63 private static String setupMetricProvisioningStartedName = "AdminIntegratedProvisioningStarted"; 64 private static String setupMetricProvisioningEndedName = "AdminIntegratedProvisioningEnded"; 65 66 @GuardedBy("this") 67 private AbstractProvisioningController mController; 68 getInstance(Context context)69 static AdminIntegratedFlowPrepareManager getInstance(Context context) { 70 if (sInstance == null) { 71 sInstance = new AdminIntegratedFlowPrepareManager(context.getApplicationContext()); 72 } 73 return sInstance; 74 } 75 AdminIntegratedFlowPrepareManager(Context context)76 private AdminIntegratedFlowPrepareManager(Context context) { 77 this( 78 context, 79 new ProvisioningManagerHelper(), 80 new ProvisioningAnalyticsTracker( 81 MetricsWriterFactory.getMetricsWriter(context, new SettingsFacade()), 82 new ManagedProvisioningSharedPreferences(context)), 83 new TimeLogger(context, PROVISIONING_PREPARE_TOTAL_TIME_MS), 84 new Utils(), 85 new SettingsFacade()); 86 } 87 88 @VisibleForTesting AdminIntegratedFlowPrepareManager( Context context, ProvisioningManagerHelper helper, ProvisioningAnalyticsTracker analyticsTracker, TimeLogger timeLogger, Utils utils, SettingsFacade settingsFacade)89 AdminIntegratedFlowPrepareManager( 90 Context context, 91 ProvisioningManagerHelper helper, 92 ProvisioningAnalyticsTracker analyticsTracker, 93 TimeLogger timeLogger, 94 Utils utils, 95 SettingsFacade settingsFacade) { 96 mContext = requireNonNull(context); 97 mHelper = requireNonNull(helper); 98 mProvisioningAnalyticsTracker = requireNonNull(analyticsTracker); 99 mTimeLogger = requireNonNull(timeLogger); 100 mUtils = requireNonNull(utils); 101 mSettingsFacade = requireNonNull(settingsFacade); 102 mScreenKey = ScreenKey.of(setupMetricScreenName, context); 103 } 104 105 @Override maybeStartProvisioning(ProvisioningParams params)106 public void maybeStartProvisioning(ProvisioningParams params) { 107 synchronized (this) { 108 if (mController == null) { 109 mController = getController(params); 110 mHelper.startNewProvisioningLocked(mController); 111 112 SetupMetricsLogger.logMetrics(mContext, mScreenKey, 113 SetupMetric.ofWaitingStart(setupMetricProvisioningStartedName)); 114 mTimeLogger.start(); 115 116 mProvisioningAnalyticsTracker.logProvisioningPrepareStarted(); 117 } else { 118 ProvisionLogger.loge("Trying to start admin integrated flow preparing, " 119 + "but it's already running"); 120 } 121 } 122 } 123 124 @Override registerListener(ProvisioningManagerCallback callback)125 public void registerListener(ProvisioningManagerCallback callback) { 126 mHelper.registerListener(callback); 127 } 128 129 @Override unregisterListener(ProvisioningManagerCallback callback)130 public void unregisterListener(ProvisioningManagerCallback callback) { 131 mHelper.unregisterListener(callback); 132 } 133 134 @Override cancelProvisioning()135 public void cancelProvisioning() { 136 final boolean prepareCancelled = mHelper.cancelProvisioning(mController); 137 if (prepareCancelled) { 138 mProvisioningAnalyticsTracker.logProvisioningCancelled(mContext, 139 CANCELLED_DURING_PROVISIONING_PREPARE); 140 } 141 } 142 143 @Override provisioningTasksCompleted()144 public void provisioningTasksCompleted() { 145 mTimeLogger.stop(); 146 preFinalizationCompleted(); 147 } 148 149 @Override preFinalizationCompleted()150 public void preFinalizationCompleted() { 151 synchronized (this) { 152 mHelper.notifyPreFinalizationCompleted(); 153 mProvisioningAnalyticsTracker.logProvisioningPrepareCompleted(); 154 clearControllerLocked(); 155 ProvisionLogger.logi("AdminIntegratedFlowPrepareManager pre-finalization completed"); 156 SetupMetricsLogger.logMetrics(mContext, mScreenKey, 157 SetupMetric.ofWaitingEnd(setupMetricProvisioningEndedName)); 158 } 159 } 160 161 @Override cleanUpCompleted()162 public void cleanUpCompleted() { 163 synchronized (this) { 164 clearControllerLocked(); 165 } 166 } 167 168 @Override error(int titleId, int messageId, boolean factoryResetRequired)169 public void error(int titleId, int messageId, boolean factoryResetRequired) { 170 mHelper.error(titleId, messageId, factoryResetRequired); 171 } 172 173 @Override error(int titleId, String message, boolean factoryResetRequired)174 public void error(int titleId, String message, boolean factoryResetRequired) { 175 mHelper.error(titleId, message, factoryResetRequired); 176 } 177 getController(ProvisioningParams params)178 private AbstractProvisioningController getController(ProvisioningParams params) { 179 return AdminIntegratedFlowPrepareController.createInstance( 180 mContext, 181 params, 182 UserHandle.myUserId(), 183 this, 184 mUtils, 185 mSettingsFacade); 186 } 187 clearControllerLocked()188 private void clearControllerLocked() { 189 mController = null; 190 mHelper.clearResourcesLocked(); 191 } 192 } 193