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