blob: b3df1839e6fe65a521f5dc396d6e38c626da510f [file] [log] [blame]
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001/*
2 * Copyright (C) 2009 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.phone;
18
19import android.app.Activity;
20import android.app.PendingIntent;
Santos Cordon00d7a432013-09-17 14:07:14 -070021import android.content.Context;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070022import android.content.Intent;
Santos Cordon00d7a432013-09-17 14:07:14 -070023import android.content.pm.PackageManager;
24import android.content.pm.ResolveInfo;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070025import android.os.Bundle;
Jonathan Basseric31f1f32015-05-12 10:13:03 -070026import android.os.PersistableBundle;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070027import android.os.SystemProperties;
Santos Cordon00d7a432013-09-17 14:07:14 -070028import android.provider.Settings;
Junda Liu605148f2015-04-28 15:23:40 -070029import android.telephony.CarrierConfigManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070030import android.util.Log;
31
32import com.android.internal.telephony.Phone;
33import com.android.internal.telephony.TelephonyCapabilities;
34
35/**
36 * Invisible activity that handles the com.android.phone.PERFORM_CDMA_PROVISIONING intent.
37 * This activity is protected by the android.permission.PERFORM_CDMA_PROVISIONING permission.
38 *
39 * We handle the PERFORM_CDMA_PROVISIONING action by launching an OTASP
40 * call via one of the OtaUtils helper methods: startInteractiveOtasp() on
41 * regular phones, or startNonInteractiveOtasp() on data-only devices.
42 *
43 * TODO: The class name InCallScreenShowActivation is misleading, since
44 * this activity is totally unrelated to the InCallScreen (which
45 * implements the in-call UI.) Let's eventually rename this to something
46 * like CdmaProvisioningLauncher or CdmaProvisioningHandler...
47 */
48public class InCallScreenShowActivation extends Activity {
49 private static final String LOG_TAG = "InCallScreenShowActivation";
50 private static final boolean DBG =
51 (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
52
53 @Override
54 protected void onCreate(Bundle icicle) {
55 super.onCreate(icicle);
56
57 Intent intent = getIntent();
58 if (DBG) Log.d(LOG_TAG, "onCreate: intent = " + intent);
59 Bundle extras = intent.getExtras();
60 if (DBG && (extras != null)) {
61 Log.d(LOG_TAG, " - has extras: size = " + extras.size()); // forces an unparcel()
62 Log.d(LOG_TAG, " - extras = " + extras);
63 }
64
65 PhoneGlobals app = PhoneGlobals.getInstance();
66 Phone phone = app.getPhone();
67 if (!TelephonyCapabilities.supportsOtasp(phone)) {
68 Log.w(LOG_TAG, "CDMA Provisioning not supported on this device");
69 setResult(RESULT_CANCELED);
70 finish();
71 return;
72 }
73
74 if (intent.getAction().equals(OtaUtils.ACTION_PERFORM_CDMA_PROVISIONING)) {
75
Jonathan Basseric31f1f32015-05-12 10:13:03 -070076 PersistableBundle carrierConfig = app.getCarrierConfig();
Jonathan Basseri9504c6b2015-06-04 14:23:32 -070077 boolean usesHfa = carrierConfig.getBoolean(
78 CarrierConfigManager.KEY_USE_HFA_FOR_PROVISIONING_BOOL);
Santos Cordon83570472013-09-06 15:45:10 -070079 if (usesHfa) {
Santos Cordonb2bfd3c2014-10-08 15:12:41 -070080 Log.i(LOG_TAG, "Starting Hfa from ACTION_PERFORM_CDMA_PROVISIONING");
Santos Cordon83570472013-09-06 15:45:10 -070081 startHfa();
82 finish();
83 return;
84 }
85
Jonathan Basseri9504c6b2015-06-04 14:23:32 -070086 boolean usesOtasp = carrierConfig.getBoolean(
87 CarrierConfigManager.KEY_USE_OTASP_FOR_PROVISIONING_BOOL);
Santos Cordonb2bfd3c2014-10-08 15:12:41 -070088 if (usesOtasp) {
89 // On voice-capable devices, we perform CDMA provisioning in
90 // "interactive" mode by directly launching the InCallScreen.
91 // boolean interactiveMode = PhoneGlobals.sVoiceCapable;
92 // TODO: Renable interactive mode for device provisioning.
93 boolean interactiveMode = false;
94 Log.i(LOG_TAG, "ACTION_PERFORM_CDMA_PROVISIONING (interactiveMode = "
95 + interactiveMode + ")...");
Santos Cordon7d4ddf62013-07-10 11:58:08 -070096
Santos Cordonb2bfd3c2014-10-08 15:12:41 -070097 // Testing: this intent extra allows test apps manually
98 // enable/disable "interactive mode", regardless of whether
99 // the current device is voice-capable. This is allowed only
100 // in userdebug or eng builds.
101 if (intent.hasExtra(OtaUtils.EXTRA_OVERRIDE_INTERACTIVE_MODE)
102 && (SystemProperties.getInt("ro.debuggable", 0) == 1)) {
103 interactiveMode =
104 intent.getBooleanExtra(OtaUtils.EXTRA_OVERRIDE_INTERACTIVE_MODE, false);
105 Log.d(LOG_TAG, "==> MANUALLY OVERRIDING interactiveMode to " + interactiveMode);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700106 }
Santos Cordonb2bfd3c2014-10-08 15:12:41 -0700107
108 // We allow the caller to pass a PendingIntent (as the
109 // EXTRA_NONINTERACTIVE_OTASP_RESULT_PENDING_INTENT extra)
110 // which we'll later use to notify them when the OTASP call
111 // fails or succeeds.
112 //
113 // Stash that away here, and we'll fire it off later in
114 // OtaUtils.sendOtaspResult().
115 app.cdmaOtaScreenState.otaspResultCodePendingIntent =
116 (PendingIntent) intent.getParcelableExtra(
117 OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
118
119 if (interactiveMode) {
120 // On voice-capable devices, launch an OTASP call and arrange
121 // for the in-call UI to come up. (The InCallScreen will
122 // notice that an OTASP call is active, and display the
123 // special OTASP UI instead of the usual in-call controls.)
124
125 if (DBG) Log.d(LOG_TAG, "==> Starting interactive CDMA provisioning...");
126 OtaUtils.startInteractiveOtasp(this);
127
128 // The result we set here is actually irrelevant, since the
129 // InCallScreen's "interactive" OTASP sequence never actually
130 // finish()es; it ends by directly launching the Home
131 // activity. So our caller won't actually ever get an
132 // onActivityResult() call in this case.
133 setResult(OtaUtils.RESULT_INTERACTIVE_OTASP_STARTED);
134 } else {
135 // On data-only devices, manually launch the OTASP call
136 // *without* displaying any UI. (Our caller, presumably
137 // SetupWizardActivity, is responsible for displaying some
138 // sort of progress UI.)
139
140 if (DBG) Log.d(LOG_TAG, "==> Starting non-interactive CDMA provisioning...");
141 int callStatus = OtaUtils.startNonInteractiveOtasp(this);
142
143 if (callStatus == PhoneUtils.CALL_STATUS_DIALED) {
144 if (DBG) Log.d(LOG_TAG,
145 " ==> successful result from startNonInteractiveOtasp(): " +
146 callStatus);
147 setResult(OtaUtils.RESULT_NONINTERACTIVE_OTASP_STARTED);
148 } else {
149 Log.w(LOG_TAG, "Failure code from startNonInteractiveOtasp(): " +
150 callStatus);
151 setResult(OtaUtils.RESULT_NONINTERACTIVE_OTASP_FAILED);
152 }
153 }
154 } else {
155 Log.i(LOG_TAG, "Skipping activation.");
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700156 }
157 } else {
158 Log.e(LOG_TAG, "Unexpected intent action: " + intent);
159 setResult(RESULT_CANCELED);
160 }
161
162 finish();
163 }
Santos Cordon83570472013-09-06 15:45:10 -0700164
Santos Cordon00d7a432013-09-17 14:07:14 -0700165 /**
166 * On devices that provide a phone initialization wizard (such as Google Setup Wizard),
167 * the wizard displays it's own activation UI. The Hfa activation started by this class
168 * will show a UI or not depending on the status of the setup wizard. If the setup wizard
169 * is running, do not show a UI, otherwise show our own UI since setup wizard will not.
170 *
171 * The method checks two properties:
172 * 1. Does the device require a setup wizard (ro.setupwizard.mode == (REQUIRED|OPTIONAL))
173 * 2. Is device_provisioned set to non-zero--a property that setup wizard sets at completion.
174 * @return true if wizard is running, false otherwise.
175 */
176 private boolean isWizardRunning(Context context) {
177 Intent intent = new Intent("android.intent.action.DEVICE_INITIALIZATION_WIZARD");
178 ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent,
179 PackageManager.MATCH_DEFAULT_ONLY);
180 boolean provisioned = Settings.Global.getInt(context.getContentResolver(),
181 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
182 String mode = SystemProperties.get("ro.setupwizard.mode", "REQUIRED");
183 boolean runningSetupWizard = "REQUIRED".equals(mode) || "OPTIONAL".equals(mode);
184 if (DBG) {
185 Log.v(LOG_TAG, "resolvInfo = " + resolveInfo + ", provisioned = " + provisioned
186 + ", runningSetupWizard = " + runningSetupWizard);
187 }
188 return resolveInfo != null && !provisioned && runningSetupWizard;
189 }
Santos Cordon83570472013-09-06 15:45:10 -0700190
191 /**
192 * Starts the HFA provisioning process by bringing up the HFA Activity.
193 */
194 private void startHfa() {
Santos Cordon06cc4482014-10-08 12:12:15 -0700195 boolean isWizardRunning = isWizardRunning(this);
196 // We always run our HFA logic if we're in setup wizard, but if we're outside of setup
197 // wizard then we have to check a config to see if we should still run HFA.
198 if (isWizardRunning ||
199 getResources().getBoolean(R.bool.config_allow_hfa_outside_of_setup_wizard)) {
Santos Cordon83570472013-09-06 15:45:10 -0700200
Santos Cordon06cc4482014-10-08 12:12:15 -0700201 final Intent intent = new Intent();
Santos Cordon83570472013-09-06 15:45:10 -0700202
Santos Cordon06cc4482014-10-08 12:12:15 -0700203 final PendingIntent otaResponseIntent = getIntent().getParcelableExtra(
204 OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
Santos Cordon00d7a432013-09-17 14:07:14 -0700205
Santos Cordon06cc4482014-10-08 12:12:15 -0700206 final boolean showUi = !isWizardRunning;
207 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Santos Cordon00d7a432013-09-17 14:07:14 -0700208
Santos Cordon06cc4482014-10-08 12:12:15 -0700209 if (otaResponseIntent != null) {
210 intent.putExtra(OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT, otaResponseIntent);
211 }
212
213 Log.v(LOG_TAG, "Starting hfa activation activity");
214 if (showUi) {
215 intent.setClassName(this, HfaActivity.class.getName());
216 startActivity(intent);
217 } else {
218 intent.setClassName(this, HfaService.class.getName());
219 startService(intent);
220 }
221
Santos Cordon00d7a432013-09-17 14:07:14 -0700222 }
Santos Cordon00d7a432013-09-17 14:07:14 -0700223 setResult(RESULT_OK);
Santos Cordon83570472013-09-06 15:45:10 -0700224 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700225}