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