| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 1 | /* | 
 | 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 |  | 
 | 17 | package com.android.phone; | 
 | 18 |  | 
 | 19 | import android.app.Activity; | 
 | 20 | import android.app.PendingIntent; | 
| Santos Cordon | 00d7a43 | 2013-09-17 14:07:14 -0700 | [diff] [blame] | 21 | import android.content.Context; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 22 | import android.content.Intent; | 
| Santos Cordon | 00d7a43 | 2013-09-17 14:07:14 -0700 | [diff] [blame] | 23 | import android.content.pm.PackageManager; | 
 | 24 | import android.content.pm.ResolveInfo; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 25 | import android.os.Bundle; | 
 | 26 | import android.os.SystemProperties; | 
| Santos Cordon | 00d7a43 | 2013-09-17 14:07:14 -0700 | [diff] [blame] | 27 | import android.provider.Settings; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 28 | import android.util.Log; | 
 | 29 |  | 
 | 30 | import com.android.internal.telephony.Phone; | 
 | 31 | import 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 |  */ | 
 | 46 | public 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 Cordon | 8357047 | 2013-09-06 15:45:10 -0700 | [diff] [blame] | 74 |             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 Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 82 |             // On voice-capable devices, we perform CDMA provisioning in | 
 | 83 |             // "interactive" mode by directly launching the InCallScreen. | 
| Santos Cordon | ff3127e | 2013-08-30 15:55:35 -0700 | [diff] [blame] | 84 |             // boolean interactiveMode = PhoneGlobals.sVoiceCapable; | 
| Christine Chen | 07fae16 | 2013-09-19 15:05:56 -0700 | [diff] [blame] | 85 |             // TODO: Renable interactive mode for device provisioning. | 
| Santos Cordon | ff3127e | 2013-08-30 15:55:35 -0700 | [diff] [blame] | 86 |             boolean interactiveMode = false; | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 87 |             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 Cordon | 8357047 | 2013-09-06 15:45:10 -0700 | [diff] [blame] | 152 |  | 
| Santos Cordon | 00d7a43 | 2013-09-17 14:07:14 -0700 | [diff] [blame] | 153 |     /** | 
 | 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 Cordon | 8357047 | 2013-09-06 15:45:10 -0700 | [diff] [blame] | 178 |  | 
 | 179 |     /** | 
 | 180 |      * Starts the HFA provisioning process by bringing up the HFA Activity. | 
 | 181 |      */ | 
 | 182 |     private void startHfa() { | 
| Santos Cordon | 00d7a43 | 2013-09-17 14:07:14 -0700 | [diff] [blame] | 183 |         final Intent intent = new Intent(); | 
| Santos Cordon | 8357047 | 2013-09-06 15:45:10 -0700 | [diff] [blame] | 184 |  | 
 | 185 |         final PendingIntent otaResponseIntent = getIntent().getParcelableExtra( | 
 | 186 |                 OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT); | 
 | 187 |  | 
| Santos Cordon | 00d7a43 | 2013-09-17 14:07:14 -0700 | [diff] [blame] | 188 |         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 Cordon | 8357047 | 2013-09-06 15:45:10 -0700 | [diff] [blame] | 195 |  | 
 | 196 |         Log.v(LOG_TAG, "Starting hfa activation activity"); | 
| Santos Cordon | 00d7a43 | 2013-09-17 14:07:14 -0700 | [diff] [blame] | 197 |         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 Cordon | 8357047 | 2013-09-06 15:45:10 -0700 | [diff] [blame] | 206 |     } | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 207 | } |