1 /* 2 * Copyright 2016, 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 com.android.internal.logging.nano.MetricsProto.MetricsEvent.PROVISIONING_TOTAL_TASK_TIME_MS; 20 import static com.android.internal.util.Preconditions.checkNotNull; 21 import static com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker.CANCELLED_DURING_PROVISIONING; 22 23 import android.content.Context; 24 import android.os.Handler; 25 import android.os.Looper; 26 27 import com.android.internal.annotations.GuardedBy; 28 import com.android.internal.annotations.VisibleForTesting; 29 import com.android.managedprovisioning.analytics.MetricsWriterFactory; 30 import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker; 31 import com.android.managedprovisioning.analytics.TimeLogger; 32 import com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences; 33 import com.android.managedprovisioning.common.ProvisionLogger; 34 import com.android.managedprovisioning.common.SettingsFacade; 35 import com.android.managedprovisioning.model.ProvisioningParams; 36 37 /** 38 * Singleton instance that provides communications between the ongoing provisioning process and the 39 * UI layer. 40 */ 41 public class ProvisioningManager implements ProvisioningControllerCallback, 42 ProvisioningManagerInterface { 43 44 private static ProvisioningManager sInstance; 45 46 private final Context mContext; 47 private final ProvisioningControllerFactory mFactory; 48 private final ProvisioningAnalyticsTracker mProvisioningAnalyticsTracker; 49 private final TimeLogger mTimeLogger; 50 private final ProvisioningManagerHelper mHelper; 51 52 @GuardedBy("this") 53 private AbstractProvisioningController mController; 54 getInstance(Context context)55 public static ProvisioningManager getInstance(Context context) { 56 if (sInstance == null) { 57 sInstance = new ProvisioningManager(context.getApplicationContext()); 58 } 59 return sInstance; 60 } 61 ProvisioningManager(Context context)62 private ProvisioningManager(Context context) { 63 this( 64 context, 65 new Handler(Looper.getMainLooper()), 66 new ProvisioningControllerFactory(), 67 new ProvisioningAnalyticsTracker( 68 MetricsWriterFactory.getMetricsWriter(context, new SettingsFacade()), 69 new ManagedProvisioningSharedPreferences(context)), 70 new TimeLogger(context, PROVISIONING_TOTAL_TASK_TIME_MS)); 71 } 72 73 @VisibleForTesting ProvisioningManager( Context context, Handler uiHandler, ProvisioningControllerFactory factory, ProvisioningAnalyticsTracker analyticsTracker, TimeLogger timeLogger)74 ProvisioningManager( 75 Context context, 76 Handler uiHandler, 77 ProvisioningControllerFactory factory, 78 ProvisioningAnalyticsTracker analyticsTracker, 79 TimeLogger timeLogger) { 80 mContext = checkNotNull(context); 81 mFactory = checkNotNull(factory); 82 mProvisioningAnalyticsTracker = checkNotNull(analyticsTracker); 83 mTimeLogger = checkNotNull(timeLogger); 84 mHelper = new ProvisioningManagerHelper(context); 85 } 86 87 @Override maybeStartProvisioning(final ProvisioningParams params)88 public void maybeStartProvisioning(final ProvisioningParams params) { 89 synchronized (this) { 90 if (mController == null) { 91 mTimeLogger.start(); 92 mController = getController(params); 93 mHelper.startNewProvisioningLocked(mController); 94 mProvisioningAnalyticsTracker.logProvisioningStarted(mContext, params); 95 } else { 96 ProvisionLogger.loge("Trying to start provisioning, but it's already running"); 97 } 98 } 99 } 100 101 @Override registerListener(ProvisioningManagerCallback callback)102 public void registerListener(ProvisioningManagerCallback callback) { 103 mHelper.registerListener(callback); 104 } 105 106 @Override unregisterListener(ProvisioningManagerCallback callback)107 public void unregisterListener(ProvisioningManagerCallback callback) { 108 mHelper.unregisterListener(callback); 109 } 110 111 @Override cancelProvisioning()112 public void cancelProvisioning() { 113 synchronized (this) { 114 final boolean provisioningCanceled = mHelper.cancelProvisioning(mController); 115 if (provisioningCanceled) { 116 mProvisioningAnalyticsTracker.logProvisioningCancelled(mContext, 117 CANCELLED_DURING_PROVISIONING); 118 } 119 } 120 } 121 122 @Override provisioningTasksCompleted()123 public void provisioningTasksCompleted() { 124 synchronized (this) { 125 mTimeLogger.stop(); 126 preFinalizationCompleted(); 127 } 128 } 129 130 @Override preFinalizationCompleted()131 public void preFinalizationCompleted() { 132 synchronized (this) { 133 mHelper.notifyPreFinalizationCompleted(); 134 mProvisioningAnalyticsTracker.logProvisioningSessionCompleted(mContext); 135 clearControllerLocked(); 136 ProvisionLogger.logi("ProvisioningManager pre-finalization completed"); 137 } 138 } 139 140 @Override cleanUpCompleted()141 public void cleanUpCompleted() { 142 synchronized (this) { 143 clearControllerLocked(); 144 } 145 } 146 147 @Override error(int titleId, int messageId, boolean factoryResetRequired)148 public void error(int titleId, int messageId, boolean factoryResetRequired) { 149 mHelper.error(titleId, messageId, factoryResetRequired); 150 } 151 getController(ProvisioningParams params)152 private AbstractProvisioningController getController(ProvisioningParams params) { 153 return mFactory.createProvisioningController(mContext, params, this); 154 } 155 clearControllerLocked()156 private void clearControllerLocked() { 157 mController = null; 158 mHelper.clearResourcesLocked(); 159 } 160 } 161