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