blob: fd202db5dacd17af33517c71095e8fc45df8683a [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;
26import android.os.SystemProperties;
Santos Cordon00d7a432013-09-17 14:07:14 -070027import android.provider.Settings;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070028import android.util.Log;
29
30import com.android.internal.telephony.Phone;
31import com.android.internal.telephony.TelephonyCapabilities;
32
33/**
34 * Invisible activity that handles the com.android.phone.PERFORM_CDMA_PROVISIONING intent.
35 * This activity is protected by the android.permission.PERFORM_CDMA_PROVISIONING permission.
36 *
37 * We handle the PERFORM_CDMA_PROVISIONING action by launching an OTASP
38 * call via one of the OtaUtils helper methods: startInteractiveOtasp() on
39 * regular phones, or startNonInteractiveOtasp() on data-only devices.
40 *
41 * TODO: The class name InCallScreenShowActivation is misleading, since
42 * this activity is totally unrelated to the InCallScreen (which
43 * implements the in-call UI.) Let's eventually rename this to something
44 * like CdmaProvisioningLauncher or CdmaProvisioningHandler...
45 */
46public class InCallScreenShowActivation extends Activity {
47 private static final String LOG_TAG = "InCallScreenShowActivation";
48 private static final boolean DBG =
49 (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
50
51 @Override
52 protected void onCreate(Bundle icicle) {
53 super.onCreate(icicle);
54
55 Intent intent = getIntent();
56 if (DBG) Log.d(LOG_TAG, "onCreate: intent = " + intent);
57 Bundle extras = intent.getExtras();
58 if (DBG && (extras != null)) {
59 Log.d(LOG_TAG, " - has extras: size = " + extras.size()); // forces an unparcel()
60 Log.d(LOG_TAG, " - extras = " + extras);
61 }
62
63 PhoneGlobals app = PhoneGlobals.getInstance();
64 Phone phone = app.getPhone();
65 if (!TelephonyCapabilities.supportsOtasp(phone)) {
66 Log.w(LOG_TAG, "CDMA Provisioning not supported on this device");
67 setResult(RESULT_CANCELED);
68 finish();
69 return;
70 }
71
72 if (intent.getAction().equals(OtaUtils.ACTION_PERFORM_CDMA_PROVISIONING)) {
73
Santos Cordon83570472013-09-06 15:45:10 -070074 boolean usesHfa = getResources().getBoolean(R.bool.config_use_hfa_for_provisioning);
75 if (usesHfa) {
76 Log.d(LOG_TAG, "Starting Hfa from ACTION_PERFORM_CDMA_PROVISIONING");
77 startHfa();
78 finish();
79 return;
80 }
81
Santos Cordon7d4ddf62013-07-10 11:58:08 -070082 // On voice-capable devices, we perform CDMA provisioning in
83 // "interactive" mode by directly launching the InCallScreen.
Santos Cordonff3127e2013-08-30 15:55:35 -070084 // boolean interactiveMode = PhoneGlobals.sVoiceCapable;
Christine Chen07fae162013-09-19 15:05:56 -070085 // TODO: Renable interactive mode for device provisioning.
Santos Cordonff3127e2013-08-30 15:55:35 -070086 boolean interactiveMode = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070087 Log.d(LOG_TAG, "ACTION_PERFORM_CDMA_PROVISIONING (interactiveMode = "
88 + interactiveMode + ")...");
89
90 // Testing: this intent extra allows test apps manually
91 // enable/disable "interactive mode", regardless of whether
92 // the current device is voice-capable. This is allowed only
93 // in userdebug or eng builds.
94 if (intent.hasExtra(OtaUtils.EXTRA_OVERRIDE_INTERACTIVE_MODE)
95 && (SystemProperties.getInt("ro.debuggable", 0) == 1)) {
96 interactiveMode =
97 intent.getBooleanExtra(OtaUtils.EXTRA_OVERRIDE_INTERACTIVE_MODE, false);
98 Log.d(LOG_TAG, "===> MANUALLY OVERRIDING interactiveMode to " + interactiveMode);
99 }
100
101 // We allow the caller to pass a PendingIntent (as the
102 // EXTRA_NONINTERACTIVE_OTASP_RESULT_PENDING_INTENT extra)
103 // which we'll later use to notify them when the OTASP call
104 // fails or succeeds.
105 //
106 // Stash that away here, and we'll fire it off later in
107 // OtaUtils.sendOtaspResult().
108 app.cdmaOtaScreenState.otaspResultCodePendingIntent =
109 (PendingIntent) intent.getParcelableExtra(
110 OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
111
112 if (interactiveMode) {
113 // On voice-capable devices, launch an OTASP call and arrange
114 // for the in-call UI to come up. (The InCallScreen will
115 // notice that an OTASP call is active, and display the
116 // special OTASP UI instead of the usual in-call controls.)
117
118 if (DBG) Log.d(LOG_TAG, "==> Starting interactive CDMA provisioning...");
119 OtaUtils.startInteractiveOtasp(this);
120
121 // The result we set here is actually irrelevant, since the
122 // InCallScreen's "interactive" OTASP sequence never actually
123 // finish()es; it ends by directly launching the Home
124 // activity. So our caller won't actually ever get an
125 // onActivityResult() call in this case.
126 setResult(OtaUtils.RESULT_INTERACTIVE_OTASP_STARTED);
127 } else {
128 // On data-only devices, manually launch the OTASP call
129 // *without* displaying any UI. (Our caller, presumably
130 // SetupWizardActivity, is responsible for displaying some
131 // sort of progress UI.)
132
133 if (DBG) Log.d(LOG_TAG, "==> Starting non-interactive CDMA provisioning...");
134 int callStatus = OtaUtils.startNonInteractiveOtasp(this);
135
136 if (callStatus == PhoneUtils.CALL_STATUS_DIALED) {
137 if (DBG) Log.d(LOG_TAG, " ==> successful result from startNonInteractiveOtasp(): "
138 + callStatus);
139 setResult(OtaUtils.RESULT_NONINTERACTIVE_OTASP_STARTED);
140 } else {
141 Log.w(LOG_TAG, "Failure code from startNonInteractiveOtasp(): " + callStatus);
142 setResult(OtaUtils.RESULT_NONINTERACTIVE_OTASP_FAILED);
143 }
144 }
145 } else {
146 Log.e(LOG_TAG, "Unexpected intent action: " + intent);
147 setResult(RESULT_CANCELED);
148 }
149
150 finish();
151 }
Santos Cordon83570472013-09-06 15:45:10 -0700152
Santos Cordon00d7a432013-09-17 14:07:14 -0700153 /**
154 * On devices that provide a phone initialization wizard (such as Google Setup Wizard),
155 * the wizard displays it's own activation UI. The Hfa activation started by this class
156 * will show a UI or not depending on the status of the setup wizard. If the setup wizard
157 * is running, do not show a UI, otherwise show our own UI since setup wizard will not.
158 *
159 * The method checks two properties:
160 * 1. Does the device require a setup wizard (ro.setupwizard.mode == (REQUIRED|OPTIONAL))
161 * 2. Is device_provisioned set to non-zero--a property that setup wizard sets at completion.
162 * @return true if wizard is running, false otherwise.
163 */
164 private boolean isWizardRunning(Context context) {
165 Intent intent = new Intent("android.intent.action.DEVICE_INITIALIZATION_WIZARD");
166 ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent,
167 PackageManager.MATCH_DEFAULT_ONLY);
168 boolean provisioned = Settings.Global.getInt(context.getContentResolver(),
169 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
170 String mode = SystemProperties.get("ro.setupwizard.mode", "REQUIRED");
171 boolean runningSetupWizard = "REQUIRED".equals(mode) || "OPTIONAL".equals(mode);
172 if (DBG) {
173 Log.v(LOG_TAG, "resolvInfo = " + resolveInfo + ", provisioned = " + provisioned
174 + ", runningSetupWizard = " + runningSetupWizard);
175 }
176 return resolveInfo != null && !provisioned && runningSetupWizard;
177 }
Santos Cordon83570472013-09-06 15:45:10 -0700178
179 /**
180 * Starts the HFA provisioning process by bringing up the HFA Activity.
181 */
182 private void startHfa() {
Santos Cordon00d7a432013-09-17 14:07:14 -0700183 final Intent intent = new Intent();
Santos Cordon83570472013-09-06 15:45:10 -0700184
185 final PendingIntent otaResponseIntent = getIntent().getParcelableExtra(
186 OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
187
Santos Cordon00d7a432013-09-17 14:07:14 -0700188 final boolean showUi = !isWizardRunning(this);
189
190 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
191
192 if (otaResponseIntent != null) {
193 intent.putExtra(OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT, otaResponseIntent);
194 }
Santos Cordon83570472013-09-06 15:45:10 -0700195
196 Log.v(LOG_TAG, "Starting hfa activation activity");
Santos Cordon00d7a432013-09-17 14:07:14 -0700197 if (showUi) {
198 intent.setClassName(this, HfaActivity.class.getName());
199 startActivity(intent);
200 } else {
201 intent.setClassName(this, HfaService.class.getName());
202 startService(intent);
203 }
204
205 setResult(RESULT_OK);
Santos Cordon83570472013-09-06 15:45:10 -0700206 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700207}