• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.annotation.IntDef;
20 import android.app.Activity;
21 import android.app.DialogFragment;
22 import android.os.Bundle;
23 
24 import androidx.annotation.VisibleForTesting;
25 
26 import com.android.managedprovisioning.R;
27 import com.android.managedprovisioning.common.DialogBuilder;
28 import com.android.managedprovisioning.common.SettingsFacade;
29 import com.android.managedprovisioning.common.SetupGlifLayoutActivity;
30 import com.android.managedprovisioning.common.SimpleDialog;
31 import com.android.managedprovisioning.common.ThemeHelper;
32 import com.android.managedprovisioning.common.Utils;
33 import com.android.managedprovisioning.model.ProvisioningParams;
34 
35 import java.lang.annotation.Retention;
36 import java.lang.annotation.RetentionPolicy;
37 
38 /**
39  * Abstract class for provisioning activity.
40  *
41  * <p>This activity registers for updates of the provisioning process from the
42  * {@link ProvisioningManager}. It shows progress updates as provisioning progresses and handles
43  * showing of cancel and error dialogs.</p>
44  */
45 // TODO(b/123288153): Rearrange provisioning activity, manager, controller classes.
46 public abstract class AbstractProvisioningActivity extends SetupGlifLayoutActivity
47         implements SimpleDialog.SimpleDialogListener, ProvisioningManagerCallback {
48 
49     private static final String KEY_ACTIVITY_STATE = "activity-state";
50 
51     static final int STATE_PROVISIONING_INTIIALIZING = 1;
52     static final int STATE_PROVISIONING_STARTED = 2;
53     static final int STATE_PROVISIONING_COMPLETED = 3;
54     static final int STATE_PROVISIONING_FINALIZED = 4;
55 
56     @Retention(RetentionPolicy.SOURCE)
57     @IntDef({STATE_PROVISIONING_INTIIALIZING,
58             STATE_PROVISIONING_STARTED,
59             STATE_PROVISIONING_COMPLETED,
60             STATE_PROVISIONING_FINALIZED})
61     private @interface ProvisioningState {}
62 
63     @VisibleForTesting static final String ERROR_DIALOG_OK = "ErrorDialogOk";
64     @VisibleForTesting static final String ERROR_DIALOG_RESET = "ErrorDialogReset";
65     @VisibleForTesting static final String CANCEL_PROVISIONING_DIALOG_OK
66             = "CancelProvisioningDialogOk";
67     @VisibleForTesting static final String CANCEL_PROVISIONING_DIALOG_RESET
68             = "CancelProvisioningDialogReset";
69 
70     protected ProvisioningParams mParams;
71     protected @ProvisioningState int mState;
72 
73     @VisibleForTesting
AbstractProvisioningActivity( Utils utils, SettingsFacade settingsFacade, ThemeHelper themeHelper)74     protected AbstractProvisioningActivity(
75             Utils utils, SettingsFacade settingsFacade, ThemeHelper themeHelper) {
76         super(utils, settingsFacade, themeHelper);
77     }
78 
79     // Lazily initialize ProvisioningManager, since we can't call in ProvisioningManager.getInstance
80     // in constructor as base context is not available in constructor.
getProvisioningManager()81     protected abstract ProvisioningManagerInterface getProvisioningManager();
82     // Show the dialog when user press back button while provisioning.
decideCancelProvisioningDialog()83     protected abstract void decideCancelProvisioningDialog();
84 
85     @Override
onCreate(Bundle savedInstanceState)86     protected void onCreate(Bundle savedInstanceState) {
87         // initialize params so they're accessible for prechecks in onCreate
88         mParams = getIntent().getParcelableExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS);
89         super.onCreate(savedInstanceState);
90 
91         if (savedInstanceState != null) {
92             mState = savedInstanceState.getInt(KEY_ACTIVITY_STATE,
93                     STATE_PROVISIONING_INTIIALIZING);
94         } else {
95             mState = STATE_PROVISIONING_INTIIALIZING;
96         }
97 
98         if (mState == STATE_PROVISIONING_INTIIALIZING) {
99             getProvisioningManager().maybeStartProvisioning(mParams);
100             mState = STATE_PROVISIONING_STARTED;
101         }
102     }
103 
104     @Override
onSaveInstanceState(Bundle outState)105     protected void onSaveInstanceState(Bundle outState) {
106         super.onSaveInstanceState(outState);
107         outState.putInt(KEY_ACTIVITY_STATE, mState);
108     }
109 
110     @Override
onResume()111     protected void onResume() {
112         super.onResume();
113         if (!isAnyDialogAdded()) {
114             getProvisioningManager().registerListener(this);
115         }
116     }
117 
isAnyDialogAdded()118     private boolean isAnyDialogAdded() {
119         return isDialogAdded(ERROR_DIALOG_OK)
120                 || isDialogAdded(ERROR_DIALOG_RESET)
121                 || isDialogAdded(CANCEL_PROVISIONING_DIALOG_OK)
122                 || isDialogAdded(CANCEL_PROVISIONING_DIALOG_RESET);
123     }
124 
125     @Override
onPause()126     public void onPause() {
127         getProvisioningManager().unregisterListener(this);
128         super.onPause();
129     }
130 
131     @Override
onBackPressed()132     public void onBackPressed() {
133         decideCancelProvisioningDialog();
134     }
135 
showCancelProvisioningDialog(boolean resetRequired)136     protected void showCancelProvisioningDialog(boolean resetRequired) {
137         if (resetRequired) {
138             showDialog(mUtils.createCancelProvisioningResetDialogBuilder(),
139                     CANCEL_PROVISIONING_DIALOG_RESET);
140         } else {
141             showDialog(mUtils.createCancelProvisioningDialogBuilder(),
142                    CANCEL_PROVISIONING_DIALOG_OK);
143         }
144     }
145 
146     @Override
error(int titleId, int messageId, boolean resetRequired)147     public void error(int titleId, int messageId, boolean resetRequired) {
148         SimpleDialog.Builder dialogBuilder = new SimpleDialog.Builder()
149                 .setTitle(titleId)
150                 .setMessage(messageId)
151                 .setCancelable(false)
152                 .setPositiveButtonMessage(resetRequired
153                         ? R.string.reset : android.R.string.ok);
154 
155         showDialog(dialogBuilder, resetRequired ? ERROR_DIALOG_RESET : ERROR_DIALOG_OK);
156     }
157 
158     @Override
showDialog(DialogBuilder builder, String tag)159     protected void showDialog(DialogBuilder builder, String tag) {
160         // Whenever a dialog is shown, stop listening for further updates
161         getProvisioningManager().unregisterListener(this);
162         super.showDialog(builder, tag);
163     }
164 
onProvisioningAborted()165     private void onProvisioningAborted() {
166         setResult(Activity.RESULT_CANCELED);
167         getTransitionHelper().finishActivity(this);
168     }
169 
170     @Override
onNegativeButtonClick(DialogFragment dialog)171     public void onNegativeButtonClick(DialogFragment dialog) {
172         switch (dialog.getTag()) {
173             case CANCEL_PROVISIONING_DIALOG_OK:
174             case CANCEL_PROVISIONING_DIALOG_RESET:
175                 dialog.dismiss();
176                 break;
177             default:
178                 SimpleDialog.throwButtonClickHandlerNotImplemented(dialog);
179         }
180         getProvisioningManager().registerListener(this);
181     }
182 
183     @Override
onPositiveButtonClick(DialogFragment dialog)184     public void onPositiveButtonClick(DialogFragment dialog) {
185         switch (dialog.getTag()) {
186             case CANCEL_PROVISIONING_DIALOG_OK:
187                 getProvisioningManager().cancelProvisioning();
188                 onProvisioningAborted();
189                 break;
190             case CANCEL_PROVISIONING_DIALOG_RESET:
191                 getUtils().factoryReset(this, "Provisioning cancelled by user");
192                 onProvisioningAborted();
193                 break;
194             case ERROR_DIALOG_OK:
195                 onProvisioningAborted();
196                 break;
197             case ERROR_DIALOG_RESET:
198                 getUtils().factoryReset(this, "Error during provisioning");
199                 onProvisioningAborted();
200                 break;
201             default:
202                 SimpleDialog.throwButtonClickHandlerNotImplemented(dialog);
203         }
204     }
205 }
206