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
17package com.android.phone;
18
19import android.app.Activity;
20import android.app.PendingIntent;
21import android.content.Intent;
22import android.os.Bundle;
23import android.os.SystemProperties;
24import android.util.Log;
25
26import com.android.internal.telephony.Phone;
27import com.android.internal.telephony.TelephonyCapabilities;
28
29/**
30 * Invisible activity that handles the com.android.phone.PERFORM_CDMA_PROVISIONING intent.
31 * This activity is protected by the android.permission.PERFORM_CDMA_PROVISIONING permission.
32 *
33 * We handle the PERFORM_CDMA_PROVISIONING action by launching an OTASP
34 * call via one of the OtaUtils helper methods: startInteractiveOtasp() on
35 * regular phones, or startNonInteractiveOtasp() on data-only devices.
36 *
37 * TODO: The class name InCallScreenShowActivation is misleading, since
38 * this activity is totally unrelated to the InCallScreen (which
39 * implements the in-call UI.)  Let's eventually rename this to something
40 * like CdmaProvisioningLauncher or CdmaProvisioningHandler...
41 */
42public class InCallScreenShowActivation extends Activity {
43    private static final String LOG_TAG = "InCallScreenShowActivation";
44    private static final boolean DBG =
45            (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
46
47    @Override
48    protected void onCreate(Bundle icicle) {
49        super.onCreate(icicle);
50
51        Intent intent = getIntent();
52        if (DBG) Log.d(LOG_TAG, "onCreate: intent = " + intent);
53        Bundle extras = intent.getExtras();
54        if (DBG && (extras != null)) {
55            Log.d(LOG_TAG, "      - has extras: size = " + extras.size()); // forces an unparcel()
56            Log.d(LOG_TAG, "      - extras = " + extras);
57        }
58
59        PhoneApp app = PhoneApp.getInstance();
60        Phone phone = app.getPhone();
61        if (!TelephonyCapabilities.supportsOtasp(phone)) {
62            Log.w(LOG_TAG, "CDMA Provisioning not supported on this device");
63            setResult(RESULT_CANCELED);
64            finish();
65            return;
66        }
67
68        if (intent.getAction().equals(OtaUtils.ACTION_PERFORM_CDMA_PROVISIONING)) {
69
70            // On voice-capable devices, we perform CDMA provisioning in
71            // "interactive" mode by directly launching the InCallScreen.
72            boolean interactiveMode = PhoneApp.sVoiceCapable;
73            Log.d(LOG_TAG, "ACTION_PERFORM_CDMA_PROVISIONING (interactiveMode = "
74                  + interactiveMode + ")...");
75
76            // Testing: this intent extra allows test apps manually
77            // enable/disable "interactive mode", regardless of whether
78            // the current device is voice-capable.  This is allowed only
79            // in userdebug or eng builds.
80            if (intent.hasExtra(OtaUtils.EXTRA_OVERRIDE_INTERACTIVE_MODE)
81                    && (SystemProperties.getInt("ro.debuggable", 0) == 1)) {
82                interactiveMode =
83                        intent.getBooleanExtra(OtaUtils.EXTRA_OVERRIDE_INTERACTIVE_MODE, false);
84                Log.d(LOG_TAG, "===> MANUALLY OVERRIDING interactiveMode to " + interactiveMode);
85            }
86
87            // We allow the caller to pass a PendingIntent (as the
88            // EXTRA_NONINTERACTIVE_OTASP_RESULT_PENDING_INTENT extra)
89            // which we'll later use to notify them when the OTASP call
90            // fails or succeeds.
91            //
92            // Stash that away here, and we'll fire it off later in
93            // OtaUtils.sendOtaspResult().
94            app.cdmaOtaScreenState.otaspResultCodePendingIntent =
95                        (PendingIntent) intent.getParcelableExtra(
96                                OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
97
98            if (interactiveMode) {
99                // On voice-capable devices, launch an OTASP call and arrange
100                // for the in-call UI to come up.  (The InCallScreen will
101                // notice that an OTASP call is active, and display the
102                // special OTASP UI instead of the usual in-call controls.)
103
104                if (DBG) Log.d(LOG_TAG, "==> Starting interactive CDMA provisioning...");
105                OtaUtils.startInteractiveOtasp(this);
106
107                // The result we set here is actually irrelevant, since the
108                // InCallScreen's "interactive" OTASP sequence never actually
109                // finish()es; it ends by directly launching the Home
110                // activity.  So our caller won't actually ever get an
111                // onActivityResult() call in this case.
112                setResult(OtaUtils.RESULT_INTERACTIVE_OTASP_STARTED);
113            } else {
114                // On data-only devices, manually launch the OTASP call
115                // *without* displaying any UI.  (Our caller, presumably
116                // SetupWizardActivity, is responsible for displaying some
117                // sort of progress UI.)
118
119                if (DBG) Log.d(LOG_TAG, "==> Starting non-interactive CDMA provisioning...");
120                int callStatus = OtaUtils.startNonInteractiveOtasp(this);
121
122                if (callStatus == PhoneUtils.CALL_STATUS_DIALED) {
123                    if (DBG) Log.d(LOG_TAG, "  ==> successful result from startNonInteractiveOtasp(): "
124                          + callStatus);
125                    setResult(OtaUtils.RESULT_NONINTERACTIVE_OTASP_STARTED);
126                } else {
127                    Log.w(LOG_TAG, "Failure code from startNonInteractiveOtasp(): " + callStatus);
128                    setResult(OtaUtils.RESULT_NONINTERACTIVE_OTASP_FAILED);
129                }
130            }
131        } else {
132            Log.e(LOG_TAG, "Unexpected intent action: " + intent);
133            setResult(RESULT_CANCELED);
134        }
135
136        finish();
137    }
138}
139