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