ProvisioningActivity.java revision 80ae370242ebd15119d1a6e9e5026e036bfe1cf7
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
17package com.android.managedprovisioning.provisioning;
18
19import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PROVISIONING_PROVISIONING_ACTIVITY_TIME_MS;
20
21import android.app.Activity;
22import android.app.DialogFragment;
23import android.os.Bundle;
24import android.support.annotation.VisibleForTesting;
25import android.view.accessibility.AccessibilityEvent;
26import android.widget.TextView;
27
28import com.android.managedprovisioning.R;
29import com.android.managedprovisioning.common.DialogBuilder;
30import com.android.managedprovisioning.common.SetupGlifLayoutActivity;
31import com.android.managedprovisioning.common.SimpleDialog;
32import com.android.managedprovisioning.common.Utils;
33import com.android.managedprovisioning.model.ProvisioningParams;
34
35/**
36 * Progress activity shown whilst provisioning is ongoing.
37 *
38 * <p>This activity registers for updates of the provisioning process from the
39 * {@link ProvisioningManager}. It shows progress updates as provisioning progresses and handles
40 * showing of cancel and error dialogs.</p>
41 */
42public class ProvisioningActivity extends SetupGlifLayoutActivity
43        implements SimpleDialog.SimpleDialogListener, ProvisioningManagerCallback {
44
45    private static final String KEY_PROVISIONING_STARTED = "ProvisioningStarted";
46
47    private static final String ERROR_DIALOG_OK = "ErrorDialogOk";
48    private static final String ERROR_DIALOG_RESET = "ErrorDialogReset";
49    private static final String CANCEL_PROVISIONING_DIALOG_OK = "CancelProvisioningDialogOk";
50    private static final String CANCEL_PROVISIONING_DIALOG_RESET = "CancelProvisioningDialogReset";
51
52    private TextView mProgressTextView;
53    private ProvisioningParams mParams;
54    private ProvisioningManager mProvisioningManager;
55
56    public ProvisioningActivity() {
57        this(null, new Utils());
58    }
59
60    @VisibleForTesting
61    public ProvisioningActivity(ProvisioningManager provisioningManager, Utils utils) {
62        super(utils);
63        mProvisioningManager = provisioningManager;
64    }
65
66    // Lazily initialize ProvisioningManager, since we can't call in ProvisioningManager.getInstance
67    // in constructor as base context is not available in constructor
68    private ProvisioningManager getProvisioningManager() {
69        if (mProvisioningManager == null) {
70            mProvisioningManager = ProvisioningManager.getInstance(this);
71        }
72        return mProvisioningManager;
73    }
74
75    @Override
76    protected void onCreate(Bundle savedInstanceState) {
77        super.onCreate(savedInstanceState);
78        mParams = getIntent().getParcelableExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS);
79        initializeUi(mParams);
80        mProgressTextView = (TextView) findViewById(R.id.prog_text);
81
82        if (savedInstanceState == null
83                || !savedInstanceState.getBoolean(KEY_PROVISIONING_STARTED)) {
84            getProvisioningManager().maybeStartProvisioning(mParams);
85        }
86    }
87
88    @Override
89    protected void onSaveInstanceState(Bundle outState) {
90        super.onSaveInstanceState(outState);
91        outState.putBoolean(KEY_PROVISIONING_STARTED, true);
92    }
93
94    @Override
95    protected void onResume() {
96        super.onResume();
97        if (!isAnyDialogAdded()) {
98            getProvisioningManager().registerListener(this);
99        }
100    }
101
102    private boolean isAnyDialogAdded() {
103        return isDialogAdded(ERROR_DIALOG_OK)
104                || isDialogAdded(ERROR_DIALOG_RESET)
105                || isDialogAdded(CANCEL_PROVISIONING_DIALOG_OK)
106                || isDialogAdded(CANCEL_PROVISIONING_DIALOG_RESET);
107    }
108
109    @Override
110    public void onPause() {
111        getProvisioningManager().unregisterListener(this);
112        super.onPause();
113    }
114
115    @Override
116    public void onBackPressed() {
117        // if EXTRA_PROVISIONING_SKIP_USER_CONSENT is specified, don't allow user to cancel
118        if (mParams.skipUserConsent) {
119            return;
120        }
121
122        showCancelProvisioningDialog();
123    }
124
125    @Override
126    public void preFinalizationCompleted() {
127        setResult(Activity.RESULT_OK);
128        finish();
129    }
130
131    @Override
132    public void provisioningTasksCompleted() {
133        getProvisioningManager().preFinalize();
134    }
135
136    @Override
137    public void progressUpdate(int progressMessage) {
138        mProgressTextView.setText(progressMessage);
139        mProgressTextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
140    }
141
142    @Override
143    public void error(int dialogMessage, boolean resetRequired) {
144        SimpleDialog.Builder dialogBuilder = new SimpleDialog.Builder()
145                .setTitle(R.string.provisioning_error_title)
146                .setMessage(dialogMessage)
147                .setCancelable(false)
148                .setPositiveButtonMessage(resetRequired
149                        ? R.string.device_owner_error_reset : R.string.device_owner_error_ok);
150
151        showDialog(dialogBuilder, resetRequired ? ERROR_DIALOG_RESET : ERROR_DIALOG_OK);
152    }
153
154    @Override
155    protected void showDialog(DialogBuilder builder, String tag) {
156        // Whenever a dialog is shown, stop listening for further updates
157        getProvisioningManager().unregisterListener(this);
158        super.showDialog(builder, tag);
159    }
160
161    @Override
162    protected int getMetricsCategory() {
163        return PROVISIONING_PROVISIONING_ACTIVITY_TIME_MS;
164    }
165
166    private void showCancelProvisioningDialog() {
167        final boolean isDoProvisioning = getUtils().isDeviceOwnerAction(mParams.provisioningAction);
168        final String dialogTag = isDoProvisioning ? CANCEL_PROVISIONING_DIALOG_RESET
169                : CANCEL_PROVISIONING_DIALOG_OK;
170        final int positiveResId = isDoProvisioning ? R.string.device_owner_error_reset
171                : R.string.profile_owner_cancel_ok;
172        final int negativeResId = isDoProvisioning ? R.string.device_owner_cancel_cancel
173                : R.string.profile_owner_cancel_cancel;
174        final int dialogMsgResId = isDoProvisioning ? R.string.device_owner_cancel_message
175                : R.string.profile_owner_cancel_message;
176
177        SimpleDialog.Builder dialogBuilder = new SimpleDialog.Builder()
178                .setCancelable(false)
179                .setMessage(dialogMsgResId)
180                .setNegativeButtonMessage(negativeResId)
181                .setPositiveButtonMessage(positiveResId);
182
183        showDialog(dialogBuilder, dialogTag);
184    }
185
186    private void onProvisioningAborted() {
187        setResult(Activity.RESULT_CANCELED);
188        finish();
189    }
190
191    @Override
192    public void onNegativeButtonClick(DialogFragment dialog) {
193        switch (dialog.getTag()) {
194            case CANCEL_PROVISIONING_DIALOG_OK:
195            case CANCEL_PROVISIONING_DIALOG_RESET:
196                dialog.dismiss();
197                break;
198            default:
199                SimpleDialog.throwButtonClickHandlerNotImplemented(dialog);
200        }
201        getProvisioningManager().registerListener(this);
202    }
203
204    @Override
205    public void onPositiveButtonClick(DialogFragment dialog) {
206        switch (dialog.getTag()) {
207            case CANCEL_PROVISIONING_DIALOG_OK:
208                getProvisioningManager().cancelProvisioning();
209                onProvisioningAborted();
210                break;
211            case CANCEL_PROVISIONING_DIALOG_RESET:
212                getUtils().sendFactoryResetBroadcast(this, "DO provisioning cancelled by user");
213                onProvisioningAborted();
214                break;
215            case ERROR_DIALOG_OK:
216                onProvisioningAborted();
217                break;
218            case ERROR_DIALOG_RESET:
219                getUtils().sendFactoryResetBroadcast(this, "Error during DO provisioning");
220                onProvisioningAborted();
221                break;
222            default:
223                SimpleDialog.throwButtonClickHandlerNotImplemented(dialog);
224        }
225    }
226
227    private void initializeUi(ProvisioningParams params) {
228        final boolean isDoProvisioning = getUtils().isDeviceOwnerAction(params.provisioningAction);
229        final int headerResId = isDoProvisioning ? R.string.setup_work_device
230                : R.string.setting_up_workspace;
231        final int titleResId = isDoProvisioning ? R.string.setup_device_progress
232                : R.string.setup_profile_progress;
233
234        initializeLayoutParams(R.layout.progress, headerResId, true);
235        setTitle(titleResId);
236        maybeSetLogoAndMainColor(params.mainColor);
237    }
238}
239