1af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville/*
2af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * Copyright (C) 2009 The Android Open Source Project
3af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville *
4af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
5af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * you may not use this file except in compliance with the License.
6af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * You may obtain a copy of the License at
7af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville *
8af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
9af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville *
10af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * Unless required by applicable law or agreed to in writing, software
11af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
12af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * See the License for the specific language governing permissions and
14af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * limitations under the License.
15af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville */
16af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
17af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savillepackage com.android.phone;
18af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
19af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savilleimport com.android.internal.telephony.Phone;
20a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ngimport com.android.internal.telephony.TelephonyProperties;
215c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Savilleimport com.android.phone.OtaUtils.CdmaOtaInCallScreenUiState.State;
22af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
23b154630235935e1aab2a41eff9ed794d40084a02David Brownimport android.app.Activity;
24777b22c936d2bfa8140427402906a140d17180dcFreeman Ngimport android.app.ActivityManager;
25af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savilleimport android.app.AlertDialog;
2613660626500d047d4a3a097e832bb175e1c4f894Freeman Ngimport android.app.PendingIntent;
2713660626500d047d4a3a097e832bb175e1c4f894Freeman Ngimport android.app.PendingIntent.CanceledException;
28af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savilleimport android.content.Context;
29af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savilleimport android.content.DialogInterface;
30af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savilleimport android.content.Intent;
31211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brownimport android.net.Uri;
32af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savilleimport android.os.AsyncResult;
33839b14d460986608fe577f89f789de854dc85b58Jim Millerimport android.os.Handler;
34af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savilleimport android.os.SystemClock;
35a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ngimport android.os.SystemProperties;
36a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ngimport android.telephony.TelephonyManager;
37af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savilleimport android.util.Log;
38af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savilleimport android.view.KeyEvent;
39af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savilleimport android.view.View;
40af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savilleimport android.view.ViewGroup;
41af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savilleimport android.view.ViewStub;
42af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savilleimport android.view.WindowManager;
43af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savilleimport android.widget.Button;
44af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savilleimport android.widget.ProgressBar;
45b154630235935e1aab2a41eff9ed794d40084a02David Brownimport android.widget.ScrollView;
46af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savilleimport android.widget.TextView;
47b154630235935e1aab2a41eff9ed794d40084a02David Brownimport android.widget.ToggleButton;
48af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
49af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville/**
507c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown * Handles all OTASP Call related logic and UI functionality.
517c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown * The InCallScreen interacts with this class to perform an OTASP Call.
52e31831f42ffa08456ef0d5d1461ddc70b9d1fcfeDavid Brown *
537c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown * OTASP is a CDMA-specific feature:
54e31831f42ffa08456ef0d5d1461ddc70b9d1fcfeDavid Brown *   OTA or OTASP == Over The Air service provisioning
55e31831f42ffa08456ef0d5d1461ddc70b9d1fcfeDavid Brown *   SPC == Service Programming Code
56e31831f42ffa08456ef0d5d1461ddc70b9d1fcfeDavid Brown *   TODO: Include pointer to more detailed documentation.
57b154630235935e1aab2a41eff9ed794d40084a02David Brown *
58b154630235935e1aab2a41eff9ed794d40084a02David Brown * TODO: This is Over The Air Service Provisioning (OTASP)
59b154630235935e1aab2a41eff9ed794d40084a02David Brown *       A better name would be OtaspUtils.java.
60af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville */
61af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savillepublic class OtaUtils {
62af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private static final String LOG_TAG = "OtaUtils";
63c3098c14cb1c0444d61ba1b6d0b81175e93bbd75David Brown    private static final boolean DBG = true;
64af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
65af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public static final int OTA_SHOW_ACTIVATION_SCREEN_OFF = 0;
66af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public static final int OTA_SHOW_ACTIVATION_SCREEN_ON = 1;
67af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public static final int OTA_SHOW_LISTENING_SCREEN_OFF =0;
68af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public static final int OTA_SHOW_LISTENING_SCREEN_ON =1;
69af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public static final int OTA_SHOW_ACTIVATE_FAIL_COUNT_OFF = 0;
70af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public static final int OTA_SHOW_ACTIVATE_FAIL_COUNT_THREE = 3;
71af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public static final int OTA_PLAY_SUCCESS_FAILURE_TONE_OFF = 0;
72af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public static final int OTA_PLAY_SUCCESS_FAILURE_TONE_ON = 1;
73af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
7417c36a10d09fac3e2312c0bcb839e0a704f42105w    // SPC Timeout is 60 seconds
7517c36a10d09fac3e2312c0bcb839e0a704f42105w    public final int OTA_SPC_TIMEOUT = 60;
76af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public final int OTA_FAILURE_DIALOG_TIMEOUT = 2;
77af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
78b154630235935e1aab2a41eff9ed794d40084a02David Brown    // Constants for OTASP-related Intents and intent extras.
79b154630235935e1aab2a41eff9ed794d40084a02David Brown    // Watch out: these must agree with the corresponding constants in
80b154630235935e1aab2a41eff9ed794d40084a02David Brown    // apps/SetupWizard!
81b154630235935e1aab2a41eff9ed794d40084a02David Brown
82b154630235935e1aab2a41eff9ed794d40084a02David Brown    // Intent action to launch an OTASP call.
83b154630235935e1aab2a41eff9ed794d40084a02David Brown    public static final String ACTION_PERFORM_CDMA_PROVISIONING =
84b154630235935e1aab2a41eff9ed794d40084a02David Brown           "com.android.phone.PERFORM_CDMA_PROVISIONING";
85b154630235935e1aab2a41eff9ed794d40084a02David Brown
86d92cf8295af01ac7c72486e95b6c52376df601faFreeman Ng    // Intent action to launch activation on a non-voice capable device
87d92cf8295af01ac7c72486e95b6c52376df601faFreeman Ng    public static final String ACTION_PERFORM_VOICELESS_CDMA_PROVISIONING =
88d92cf8295af01ac7c72486e95b6c52376df601faFreeman Ng            "com.android.phone.PERFORM_VOICELESS_CDMA_PROVISIONING";
89d92cf8295af01ac7c72486e95b6c52376df601faFreeman Ng
90eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown    // Intent action to display the InCallScreen in the OTASP "activation" state.
91eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown    public static final String ACTION_DISPLAY_ACTIVATION_SCREEN =
92eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown            "com.android.phone.DISPLAY_ACTIVATION_SCREEN";
93eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown
940c38cb459cd32bbe1db923fa77fa9f4671f7edfaFreeman Ng    // boolean voiceless provisioning extra that enables a "don't show this again" checkbox
950c38cb459cd32bbe1db923fa77fa9f4671f7edfaFreeman Ng    // the user can check to never see the activity upon bootup again
960c38cb459cd32bbe1db923fa77fa9f4671f7edfaFreeman Ng    public static final String EXTRA_VOICELESS_PROVISIONING_OFFER_DONTSHOW =
970c38cb459cd32bbe1db923fa77fa9f4671f7edfaFreeman Ng            "com.android.phone.VOICELESS_PROVISIONING_OFFER_DONTSHOW";
980c38cb459cd32bbe1db923fa77fa9f4671f7edfaFreeman Ng
99b154630235935e1aab2a41eff9ed794d40084a02David Brown    // Activity result codes for the ACTION_PERFORM_CDMA_PROVISIONING intent
100b154630235935e1aab2a41eff9ed794d40084a02David Brown    // (see the InCallScreenShowActivation activity.)
101b5d698eb0a399d6f8c5c1b82f9b39903408e3cb8David Brown    //
102b5d698eb0a399d6f8c5c1b82f9b39903408e3cb8David Brown    // Note: currently, our caller won't ever actually receive the
103b5d698eb0a399d6f8c5c1b82f9b39903408e3cb8David Brown    // RESULT_INTERACTIVE_OTASP_STARTED result code; see comments in
104b5d698eb0a399d6f8c5c1b82f9b39903408e3cb8David Brown    // InCallScreenShowActivation.onCreate() for details.
105b5d698eb0a399d6f8c5c1b82f9b39903408e3cb8David Brown
106b154630235935e1aab2a41eff9ed794d40084a02David Brown    public static final int RESULT_INTERACTIVE_OTASP_STARTED = Activity.RESULT_FIRST_USER;
107b154630235935e1aab2a41eff9ed794d40084a02David Brown    public static final int RESULT_NONINTERACTIVE_OTASP_STARTED = Activity.RESULT_FIRST_USER + 1;
108b154630235935e1aab2a41eff9ed794d40084a02David Brown    public static final int RESULT_NONINTERACTIVE_OTASP_FAILED = Activity.RESULT_FIRST_USER + 2;
109b154630235935e1aab2a41eff9ed794d40084a02David Brown
110b154630235935e1aab2a41eff9ed794d40084a02David Brown    // Testing: Extra for the ACTION_PERFORM_CDMA_PROVISIONING intent that
111b154630235935e1aab2a41eff9ed794d40084a02David Brown    // allows the caller to manually enable/disable "interactive mode" for
1127d38129b67491544c5969dc784db478b13918b08David Brown    // the OTASP call.   Only available in userdebug or eng builds.
113b154630235935e1aab2a41eff9ed794d40084a02David Brown    public static final String EXTRA_OVERRIDE_INTERACTIVE_MODE =
114b154630235935e1aab2a41eff9ed794d40084a02David Brown            "ota_override_interactive_mode";
115b154630235935e1aab2a41eff9ed794d40084a02David Brown
116b154630235935e1aab2a41eff9ed794d40084a02David Brown    // Extra for the ACTION_PERFORM_CDMA_PROVISIONING intent, holding a
117b154630235935e1aab2a41eff9ed794d40084a02David Brown    // PendingIntent which the phone app can use to send a result code
118b154630235935e1aab2a41eff9ed794d40084a02David Brown    // back to the caller.
119b154630235935e1aab2a41eff9ed794d40084a02David Brown    public static final String EXTRA_OTASP_RESULT_CODE_PENDING_INTENT =
120b154630235935e1aab2a41eff9ed794d40084a02David Brown            "otasp_result_code_pending_intent";
121b154630235935e1aab2a41eff9ed794d40084a02David Brown
122b154630235935e1aab2a41eff9ed794d40084a02David Brown    // Extra attached to the above PendingIntent that indicates
123b154630235935e1aab2a41eff9ed794d40084a02David Brown    // success or failure.
124b154630235935e1aab2a41eff9ed794d40084a02David Brown    public static final String EXTRA_OTASP_RESULT_CODE =
125b154630235935e1aab2a41eff9ed794d40084a02David Brown            "otasp_result_code";
126b154630235935e1aab2a41eff9ed794d40084a02David Brown    public static final int OTASP_UNKNOWN = 0;
127b154630235935e1aab2a41eff9ed794d40084a02David Brown    public static final int OTASP_USER_SKIPPED = 1;  // Only meaningful with interactive OTASP
128b154630235935e1aab2a41eff9ed794d40084a02David Brown    public static final int OTASP_SUCCESS = 2;
129b154630235935e1aab2a41eff9ed794d40084a02David Brown    public static final int OTASP_FAILURE = 3;
13062995702f659b906127351596305906ccd0d7cb5Freeman Ng    // failed due to CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED
13162995702f659b906127351596305906ccd0d7cb5Freeman Ng    public static final int OTASP_FAILURE_SPC_RETRIES = 4;
132b5d698eb0a399d6f8c5c1b82f9b39903408e3cb8David Brown    // TODO: Distinguish between interactive and non-interactive success
133b5d698eb0a399d6f8c5c1b82f9b39903408e3cb8David Brown    // and failure.  Then, have the PendingIntent be sent after
134b5d698eb0a399d6f8c5c1b82f9b39903408e3cb8David Brown    // interactive OTASP as well (so the caller can find out definitively
135b5d698eb0a399d6f8c5c1b82f9b39903408e3cb8David Brown    // when interactive OTASP completes.)
136b154630235935e1aab2a41eff9ed794d40084a02David Brown
137b154630235935e1aab2a41eff9ed794d40084a02David Brown    private static final String OTASP_NUMBER = "*228";
138b154630235935e1aab2a41eff9ed794d40084a02David Brown    private static final String OTASP_NUMBER_NON_INTERACTIVE = "*22899";
139b154630235935e1aab2a41eff9ed794d40084a02David Brown
140af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private InCallScreen mInCallScreen;
141af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private Context mContext;
142af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private PhoneApp mApplication;
143af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private OtaWidgetData mOtaWidgetData;
144ed6c435b8ce38a269982385071b720cc98819239David Brown    private ViewGroup mInCallPanel;  // Container for the CallCard
145ed6c435b8ce38a269982385071b720cc98819239David Brown    private ViewGroup mInCallTouchUi;  // UI controls for regular calls
146af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private CallCard mCallCard;
1472f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown
1487c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown    // The DTMFTwelveKeyDialer instance.   We create this in
1497c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown    // initOtaInCallScreen(), and attach it to the DTMFTwelveKeyDialerView
1502f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown    // ("otaDtmfDialerView") that comes from otacall_card.xml.
1512f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown    private DTMFTwelveKeyDialer mOtaCallCardDtmfDialer;
1522f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown
153a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng    private static boolean sIsWizardMode = true;
154a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng
155a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng    // How many times do we retry maybeDoOtaCall() if the LTE state is not known yet,
156a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng    // and how long do we wait between retries
157a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng    private static final int OTA_CALL_LTE_RETRIES_MAX = 5;
158a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng    private static final int OTA_CALL_LTE_RETRY_PERIOD = 3000;
159a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng    private static int sOtaCallLteRetries = 0;
160af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
161b154630235935e1aab2a41eff9ed794d40084a02David Brown    // In "interactive mode", the OtaUtils object is tied to an
162b154630235935e1aab2a41eff9ed794d40084a02David Brown    // InCallScreen instance, where we display a bunch of UI specific to
163b154630235935e1aab2a41eff9ed794d40084a02David Brown    // the OTASP call.  But on devices that are not "voice capable", the
164b154630235935e1aab2a41eff9ed794d40084a02David Brown    // OTASP call runs in a non-interactive mode, and we don't have
165b154630235935e1aab2a41eff9ed794d40084a02David Brown    // an InCallScreen or CallCard or any OTASP UI elements at all.
166b154630235935e1aab2a41eff9ed794d40084a02David Brown    private boolean mInteractive = true;
167b154630235935e1aab2a41eff9ed794d40084a02David Brown
168b154630235935e1aab2a41eff9ed794d40084a02David Brown
169af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
170af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * OtaWidgetData class represent all OTA UI elements
171211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *
172211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * TODO(OTASP): It's really ugly for the OtaUtils object to reach into the
173211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *     InCallScreen like this and directly manipulate its widgets.
174211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *
175211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *     Instead, the model/view separation should be more clear: OtaUtils
176211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *     should only know about a higher-level abstraction of the
177211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *     OTASP-specific UI state (just like how the CallController uses the
178211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *     InCallUiState object), and the InCallScreen itself should translate
179211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *     that higher-level abstraction into actual onscreen views and widgets.
180af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
181af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private class OtaWidgetData {
182af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public Button otaEndButton;
183af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public Button otaActivateButton;
18413660626500d047d4a3a097e832bb175e1c4f894Freeman Ng        public Button otaSkipButton;
185986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        public Button otaNextButton;
186af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public ToggleButton otaSpeakerButton;
1877c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        public ViewGroup otaUpperWidgets;
188af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public View callCardOtaButtonsFailSuccess;
189af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public ProgressBar otaTextProgressBar;
190af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public TextView otaTextSuccessFail;
191af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public View callCardOtaButtonsActivate;
192af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public View callCardOtaButtonsListenProgress;
193af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public TextView otaTextActivate;
194af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public TextView otaTextListenProgress;
195af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public AlertDialog spcErrorDialog;
196af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public AlertDialog otaFailureDialog;
19713660626500d047d4a3a097e832bb175e1c4f894Freeman Ng        public AlertDialog otaSkipConfirmationDialog;
198986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        public TextView otaTitle;
199986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        public DTMFTwelveKeyDialerView otaDtmfDialerView;
200986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        public Button otaTryAgainButton;
201af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
202af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
203211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown    /**
204211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * OtaUtils constructor.
205211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *
206211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * @param context the Context of the calling Activity or Application
207211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * @param interactive if true, use the InCallScreen to display the progress
208211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *                    and result of the OTASP call.  In practice this is
209211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *                    true IFF the current device is a voice-capable phone.
210211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *
211211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * Note if interactive is true, you must also call updateUiWidgets() as soon
212211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * as the InCallScreen instance is ready.
213211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     */
214211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown    public OtaUtils(Context context, boolean interactive) {
215211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if (DBG) log("OtaUtils constructor...");
216211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        mApplication = PhoneApp.getInstance();
217211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        mContext = context;
218211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        mInteractive = interactive;
219211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown    }
220211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
221211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown    /**
222211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * Updates the OtaUtils object's references to some UI elements belonging to
223211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * the InCallScreen.  This is used only in interactive mode.
224211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *
225211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * Use clearUiWidgets() to clear out these references.  (The InCallScreen
226211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * is responsible for doing this from its onDestroy() method.)
227211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *
228211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * This method has no effect if the UI widgets have already been set up.
229211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * (In other words, it's safe to call this every time through
230211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * InCallScreen.onResume().)
231211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     */
232211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown    public void updateUiWidgets(InCallScreen inCallScreen,
233211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown                                ViewGroup inCallPanel,
234ed6c435b8ce38a269982385071b720cc98819239David Brown                                ViewGroup inCallTouchUi,
2357c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown                                CallCard callCard) {
236211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if (DBG) log("updateUiWidgets()...  mInCallScreen = " + mInCallScreen);
237211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
238211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if (!mInteractive) {
239211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            throw new IllegalStateException("updateUiWidgets() called in non-interactive mode");
240211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        }
241af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
242211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if (mInCallScreen != null) {
243211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            if (DBG) log("updateUiWidgets(): widgets already set up, nothing to do...");
244211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            return;
245211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        }
246af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
247af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mInCallScreen = inCallScreen;
248af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mInCallPanel = inCallPanel;
249ed6c435b8ce38a269982385071b720cc98819239David Brown        mInCallTouchUi = inCallTouchUi;
250af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mCallCard = callCard;
251af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData = new OtaWidgetData();
252af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
253211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // Inflate OTASP-specific UI elements:
254211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        ViewStub otaCallCardStub = (ViewStub) mInCallScreen.findViewById(R.id.otaCallCardStub);
255211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if (otaCallCardStub != null) {
256211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            // If otaCallCardStub is null here, that means it's already been
257211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            // inflated (which could have happened in the current InCallScreen
258211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            // instance for a *prior* OTASP call.)
259b154630235935e1aab2a41eff9ed794d40084a02David Brown            otaCallCardStub.inflate();
260b154630235935e1aab2a41eff9ed794d40084a02David Brown        }
261211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
262211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        readXmlSettings();
263211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        initOtaInCallScreen();
264211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown    }
265211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
266211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown    /**
267211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * Clear out the OtaUtils object's references to any InCallScreen UI
268211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * elements.  This is the opposite of updateUiWidgets().
269211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     */
270211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown    public void clearUiWidgets() {
271211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        mInCallScreen = null;
272211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        mInCallPanel = null;
273ed6c435b8ce38a269982385071b720cc98819239David Brown        mInCallTouchUi = null;
274211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        mCallCard = null;
275211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        mOtaWidgetData = null;
276af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
277a44a437fae34920b0ecbf66400ac50e10e5ae49eEric Laurent
278839b14d460986608fe577f89f789de854dc85b58Jim Miller    /**
279839b14d460986608fe577f89f789de854dc85b58Jim Miller     * Starts the OTA provisioning call.  If the MIN isn't available yet, it returns false and adds
280a44a437fae34920b0ecbf66400ac50e10e5ae49eEric Laurent     * an event to return the request to the calling app when it becomes available.
281a44a437fae34920b0ecbf66400ac50e10e5ae49eEric Laurent     *
282839b14d460986608fe577f89f789de854dc85b58Jim Miller     * @param context
283839b14d460986608fe577f89f789de854dc85b58Jim Miller     * @param handler
284839b14d460986608fe577f89f789de854dc85b58Jim Miller     * @param request
285839b14d460986608fe577f89f789de854dc85b58Jim Miller     * @return true if we were able to launch Ota activity or it's not required; false otherwise
286839b14d460986608fe577f89f789de854dc85b58Jim Miller     */
287839b14d460986608fe577f89f789de854dc85b58Jim Miller    public static boolean maybeDoOtaCall(Context context, Handler handler, int request) {
288839b14d460986608fe577f89f789de854dc85b58Jim Miller        PhoneApp app = PhoneApp.getInstance();
289839b14d460986608fe577f89f789de854dc85b58Jim Miller        Phone phone = app.phone;
290839b14d460986608fe577f89f789de854dc85b58Jim Miller
291777b22c936d2bfa8140427402906a140d17180dcFreeman Ng        if (ActivityManager.isRunningInTestHarness()) {
292777b22c936d2bfa8140427402906a140d17180dcFreeman Ng            Log.i(LOG_TAG, "Don't run provisioning when in test harness");
293777b22c936d2bfa8140427402906a140d17180dcFreeman Ng            return true;
294777b22c936d2bfa8140427402906a140d17180dcFreeman Ng        }
295777b22c936d2bfa8140427402906a140d17180dcFreeman Ng
2967c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        if (!TelephonyCapabilities.supportsOtasp(phone)) {
2977c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            // Presumably not a CDMA phone.
2987c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            if (DBG) log("maybeDoOtaCall: OTASP not supported on this device");
2997c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            return true;  // Nothing to do here.
300839b14d460986608fe577f89f789de854dc85b58Jim Miller        }
301839b14d460986608fe577f89f789de854dc85b58Jim Miller
302839b14d460986608fe577f89f789de854dc85b58Jim Miller        if (!phone.isMinInfoReady()) {
303839b14d460986608fe577f89f789de854dc85b58Jim Miller            if (DBG) log("MIN is not ready. Registering to receive notification.");
304839b14d460986608fe577f89f789de854dc85b58Jim Miller            phone.registerForSubscriptionInfoReady(handler, request, null);
305839b14d460986608fe577f89f789de854dc85b58Jim Miller            return false;
306839b14d460986608fe577f89f789de854dc85b58Jim Miller        }
307839b14d460986608fe577f89f789de854dc85b58Jim Miller        phone.unregisterForSubscriptionInfoReady(handler);
308839b14d460986608fe577f89f789de854dc85b58Jim Miller
309a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng        if (getLteOnCdmaMode(context) == Phone.LTE_ON_CDMA_UNKNOWN) {
310a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng            if (sOtaCallLteRetries < OTA_CALL_LTE_RETRIES_MAX) {
311a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng                if (DBG) log("maybeDoOtaCall: LTE state still unknown: retrying");
312a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng                handler.sendEmptyMessageDelayed(request, OTA_CALL_LTE_RETRY_PERIOD);
313a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng                sOtaCallLteRetries++;
314a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng                return false;
315a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng            } else {
316a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng                Log.w(LOG_TAG, "maybeDoOtaCall: LTE state still unknown: giving up");
317a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng                return true;
318a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng            }
319a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng        }
320a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng
321f0d315541b1b1f33fab5e7952471da6e886b53efWink Saville        boolean phoneNeedsActivation = phone.needsOtaServiceProvisioning();
322839b14d460986608fe577f89f789de854dc85b58Jim Miller        if (DBG) log("phoneNeedsActivation is set to " + phoneNeedsActivation);
323a44a437fae34920b0ecbf66400ac50e10e5ae49eEric Laurent
324839b14d460986608fe577f89f789de854dc85b58Jim Miller        int otaShowActivationScreen = context.getResources().getInteger(
325839b14d460986608fe577f89f789de854dc85b58Jim Miller                R.integer.OtaShowActivationScreen);
326839b14d460986608fe577f89f789de854dc85b58Jim Miller        if (DBG) log("otaShowActivationScreen: " + otaShowActivationScreen);
327839b14d460986608fe577f89f789de854dc85b58Jim Miller
328d5251aa62c211ab6f7b66c877d862131d709bccbFreeman Ng        // Run the OTASP call in "interactive" mode only if
329a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng        // this is a non-LTE "voice capable" device.
330a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng        if (PhoneApp.sVoiceCapable && getLteOnCdmaMode(context) == Phone.LTE_ON_CDMA_FALSE) {
331b154630235935e1aab2a41eff9ed794d40084a02David Brown            if (phoneNeedsActivation
332b154630235935e1aab2a41eff9ed794d40084a02David Brown                    && (otaShowActivationScreen == OTA_SHOW_ACTIVATION_SCREEN_ON)) {
333b154630235935e1aab2a41eff9ed794d40084a02David Brown                app.cdmaOtaProvisionData.isOtaCallIntentProcessed = false;
334a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng                sIsWizardMode = false;
33558e4707b6cc021a663deae3e614364545ec9ee6aDavid Brown
336211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown                if (DBG) Log.d(LOG_TAG, "==> Starting interactive CDMA provisioning...");
337211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown                OtaUtils.startInteractiveOtasp(context);
33858e4707b6cc021a663deae3e614364545ec9ee6aDavid Brown
339211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown                if (DBG) log("maybeDoOtaCall: voice capable; activation started.");
340b154630235935e1aab2a41eff9ed794d40084a02David Brown            } else {
341211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown                if (DBG) log("maybeDoOtaCall: voice capable; activation NOT started.");
342b154630235935e1aab2a41eff9ed794d40084a02David Brown            }
343839b14d460986608fe577f89f789de854dc85b58Jim Miller        } else {
344b154630235935e1aab2a41eff9ed794d40084a02David Brown            if (phoneNeedsActivation) {
345d5251aa62c211ab6f7b66c877d862131d709bccbFreeman Ng                app.cdmaOtaProvisionData.isOtaCallIntentProcessed = false;
346d5251aa62c211ab6f7b66c877d862131d709bccbFreeman Ng                Intent newIntent = new Intent(ACTION_PERFORM_VOICELESS_CDMA_PROVISIONING);
347d5251aa62c211ab6f7b66c877d862131d709bccbFreeman Ng                newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3480c38cb459cd32bbe1db923fa77fa9f4671f7edfaFreeman Ng                newIntent.putExtra(EXTRA_VOICELESS_PROVISIONING_OFFER_DONTSHOW, true);
349d5251aa62c211ab6f7b66c877d862131d709bccbFreeman Ng                context.startActivity(newIntent);
350d5251aa62c211ab6f7b66c877d862131d709bccbFreeman Ng                if (DBG) log("maybeDoOtaCall: non-interactive; activation intent sent.");
351b154630235935e1aab2a41eff9ed794d40084a02David Brown            } else {
352d5251aa62c211ab6f7b66c877d862131d709bccbFreeman Ng                if (DBG) log("maybeDoOtaCall: non-interactive, no need for OTASP.");
353b154630235935e1aab2a41eff9ed794d40084a02David Brown            }
354839b14d460986608fe577f89f789de854dc85b58Jim Miller        }
355839b14d460986608fe577f89f789de854dc85b58Jim Miller        return true;
356839b14d460986608fe577f89f789de854dc85b58Jim Miller    }
357af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
358b154630235935e1aab2a41eff9ed794d40084a02David Brown    /**
359211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * Starts a normal "interactive" OTASP call (i.e. CDMA activation
360211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * for regular voice-capable phone devices.)
361211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *
362211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * This method is called from the InCallScreenShowActivation activity when
363211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * handling the ACTION_PERFORM_CDMA_PROVISIONING intent.
364211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     */
365211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown    public static void startInteractiveOtasp(Context context) {
366211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if (DBG) log("startInteractiveOtasp()...");
367211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        PhoneApp app = PhoneApp.getInstance();
368211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
369211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // There are two ways to start OTASP on voice-capable devices:
370211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //
371211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // (1) via the PERFORM_CDMA_PROVISIONING intent
372eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown        //     - this is triggered by the "Activate device" button in settings,
373211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //       or can be launched automatically upon boot if the device
374211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //       thinks it needs to be provisioned.
375211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //     - the intent is handled by InCallScreenShowActivation.onCreate(),
376211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //       which calls this method
377211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //     - we prepare for OTASP by initializing the OtaUtils object
378211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //     - we bring up the InCallScreen in the ready-to-activate state
379211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //     - when the user presses the "Activate" button we launch the
380211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //       call by calling CallController.placeCall() via the
381211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //       otaPerformActivation() method.
382211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //
383211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // (2) by manually making an outgoing call to a special OTASP number
384211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //     like "*228" or "*22899".
385211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //     - That sequence does NOT involve this method (OtaUtils.startInteractiveOtasp()).
386211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //       Instead, the outgoing call request goes straight to CallController.placeCall().
387211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //     - CallController.placeCall() notices that it's an OTASP
388211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //       call, and initializes the OtaUtils object.
389211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //     - The InCallScreen is launched (as the last step of
390211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //       CallController.placeCall()).  The InCallScreen notices that
391211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //       OTASP is active and shows the correct UI.
392211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
393eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown        // Here, we start sequence (1):
394eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown        // Do NOT immediately start the call.  Instead, bring up the InCallScreen
395eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown        // in the special "activate" state (see OtaUtils.otaShowActivateScreen()).
396eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown        // We won't actually make the call until the user presses the "Activate"
397eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown        // button.
398211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
399eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown        Intent activationScreenIntent = new Intent().setClass(context, InCallScreen.class)
400eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown                .setAction(ACTION_DISPLAY_ACTIVATION_SCREEN);
401211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
4029bb1e9b46be44d45367e8c9a99fcb2edb0546c54David Brown        // Watch out: in the scenario where OTASP gets triggered from the
4039bb1e9b46be44d45367e8c9a99fcb2edb0546c54David Brown        // BOOT_COMPLETED broadcast (see OtaStartupReceiver.java), we might be
4049bb1e9b46be44d45367e8c9a99fcb2edb0546c54David Brown        // running in the PhoneApp's context right now.
4059bb1e9b46be44d45367e8c9a99fcb2edb0546c54David Brown        // So the FLAG_ACTIVITY_NEW_TASK flag is required here.
4069bb1e9b46be44d45367e8c9a99fcb2edb0546c54David Brown        activationScreenIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4079bb1e9b46be44d45367e8c9a99fcb2edb0546c54David Brown
408eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown        // We're about to start the OTASP sequence, so create and initialize the
409eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown        // OtaUtils instance.  (This needs to happen before bringing up the
410eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown        // InCallScreen.)
411eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown        OtaUtils.setupOtaspCall(activationScreenIntent);
412211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
413eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown        // And bring up the InCallScreen...
414eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown        Log.i(LOG_TAG, "startInteractiveOtasp: launching InCallScreen in 'activate' state: "
415eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown              + activationScreenIntent);
416eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown        context.startActivity(activationScreenIntent);
417211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown    }
418211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
419211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown    /**
420b154630235935e1aab2a41eff9ed794d40084a02David Brown     * Starts the OTASP call *without* involving the InCallScreen or
421b154630235935e1aab2a41eff9ed794d40084a02David Brown     * displaying any UI.
422b154630235935e1aab2a41eff9ed794d40084a02David Brown     *
423b154630235935e1aab2a41eff9ed794d40084a02David Brown     * This is used on data-only devices, which don't support any kind of
424b154630235935e1aab2a41eff9ed794d40084a02David Brown     * in-call phone UI.
425b154630235935e1aab2a41eff9ed794d40084a02David Brown     *
426b154630235935e1aab2a41eff9ed794d40084a02David Brown     * @return PhoneUtils.CALL_STATUS_DIALED if we successfully
427b154630235935e1aab2a41eff9ed794d40084a02David Brown     *         dialed the OTASP number, or one of the other
428b154630235935e1aab2a41eff9ed794d40084a02David Brown     *         CALL_STATUS_* constants if there was a failure.
429b154630235935e1aab2a41eff9ed794d40084a02David Brown     */
430b154630235935e1aab2a41eff9ed794d40084a02David Brown    public static int startNonInteractiveOtasp(Context context) {
431b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (DBG) log("startNonInteractiveOtasp()...");
432b154630235935e1aab2a41eff9ed794d40084a02David Brown        PhoneApp app = PhoneApp.getInstance();
433b154630235935e1aab2a41eff9ed794d40084a02David Brown
434b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (app.otaUtils != null) {
435211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            // An OtaUtils instance already exists, presumably from a previous OTASP call.
436211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            Log.i(LOG_TAG, "startNonInteractiveOtasp: "
437b154630235935e1aab2a41eff9ed794d40084a02David Brown                  + "OtaUtils already exists; nuking the old one and starting again...");
438b154630235935e1aab2a41eff9ed794d40084a02David Brown        }
439b154630235935e1aab2a41eff9ed794d40084a02David Brown
440211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // Create the OtaUtils instance.
441211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        app.otaUtils = new OtaUtils(context, false /* non-interactive mode */);
442b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (DBG) log("- created OtaUtils: " + app.otaUtils);
443b154630235935e1aab2a41eff9ed794d40084a02David Brown
444b154630235935e1aab2a41eff9ed794d40084a02David Brown        // ... and kick off the OTASP call.
44575e3711d82d0c98444f6c438437cad41d862fca6David Brown        // TODO(InCallScreen redesign): This should probably go through
44675e3711d82d0c98444f6c438437cad41d862fca6David Brown        // the CallController, rather than directly calling
44775e3711d82d0c98444f6c438437cad41d862fca6David Brown        // PhoneUtils.placeCall().
448b154630235935e1aab2a41eff9ed794d40084a02David Brown        Phone phone = PhoneApp.getPhone();
449b154630235935e1aab2a41eff9ed794d40084a02David Brown        String number = OTASP_NUMBER_NON_INTERACTIVE;
450211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        Log.i(LOG_TAG, "startNonInteractiveOtasp: placing call to '" + number + "'...");
451b154630235935e1aab2a41eff9ed794d40084a02David Brown        int callStatus = PhoneUtils.placeCall(context,
452b154630235935e1aab2a41eff9ed794d40084a02David Brown                                              phone,
453b154630235935e1aab2a41eff9ed794d40084a02David Brown                                              number,
454b154630235935e1aab2a41eff9ed794d40084a02David Brown                                              null,  // contactRef
455b154630235935e1aab2a41eff9ed794d40084a02David Brown                                              false,  //isEmergencyCall
456b154630235935e1aab2a41eff9ed794d40084a02David Brown                                              null);  // gatewayUri
457b154630235935e1aab2a41eff9ed794d40084a02David Brown
458b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (callStatus == PhoneUtils.CALL_STATUS_DIALED) {
459b154630235935e1aab2a41eff9ed794d40084a02David Brown            if (DBG) log("  ==> successful return from placeCall(): callStatus = " + callStatus);
460b154630235935e1aab2a41eff9ed794d40084a02David Brown        } else {
461b154630235935e1aab2a41eff9ed794d40084a02David Brown            Log.w(LOG_TAG, "Failure from placeCall() for OTA number '"
462b154630235935e1aab2a41eff9ed794d40084a02David Brown                  + number + "': code " + callStatus);
463b154630235935e1aab2a41eff9ed794d40084a02David Brown            return callStatus;
464b154630235935e1aab2a41eff9ed794d40084a02David Brown        }
465b154630235935e1aab2a41eff9ed794d40084a02David Brown
466b154630235935e1aab2a41eff9ed794d40084a02David Brown        // TODO: Any other special work to do here?
467b154630235935e1aab2a41eff9ed794d40084a02David Brown        // Such as:
468b154630235935e1aab2a41eff9ed794d40084a02David Brown        //
469b154630235935e1aab2a41eff9ed794d40084a02David Brown        // - manually kick off progress updates, either using TelephonyRegistry
470b154630235935e1aab2a41eff9ed794d40084a02David Brown        //   or else by sending PendingIntents directly to our caller?
471b154630235935e1aab2a41eff9ed794d40084a02David Brown        //
472b154630235935e1aab2a41eff9ed794d40084a02David Brown        // - manually silence the in-call audio?  (Probably unnecessary
473b154630235935e1aab2a41eff9ed794d40084a02David Brown        //   if Stingray truly has no audio path from phone baseband
474b154630235935e1aab2a41eff9ed794d40084a02David Brown        //   to the device's speakers.)
475b154630235935e1aab2a41eff9ed794d40084a02David Brown        //
476b154630235935e1aab2a41eff9ed794d40084a02David Brown
477b154630235935e1aab2a41eff9ed794d40084a02David Brown        return callStatus;
478b154630235935e1aab2a41eff9ed794d40084a02David Brown    }
479b154630235935e1aab2a41eff9ed794d40084a02David Brown
480211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown    /**
481211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * @return true if the specified Intent is a CALL action that's an attempt
482211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * to initate an OTASP call.
483211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *
484211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * OTASP is a CDMA-specific concept, so this method will always return false
485211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * on GSM phones.
486211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *
487211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * This code was originally part of the InCallScreen.checkIsOtaCall() method.
488211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     */
489211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown    public static boolean isOtaspCallIntent(Intent intent) {
490211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if (DBG) log("isOtaspCallIntent(" + intent + ")...");
491211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        PhoneApp app = PhoneApp.getInstance();
492211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        Phone phone = app.mCM.getDefaultPhone();
493211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
494211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if (intent == null) {
495211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            return false;
496211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        }
497211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if (!TelephonyCapabilities.supportsOtasp(phone)) {
498211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            return false;
499211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        }
500211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
501211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        String action = intent.getAction();
502211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if (action == null) {
503211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            return false;
504211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        }
505211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if (!action.equals(Intent.ACTION_CALL)) {
506211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            if (DBG) log("isOtaspCallIntent: not a CALL action: '" + action + "' ==> not OTASP");
507211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            return false;
508211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        }
509211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
510211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if ((app.cdmaOtaScreenState == null) || (app.cdmaOtaProvisionData == null)) {
511211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            // Uh oh -- something wrong with our internal OTASP state.
512211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            // (Since this is an OTASP-capable device, these objects
513211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            // *should* have already been created by PhoneApp.onCreate().)
514211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            throw new IllegalStateException("isOtaspCallIntent: "
515211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown                                            + "app.cdmaOta* objects(s) not initialized");
516211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        }
517211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
518211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // This is an OTASP call iff the number we're trying to dial is one of
519211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // the magic OTASP numbers.
520211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        String number;
521211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        try {
522211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            number = CallController.getInitialNumber(intent);
523211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        } catch (PhoneUtils.VoiceMailNumberMissingException ex) {
524211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            // This was presumably a "voicemail:" intent, so it's
525211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            // obviously not an OTASP number.
526211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            if (DBG) log("isOtaspCallIntent: VoiceMailNumberMissingException => not OTASP");
527211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            return false;
528211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        }
529211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if (phone.isOtaSpNumber(number)) {
530211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            if (DBG) log("isOtaSpNumber: ACTION_CALL to '" + number + "' ==> OTASP call!");
531211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            return true;
532211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        }
533211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        return false;
534211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown    }
535211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
536211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown    /**
537211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * Set up for an OTASP call.
538211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *
539211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * This method is called as part of the CallController placeCall() sequence
540211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * before initiating an outgoing OTASP call.
541211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *
542211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * The purpose of this method is mainly to create and initialize the
543211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * OtaUtils instance, along with some other misc pre-OTASP cleanup.
544211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     */
545211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown    public static void setupOtaspCall(Intent intent) {
546211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if (DBG) log("setupOtaspCall(): preparing for OTASP call to " + intent);
547211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        PhoneApp app = PhoneApp.getInstance();
548211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
549211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if (app.otaUtils != null) {
550211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            // An OtaUtils instance already exists, presumably from a prior OTASP call.
551211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            // Nuke the old one and start this call with a fresh instance.
552211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            Log.i(LOG_TAG, "setupOtaspCall: "
553211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown                  + "OtaUtils already exists; replacing with new instance...");
554211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        }
555211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
556211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // Create the OtaUtils instance.
557211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        app.otaUtils = new OtaUtils(app.getApplicationContext(), true /* interactive */);
558211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if (DBG) log("- created OtaUtils: " + app.otaUtils);
559211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
560211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // NOTE we still need to call OtaUtils.updateUiWidgets() once the
561211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // InCallScreen instance is ready; see InCallScreen.checkOtaspStateOnResume()
562211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
563211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // Make sure the InCallScreen knows that it needs to switch into OTASP mode.
564211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //
565211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // NOTE in gingerbread and earlier, we used to do
566211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //     setInCallScreenMode(InCallScreenMode.OTA_NORMAL);
567211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // directly in the InCallScreen, back when this check happened inside the InCallScreen.
568211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        //
569211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // But now, set the global CdmaOtaInCallScreenUiState object into
570211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // NORMAL mode, which will then cause the InCallScreen (when it
571211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // comes up) to realize that an OTA call is active.
572211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
573211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        app.otaUtils.setCdmaOtaInCallScreenUiState(
574211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            OtaUtils.CdmaOtaInCallScreenUiState.State.NORMAL);
575211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
576211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // TODO(OTASP): note app.inCallUiState.inCallScreenMode and
577211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // app.cdmaOtaInCallScreenUiState.state are mostly redundant.  Combine them.
578211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        app.inCallUiState.inCallScreenMode = InCallUiState.InCallScreenMode.OTA_NORMAL;
579211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
580ed6c435b8ce38a269982385071b720cc98819239David Brown        // TODO(OTASP / bug 5092031): we ideally should call
581ed6c435b8ce38a269982385071b720cc98819239David Brown        // otaShowListeningScreen() here to make sure that the DTMF dialpad
582ed6c435b8ce38a269982385071b720cc98819239David Brown        // becomes visible at the start of the "*228" call:
583ed6c435b8ce38a269982385071b720cc98819239David Brown        //
584ed6c435b8ce38a269982385071b720cc98819239David Brown        //  // ...and get the OTASP-specific UI into the right state.
585ed6c435b8ce38a269982385071b720cc98819239David Brown        //  app.otaUtils.otaShowListeningScreen();
586ed6c435b8ce38a269982385071b720cc98819239David Brown        //  if (app.otaUtils.mInCallScreen != null) {
587ed6c435b8ce38a269982385071b720cc98819239David Brown        //      app.otaUtils.mInCallScreen.requestUpdateScreen();
588ed6c435b8ce38a269982385071b720cc98819239David Brown        //  }
589ed6c435b8ce38a269982385071b720cc98819239David Brown        //
590ed6c435b8ce38a269982385071b720cc98819239David Brown        // But this doesn't actually work; the call to otaShowListeningScreen()
591ed6c435b8ce38a269982385071b720cc98819239David Brown        // *doesn't* actually bring up the listening screen, since the
592ed6c435b8ce38a269982385071b720cc98819239David Brown        // cdmaOtaConfigData.otaShowListeningScreen config parameter hasn't been
593ed6c435b8ce38a269982385071b720cc98819239David Brown        // initialized (we haven't run readXmlSettings() yet at this point!)
594ed6c435b8ce38a269982385071b720cc98819239David Brown
595211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // Also, since the OTA call is now just starting, clear out
596211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        // the "committed" flag in app.cdmaOtaProvisionData.
597211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if (app.cdmaOtaProvisionData != null) {
598211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            app.cdmaOtaProvisionData.isOtaCallCommitted = false;
599211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        }
600211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown    }
601211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
602af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private void setSpeaker(boolean state) {
603af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (DBG) log("setSpeaker : " + state );
604b154630235935e1aab2a41eff9ed794d40084a02David Brown
605b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (!mInteractive) {
606b154630235935e1aab2a41eff9ed794d40084a02David Brown            if (DBG) log("non-interactive mode, ignoring setSpeaker.");
607b154630235935e1aab2a41eff9ed794d40084a02David Brown            return;
608b154630235935e1aab2a41eff9ed794d40084a02David Brown        }
609b154630235935e1aab2a41eff9ed794d40084a02David Brown
610af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (state == PhoneUtils.isSpeakerOn(mContext)) {
611af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            if (DBG) log("no change. returning");
612af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            return;
613af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
614af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
615af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (state && mInCallScreen.isBluetoothAvailable()
616af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                && mInCallScreen.isBluetoothAudioConnected()) {
617af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            mInCallScreen.disconnectBluetoothAudio();
618af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
619425b8e3c9846d5e0e76466604b35cad8856d79deEric Laurent        PhoneUtils.turnOnSpeaker(mContext, state, true);
620af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
621af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
622af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
623211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * Handles OTA Provision events from the telephony layer.
624211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * These events come in to this method whether or not
625211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * the InCallScreen is visible.
626211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     *
627211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown     * Possible events are:
628af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * OTA Commit Event - OTA provisioning was successful
629af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * SPC retries exceeded - SPC failure retries has exceeded, and Phone needs to
630af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     *    power down.
631af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
632af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public void onOtaProvisionStatusChanged(AsyncResult r) {
633af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        int OtaStatus[] = (int[]) r.result;
634b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (DBG) log("Provision status event!");
635b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (DBG) log("onOtaProvisionStatusChanged(): status = "
636b154630235935e1aab2a41eff9ed794d40084a02David Brown                     + OtaStatus[0] + " ==> " + otaProvisionStatusToString(OtaStatus[0]));
637b154630235935e1aab2a41eff9ed794d40084a02David Brown
638b154630235935e1aab2a41eff9ed794d40084a02David Brown        // In practice, in a normal successful OTASP call, events come in as follows:
639b154630235935e1aab2a41eff9ed794d40084a02David Brown        //   - SPL_UNLOCKED within a couple of seconds after the call starts
640b154630235935e1aab2a41eff9ed794d40084a02David Brown        //   - then a delay of around 45 seconds
641b154630235935e1aab2a41eff9ed794d40084a02David Brown        //   - then PRL_DOWNLOADED and MDN_DOWNLOADED and COMMITTED within a span of 2 seconds
642af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
643af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        switch(OtaStatus[0]) {
644af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            case Phone.CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED:
645b154630235935e1aab2a41eff9ed794d40084a02David Brown                if (DBG) log("onOtaProvisionStatusChanged(): RETRIES EXCEEDED");
646b154630235935e1aab2a41eff9ed794d40084a02David Brown                updateOtaspProgress();
647af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                mApplication.cdmaOtaProvisionData.otaSpcUptime = SystemClock.elapsedRealtime();
64862995702f659b906127351596305906ccd0d7cb5Freeman Ng                if (mInteractive) {
64962995702f659b906127351596305906ccd0d7cb5Freeman Ng                    otaShowSpcErrorNotice(OTA_SPC_TIMEOUT);
65062995702f659b906127351596305906ccd0d7cb5Freeman Ng                } else {
65162995702f659b906127351596305906ccd0d7cb5Freeman Ng                    sendOtaspResult(OTASP_FAILURE_SPC_RETRIES);
65262995702f659b906127351596305906ccd0d7cb5Freeman Ng                }
653af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                // Power.shutdown();
654af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                break;
65565336771f727928a14d1d8fe175390ef7a06f71dWink Saville
656af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            case Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED:
657d0c1beb9de9365f386becd7324e4e272152bd010Meng Hu                if (DBG) {
658d0c1beb9de9365f386becd7324e4e272152bd010Meng Hu                    log("onOtaProvisionStatusChanged(): DONE, isOtaCallCommitted set to true");
659d0c1beb9de9365f386becd7324e4e272152bd010Meng Hu                }
660d0c1beb9de9365f386becd7324e4e272152bd010Meng Hu                mApplication.cdmaOtaProvisionData.isOtaCallCommitted = true;
661a173cc986b1ca7d4dbb18263ed37d85c189d6cb7Meng Hu                if (mApplication.cdmaOtaScreenState.otaScreenState !=
662d0c1beb9de9365f386becd7324e4e272152bd010Meng Hu                    CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED) {
663a173cc986b1ca7d4dbb18263ed37d85c189d6cb7Meng Hu                    updateOtaspProgress();
664a173cc986b1ca7d4dbb18263ed37d85c189d6cb7Meng Hu                }
665a173cc986b1ca7d4dbb18263ed37d85c189d6cb7Meng Hu
66665336771f727928a14d1d8fe175390ef7a06f71dWink Saville                break;
66765336771f727928a14d1d8fe175390ef7a06f71dWink Saville
66865336771f727928a14d1d8fe175390ef7a06f71dWink Saville            case Phone.CDMA_OTA_PROVISION_STATUS_SPL_UNLOCKED:
66965336771f727928a14d1d8fe175390ef7a06f71dWink Saville            case Phone.CDMA_OTA_PROVISION_STATUS_A_KEY_EXCHANGED:
67065336771f727928a14d1d8fe175390ef7a06f71dWink Saville            case Phone.CDMA_OTA_PROVISION_STATUS_SSD_UPDATED:
67165336771f727928a14d1d8fe175390ef7a06f71dWink Saville            case Phone.CDMA_OTA_PROVISION_STATUS_NAM_DOWNLOADED:
67265336771f727928a14d1d8fe175390ef7a06f71dWink Saville            case Phone.CDMA_OTA_PROVISION_STATUS_MDN_DOWNLOADED:
67365336771f727928a14d1d8fe175390ef7a06f71dWink Saville            case Phone.CDMA_OTA_PROVISION_STATUS_IMSI_DOWNLOADED:
67465336771f727928a14d1d8fe175390ef7a06f71dWink Saville            case Phone.CDMA_OTA_PROVISION_STATUS_PRL_DOWNLOADED:
67565336771f727928a14d1d8fe175390ef7a06f71dWink Saville            case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STARTED:
67665336771f727928a14d1d8fe175390ef7a06f71dWink Saville            case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED:
67765336771f727928a14d1d8fe175390ef7a06f71dWink Saville            case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_ABORTED:
678a173cc986b1ca7d4dbb18263ed37d85c189d6cb7Meng Hu                // Only update progress when OTA call is in normal state
679a173cc986b1ca7d4dbb18263ed37d85c189d6cb7Meng Hu                if (getCdmaOtaInCallScreenUiState() == CdmaOtaInCallScreenUiState.State.NORMAL) {
680a173cc986b1ca7d4dbb18263ed37d85c189d6cb7Meng Hu                    if (DBG) log("onOtaProvisionStatusChanged(): change to ProgressScreen");
681a173cc986b1ca7d4dbb18263ed37d85c189d6cb7Meng Hu                    updateOtaspProgress();
682a173cc986b1ca7d4dbb18263ed37d85c189d6cb7Meng Hu                }
68365336771f727928a14d1d8fe175390ef7a06f71dWink Saville                break;
68465336771f727928a14d1d8fe175390ef7a06f71dWink Saville
68565336771f727928a14d1d8fe175390ef7a06f71dWink Saville            default:
68665336771f727928a14d1d8fe175390ef7a06f71dWink Saville                if (DBG) log("onOtaProvisionStatusChanged(): Ignoring OtaStatus " + OtaStatus[0]);
687af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                break;
688af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
689af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
690af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
691b154630235935e1aab2a41eff9ed794d40084a02David Brown    /**
692b154630235935e1aab2a41eff9ed794d40084a02David Brown     * Handle a disconnect event from the OTASP call.
693b154630235935e1aab2a41eff9ed794d40084a02David Brown     */
694b154630235935e1aab2a41eff9ed794d40084a02David Brown    public void onOtaspDisconnect() {
695b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (DBG) log("onOtaspDisconnect()...");
696b154630235935e1aab2a41eff9ed794d40084a02David Brown        // We only handle this event explicitly in non-interactive mode.
697b154630235935e1aab2a41eff9ed794d40084a02David Brown        // (In interactive mode, the InCallScreen does any post-disconnect
698b154630235935e1aab2a41eff9ed794d40084a02David Brown        // cleanup.)
699b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (!mInteractive) {
700b154630235935e1aab2a41eff9ed794d40084a02David Brown            // Send a success or failure indication back to our caller.
701b154630235935e1aab2a41eff9ed794d40084a02David Brown            updateNonInteractiveOtaSuccessFailure();
702b154630235935e1aab2a41eff9ed794d40084a02David Brown        }
703b154630235935e1aab2a41eff9ed794d40084a02David Brown    }
704b154630235935e1aab2a41eff9ed794d40084a02David Brown
705af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private void otaShowHome() {
7067c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        if (DBG) log("otaShowHome()...");
707af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mApplication.cdmaOtaScreenState.otaScreenState =
708af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED;
7094a5a966f0d43e04d336be1b94182346399a931f6Wink Saville        mInCallScreen.endInCallScreenSession();
710af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        Intent intent = new Intent(Intent.ACTION_MAIN);
711af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        intent.addCategory (Intent.CATEGORY_HOME);
712af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
713af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mContext.startActivity(intent);
714af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        return;
715af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
716af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
71713660626500d047d4a3a097e832bb175e1c4f894Freeman Ng    private void otaSkipActivation() {
71813660626500d047d4a3a097e832bb175e1c4f894Freeman Ng        if (DBG) log("otaSkipActivation()...");
71913660626500d047d4a3a097e832bb175e1c4f894Freeman Ng
720b154630235935e1aab2a41eff9ed794d40084a02David Brown        sendOtaspResult(OTASP_USER_SKIPPED);
72113660626500d047d4a3a097e832bb175e1c4f894Freeman Ng
722b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (mInteractive) mInCallScreen.finish();
72313660626500d047d4a3a097e832bb175e1c4f894Freeman Ng        return;
72413660626500d047d4a3a097e832bb175e1c4f894Freeman Ng    }
72513660626500d047d4a3a097e832bb175e1c4f894Freeman Ng
726b154630235935e1aab2a41eff9ed794d40084a02David Brown    /**
727b154630235935e1aab2a41eff9ed794d40084a02David Brown     * Actually initiate the OTASP call.  This method is triggered by the
728b154630235935e1aab2a41eff9ed794d40084a02David Brown     * onscreen "Activate" button, and is only used in interactive mode.
729b154630235935e1aab2a41eff9ed794d40084a02David Brown     */
73013660626500d047d4a3a097e832bb175e1c4f894Freeman Ng    private void otaPerformActivation() {
73113660626500d047d4a3a097e832bb175e1c4f894Freeman Ng        if (DBG) log("otaPerformActivation()...");
732b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (!mInteractive) {
733b154630235935e1aab2a41eff9ed794d40084a02David Brown            // We shouldn't ever get here in non-interactive mode!
734b154630235935e1aab2a41eff9ed794d40084a02David Brown            Log.w(LOG_TAG, "otaPerformActivation: not interactive!");
735b154630235935e1aab2a41eff9ed794d40084a02David Brown            return;
736b154630235935e1aab2a41eff9ed794d40084a02David Brown        }
737b154630235935e1aab2a41eff9ed794d40084a02David Brown
73813660626500d047d4a3a097e832bb175e1c4f894Freeman Ng        if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
739211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            // Place an outgoing call to the special OTASP number:
74013660626500d047d4a3a097e832bb175e1c4f894Freeman Ng            Intent newIntent = new Intent(Intent.ACTION_CALL);
74165454c803eb305c4740885ad4995a871b034a58aDavid Brown            newIntent.setData(Uri.fromParts(Constants.SCHEME_TEL, OTASP_NUMBER, null));
74275e3711d82d0c98444f6c438437cad41d862fca6David Brown
74375e3711d82d0c98444f6c438437cad41d862fca6David Brown            // Initiate the outgoing call:
744211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            mApplication.callController.placeCall(newIntent);
74575e3711d82d0c98444f6c438437cad41d862fca6David Brown
746ed6c435b8ce38a269982385071b720cc98819239David Brown            // ...and get the OTASP-specific UI into the right state.
74713660626500d047d4a3a097e832bb175e1c4f894Freeman Ng            otaShowListeningScreen();
7487c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            mInCallScreen.requestUpdateScreen();
74913660626500d047d4a3a097e832bb175e1c4f894Freeman Ng        }
75013660626500d047d4a3a097e832bb175e1c4f894Freeman Ng        return;
75113660626500d047d4a3a097e832bb175e1c4f894Freeman Ng    }
75213660626500d047d4a3a097e832bb175e1c4f894Freeman Ng
753af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
754af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Show Activation Screen when phone powers up and OTA provision is
755af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * required. Also shown when activation fails and user needs
75613660626500d047d4a3a097e832bb175e1c4f894Freeman Ng     * to re-attempt it. Contains ACTIVATE and SKIP buttons
75713660626500d047d4a3a097e832bb175e1c4f894Freeman Ng     * which allow user to start OTA activation or skip the activation process.
758af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
759af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public void otaShowActivateScreen() {
7607c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        if (DBG) log("otaShowActivateScreen()...");
761af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (mApplication.cdmaOtaConfigData.otaShowActivationScreen
762af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                == OTA_SHOW_ACTIVATION_SCREEN_ON) {
7637c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            if (DBG) log("otaShowActivateScreen(): show activation screen");
764e4a6da04f5ed72f8be2e578b91d041493277e248Paul Berman            if (!isDialerOpened()) {
765af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                otaScreenInitialize();
766a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng                mOtaWidgetData.otaSkipButton.setVisibility(sIsWizardMode ?
76757a38778e8c9f58b24cea1062e451934cadc4b3dJim Miller                        View.VISIBLE : View.INVISIBLE);
768af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                mOtaWidgetData.otaTextActivate.setVisibility(View.VISIBLE);
769af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.VISIBLE);
770af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            }
771af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            mApplication.cdmaOtaScreenState.otaScreenState =
772af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION;
773af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        } else {
7747c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            if (DBG) log("otaShowActivateScreen(): show home screen");
775af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            otaShowHome();
776af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
777af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     }
778af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
779af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
780af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Show "Listen for Instruction" screen during OTA call. Shown when OTA Call
781af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * is initiated and user needs to listen for network instructions and press
782af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * appropriate DTMF digits to proceed to the "Programming in Progress" phase.
783af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
784af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private void otaShowListeningScreen() {
785b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (DBG) log("otaShowListeningScreen()...");
786b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (!mInteractive) {
787b154630235935e1aab2a41eff9ed794d40084a02David Brown            // We shouldn't ever get here in non-interactive mode!
788b154630235935e1aab2a41eff9ed794d40084a02David Brown            Log.w(LOG_TAG, "otaShowListeningScreen: not interactive!");
789b154630235935e1aab2a41eff9ed794d40084a02David Brown            return;
790b154630235935e1aab2a41eff9ed794d40084a02David Brown        }
791b154630235935e1aab2a41eff9ed794d40084a02David Brown
792af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (mApplication.cdmaOtaConfigData.otaShowListeningScreen
793af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                == OTA_SHOW_LISTENING_SCREEN_ON) {
7947c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            if (DBG) log("otaShowListeningScreen(): show listening screen");
795e4a6da04f5ed72f8be2e578b91d041493277e248Paul Berman            if (!isDialerOpened()) {
796af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                otaScreenInitialize();
7977c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown                mOtaWidgetData.otaTextListenProgress.setVisibility(View.VISIBLE);
798af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                mOtaWidgetData.otaTextListenProgress.setText(R.string.ota_listen);
799986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller                mOtaWidgetData.otaDtmfDialerView.setVisibility(View.VISIBLE);
800af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.VISIBLE);
801986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller                mOtaWidgetData.otaSpeakerButton.setVisibility(View.VISIBLE);
802a44a437fae34920b0ecbf66400ac50e10e5ae49eEric Laurent                boolean speakerOn = PhoneUtils.isSpeakerOn(mContext);
803a44a437fae34920b0ecbf66400ac50e10e5ae49eEric Laurent                mOtaWidgetData.otaSpeakerButton.setChecked(speakerOn);
804af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            }
805af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            mApplication.cdmaOtaScreenState.otaScreenState =
806af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    CdmaOtaScreenState.OtaScreenState.OTA_STATUS_LISTENING;
807af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        } else {
8087c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            if (DBG) log("otaShowListeningScreen(): show progress screen");
809af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            otaShowInProgressScreen();
810af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
811af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
812af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
813af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
814b154630235935e1aab2a41eff9ed794d40084a02David Brown     * Do any necessary updates (of onscreen UI, for example)
815b154630235935e1aab2a41eff9ed794d40084a02David Brown     * based on the latest status of the OTASP call.
816b154630235935e1aab2a41eff9ed794d40084a02David Brown     */
817b154630235935e1aab2a41eff9ed794d40084a02David Brown    private void updateOtaspProgress() {
818b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (DBG) log("updateOtaspProgress()...  mInteractive = " + mInteractive);
819b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (mInteractive) {
820b154630235935e1aab2a41eff9ed794d40084a02David Brown            // On regular phones we just call through to
821b154630235935e1aab2a41eff9ed794d40084a02David Brown            // otaShowInProgressScreen(), which updates the
822b154630235935e1aab2a41eff9ed794d40084a02David Brown            // InCallScreen's onscreen UI.
823b154630235935e1aab2a41eff9ed794d40084a02David Brown            otaShowInProgressScreen();
824b154630235935e1aab2a41eff9ed794d40084a02David Brown        } else {
825b154630235935e1aab2a41eff9ed794d40084a02David Brown            // We're not using the InCallScreen to show OTA progress.
826b154630235935e1aab2a41eff9ed794d40084a02David Brown
827b154630235935e1aab2a41eff9ed794d40084a02David Brown            // For now, at least, there's nothing to do here.
828b154630235935e1aab2a41eff9ed794d40084a02David Brown            // The overall "success" or "failure" indication we send back
829b154630235935e1aab2a41eff9ed794d40084a02David Brown            // (to our caller) is triggered by the DISCONNECT event;
830b154630235935e1aab2a41eff9ed794d40084a02David Brown            // see updateNonInteractiveOtaSuccessFailure().
831b154630235935e1aab2a41eff9ed794d40084a02David Brown
832b154630235935e1aab2a41eff9ed794d40084a02David Brown            // But if we ever need to send *intermediate* progress updates back
833b154630235935e1aab2a41eff9ed794d40084a02David Brown            // to our caller, we'd do that here, possbily using the same
834b154630235935e1aab2a41eff9ed794d40084a02David Brown            // PendingIntent that we already use to indicate success or failure.
835b154630235935e1aab2a41eff9ed794d40084a02David Brown        }
836b154630235935e1aab2a41eff9ed794d40084a02David Brown    }
837b154630235935e1aab2a41eff9ed794d40084a02David Brown
838b154630235935e1aab2a41eff9ed794d40084a02David Brown    /**
839b154630235935e1aab2a41eff9ed794d40084a02David Brown     * When a non-interactive OTASP call completes, send a success or
840b154630235935e1aab2a41eff9ed794d40084a02David Brown     * failure indication back to our caller.
841b154630235935e1aab2a41eff9ed794d40084a02David Brown     *
842b154630235935e1aab2a41eff9ed794d40084a02David Brown     * This is basically the non-interactive equivalent of
843b154630235935e1aab2a41eff9ed794d40084a02David Brown     * otaShowSuccessFailure().
844b154630235935e1aab2a41eff9ed794d40084a02David Brown     */
845b154630235935e1aab2a41eff9ed794d40084a02David Brown    private void updateNonInteractiveOtaSuccessFailure() {
846b154630235935e1aab2a41eff9ed794d40084a02David Brown        // This is basically the same logic as otaShowSuccessFailure(): we
847b154630235935e1aab2a41eff9ed794d40084a02David Brown        // check the isOtaCallCommitted bit, and if that's true it means
848b154630235935e1aab2a41eff9ed794d40084a02David Brown        // that activation was successful.
849b154630235935e1aab2a41eff9ed794d40084a02David Brown
850b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (DBG) log("updateNonInteractiveOtaSuccessFailure(): isOtaCallCommitted = "
851b154630235935e1aab2a41eff9ed794d40084a02David Brown                     + mApplication.cdmaOtaProvisionData.isOtaCallCommitted);
852b154630235935e1aab2a41eff9ed794d40084a02David Brown        int resultCode =
853b154630235935e1aab2a41eff9ed794d40084a02David Brown                mApplication.cdmaOtaProvisionData.isOtaCallCommitted
854b154630235935e1aab2a41eff9ed794d40084a02David Brown                ? OTASP_SUCCESS : OTASP_FAILURE;
855b154630235935e1aab2a41eff9ed794d40084a02David Brown        sendOtaspResult(resultCode);
856b154630235935e1aab2a41eff9ed794d40084a02David Brown    }
857b154630235935e1aab2a41eff9ed794d40084a02David Brown
858b154630235935e1aab2a41eff9ed794d40084a02David Brown    /**
859b154630235935e1aab2a41eff9ed794d40084a02David Brown     * Sends the specified OTASP result code back to our caller (presumably
860b154630235935e1aab2a41eff9ed794d40084a02David Brown     * SetupWizard) via the PendingIntent that they originally sent along with
861b154630235935e1aab2a41eff9ed794d40084a02David Brown     * the ACTION_PERFORM_CDMA_PROVISIONING intent.
862b154630235935e1aab2a41eff9ed794d40084a02David Brown     */
863b154630235935e1aab2a41eff9ed794d40084a02David Brown    private void sendOtaspResult(int resultCode) {
864b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (DBG) log("sendOtaspResult: resultCode = " + resultCode);
865b154630235935e1aab2a41eff9ed794d40084a02David Brown
866b154630235935e1aab2a41eff9ed794d40084a02David Brown        // Pass the success or failure indication back to our caller by
867b154630235935e1aab2a41eff9ed794d40084a02David Brown        // adding an additional extra to the PendingIntent we already
868b154630235935e1aab2a41eff9ed794d40084a02David Brown        // have.
869b154630235935e1aab2a41eff9ed794d40084a02David Brown        // (NB: there's a PendingIntent send() method that takes a resultCode
870b154630235935e1aab2a41eff9ed794d40084a02David Brown        // directly, but we can't use that here since that call is only
871b154630235935e1aab2a41eff9ed794d40084a02David Brown        // meaningful for pending intents that are actually used as activity
872b154630235935e1aab2a41eff9ed794d40084a02David Brown        // results.)
873b154630235935e1aab2a41eff9ed794d40084a02David Brown
874b154630235935e1aab2a41eff9ed794d40084a02David Brown        Intent extraStuff = new Intent();
875b154630235935e1aab2a41eff9ed794d40084a02David Brown        extraStuff.putExtra(EXTRA_OTASP_RESULT_CODE, resultCode);
876b154630235935e1aab2a41eff9ed794d40084a02David Brown        // When we call PendingIntent.send() below, the extras from this
877b154630235935e1aab2a41eff9ed794d40084a02David Brown        // intent will get merged with any extras already present in
878b154630235935e1aab2a41eff9ed794d40084a02David Brown        // cdmaOtaScreenState.otaspResultCodePendingIntent.
879b154630235935e1aab2a41eff9ed794d40084a02David Brown
880b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (mApplication.cdmaOtaScreenState == null) {
881b154630235935e1aab2a41eff9ed794d40084a02David Brown            Log.e(LOG_TAG, "updateNonInteractiveOtaSuccessFailure: no cdmaOtaScreenState object!");
882b154630235935e1aab2a41eff9ed794d40084a02David Brown            return;
883b154630235935e1aab2a41eff9ed794d40084a02David Brown        }
884b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (mApplication.cdmaOtaScreenState.otaspResultCodePendingIntent == null) {
885b154630235935e1aab2a41eff9ed794d40084a02David Brown            Log.w(LOG_TAG, "updateNonInteractiveOtaSuccessFailure: "
886b154630235935e1aab2a41eff9ed794d40084a02David Brown                  + "null otaspResultCodePendingIntent!");
887b154630235935e1aab2a41eff9ed794d40084a02David Brown            // This *should* never happen, since SetupWizard always passes this
888b154630235935e1aab2a41eff9ed794d40084a02David Brown            // PendingIntent along with the ACTION_PERFORM_CDMA_PROVISIONING
889b154630235935e1aab2a41eff9ed794d40084a02David Brown            // intent.
890b154630235935e1aab2a41eff9ed794d40084a02David Brown            // (But if this happens it's not a fatal error, it just means that
891b154630235935e1aab2a41eff9ed794d40084a02David Brown            // our original caller has no way of finding out whether the OTASP
892b154630235935e1aab2a41eff9ed794d40084a02David Brown            // call ultimately failed or succeeded...)
893b154630235935e1aab2a41eff9ed794d40084a02David Brown            return;
894b154630235935e1aab2a41eff9ed794d40084a02David Brown        }
895b154630235935e1aab2a41eff9ed794d40084a02David Brown
896b154630235935e1aab2a41eff9ed794d40084a02David Brown        try {
897b154630235935e1aab2a41eff9ed794d40084a02David Brown            if (DBG) log("- sendOtaspResult:  SENDING PENDING INTENT: " +
898b154630235935e1aab2a41eff9ed794d40084a02David Brown                         mApplication.cdmaOtaScreenState.otaspResultCodePendingIntent);
899b154630235935e1aab2a41eff9ed794d40084a02David Brown            mApplication.cdmaOtaScreenState.otaspResultCodePendingIntent.send(
900b154630235935e1aab2a41eff9ed794d40084a02David Brown                    mContext,
901b154630235935e1aab2a41eff9ed794d40084a02David Brown                    0, /* resultCode (unused) */
902b154630235935e1aab2a41eff9ed794d40084a02David Brown                    extraStuff);
903b154630235935e1aab2a41eff9ed794d40084a02David Brown        } catch (CanceledException e) {
904b154630235935e1aab2a41eff9ed794d40084a02David Brown            // should never happen because no code cancels the pending intent right now,
905b154630235935e1aab2a41eff9ed794d40084a02David Brown            Log.e(LOG_TAG, "PendingIntent send() failed: " + e);
906b154630235935e1aab2a41eff9ed794d40084a02David Brown        }
907b154630235935e1aab2a41eff9ed794d40084a02David Brown    }
908b154630235935e1aab2a41eff9ed794d40084a02David Brown
909b154630235935e1aab2a41eff9ed794d40084a02David Brown    /**
910af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Show "Programming In Progress" screen during OTA call. Shown when OTA
911af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * provisioning is in progress after user has selected an option.
912af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
913af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private void otaShowInProgressScreen() {
914b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (DBG) log("otaShowInProgressScreen()...");
915b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (!mInteractive) {
916b154630235935e1aab2a41eff9ed794d40084a02David Brown            // We shouldn't ever get here in non-interactive mode!
917b154630235935e1aab2a41eff9ed794d40084a02David Brown            Log.w(LOG_TAG, "otaShowInProgressScreen: not interactive!");
918b154630235935e1aab2a41eff9ed794d40084a02David Brown            return;
919b154630235935e1aab2a41eff9ed794d40084a02David Brown        }
920b154630235935e1aab2a41eff9ed794d40084a02David Brown
921211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        mApplication.cdmaOtaScreenState.otaScreenState =
922211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            CdmaOtaScreenState.OtaScreenState.OTA_STATUS_PROGRESS;
923211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
924211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if ((mOtaWidgetData == null) || (mInCallScreen == null)) {
925211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            Log.w(LOG_TAG, "otaShowInProgressScreen: UI widgets not set up yet!");
926211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
927211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            // TODO(OTASP): our CdmaOtaScreenState is now correct; we just set
928211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            // it to OTA_STATUS_PROGRESS.  But we still need to make sure that
929211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            // when the InCallScreen eventually comes to the foreground, it
930211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            // notices that state and does all the same UI updating we do below.
931211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            return;
932211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        }
933211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown
934e4a6da04f5ed72f8be2e578b91d041493277e248Paul Berman        if (!isDialerOpened()) {
935af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            otaScreenInitialize();
9367c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            mOtaWidgetData.otaTextListenProgress.setVisibility(View.VISIBLE);
937af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            mOtaWidgetData.otaTextListenProgress.setText(R.string.ota_progress);
938af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            mOtaWidgetData.otaTextProgressBar.setVisibility(View.VISIBLE);
939af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.VISIBLE);
9409bd141ba20a6cf6dcb745aca6c5c05a9c88f3a98Jim Miller            mOtaWidgetData.otaSpeakerButton.setVisibility(View.VISIBLE);
941a44a437fae34920b0ecbf66400ac50e10e5ae49eEric Laurent            boolean speakerOn = PhoneUtils.isSpeakerOn(mContext);
942a44a437fae34920b0ecbf66400ac50e10e5ae49eEric Laurent            mOtaWidgetData.otaSpeakerButton.setChecked(speakerOn);
943af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
944af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
945af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
946af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
947af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Show programming failure dialog when OTA provisioning fails.
948af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * If OTA provisioning attempts fail more than 3 times, then unsuccessful
949af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * dialog is shown. Otherwise a two-second notice is shown with unsuccessful
950af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * information. When notice expires, phone returns to activation screen.
951af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
952986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller    private void otaShowProgramFailure(int length) {
9537c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        if (DBG) log("otaShowProgramFailure()...");
954af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mApplication.cdmaOtaProvisionData.activationCount++;
955af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if ((mApplication.cdmaOtaProvisionData.activationCount <
956af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                mApplication.cdmaOtaConfigData.otaShowActivateFailTimes)
957af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                && (mApplication.cdmaOtaConfigData.otaShowActivationScreen ==
958af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                OTA_SHOW_ACTIVATION_SCREEN_ON)) {
9597c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            if (DBG) log("otaShowProgramFailure(): activationCount"
960af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    + mApplication.cdmaOtaProvisionData.activationCount);
9617c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            if (DBG) log("otaShowProgramFailure(): show failure notice");
962af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            otaShowProgramFailureNotice(length);
963af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        } else {
9647c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            if (DBG) log("otaShowProgramFailure(): show failure dialog");
965af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            otaShowProgramFailureDialog();
966af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
967af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
968af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
969af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
970af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Show either programming success dialog when OTA provisioning succeeds, or
971f0d315541b1b1f33fab5e7952471da6e886b53efWink Saville     * programming failure dialog when it fails. See {@link #otaShowProgramFailure}
972af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * for more details.
973af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
974af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public void otaShowSuccessFailure() {
975b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (DBG) log("otaShowSuccessFailure()...");
976b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (!mInteractive) {
977b154630235935e1aab2a41eff9ed794d40084a02David Brown            // We shouldn't ever get here in non-interactive mode!
978b154630235935e1aab2a41eff9ed794d40084a02David Brown            Log.w(LOG_TAG, "otaShowSuccessFailure: not interactive!");
979b154630235935e1aab2a41eff9ed794d40084a02David Brown            return;
980b154630235935e1aab2a41eff9ed794d40084a02David Brown        }
981b154630235935e1aab2a41eff9ed794d40084a02David Brown
982af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        otaScreenInitialize();
9837c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        if (DBG) log("otaShowSuccessFailure(): isOtaCallCommitted"
984af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                + mApplication.cdmaOtaProvisionData.isOtaCallCommitted);
985af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (mApplication.cdmaOtaProvisionData.isOtaCallCommitted) {
9867c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            if (DBG) log("otaShowSuccessFailure(), show success dialog");
987af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            otaShowProgramSuccessDialog();
988af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        } else {
9897c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            if (DBG) log("otaShowSuccessFailure(), show failure dialog");
990af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            otaShowProgramFailure(OTA_FAILURE_DIALOG_TIMEOUT);
991af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
992af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        return;
993af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
994af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
995af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
996af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Show programming failure dialog when OTA provisioning fails more than 3
997af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * times.
998af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
999af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private void otaShowProgramFailureDialog() {
10007c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        if (DBG) log("otaShowProgramFailureDialog()...");
1001af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mApplication.cdmaOtaScreenState.otaScreenState =
1002af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG;
1003986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mOtaWidgetData.otaTitle.setText(R.string.ota_title_problem_with_activation);
1004af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaTextSuccessFail.setVisibility(View.VISIBLE);
1005af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaTextSuccessFail.setText(R.string.ota_unsuccessful);
1006af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.VISIBLE);
1007986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mOtaWidgetData.otaTryAgainButton.setVisibility(View.VISIBLE);
1008af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        //close the dialer if open
1009e4a6da04f5ed72f8be2e578b91d041493277e248Paul Berman        if (isDialerOpened()) {
10107c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            mOtaCallCardDtmfDialer.closeDialer(false);
1011af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
1012af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1013af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1014af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
1015af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Show programming success dialog when OTA provisioning succeeds.
1016af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
1017af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private void otaShowProgramSuccessDialog() {
10187c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        if (DBG) log("otaShowProgramSuccessDialog()...");
1019af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mApplication.cdmaOtaScreenState.otaScreenState =
1020af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG;
1021986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mOtaWidgetData.otaTitle.setText(R.string.ota_title_activate_success);
1022af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaTextSuccessFail.setVisibility(View.VISIBLE);
1023af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaTextSuccessFail.setText(R.string.ota_successful);
1024af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.VISIBLE);
1025986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mOtaWidgetData.otaNextButton.setVisibility(View.VISIBLE);
1026af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        //close the dialer if open
1027e4a6da04f5ed72f8be2e578b91d041493277e248Paul Berman        if (isDialerOpened()) {
10287c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            mOtaCallCardDtmfDialer.closeDialer(false);
1029af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
1030af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1031af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1032af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
1033af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Show SPC failure notice when SPC attempts exceed 15 times.
1034af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * During OTA provisioning, if SPC code is incorrect OTA provisioning will
1035af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * fail. When SPC attempts are over 15, it shows SPC failure notice for one minute and
1036af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * then phone will power down.
1037af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
1038af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private void otaShowSpcErrorNotice(int length) {
10397c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        if (DBG) log("otaShowSpcErrorNotice()...");
1040af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (mOtaWidgetData.spcErrorDialog == null) {
1041af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            mApplication.cdmaOtaProvisionData.inOtaSpcState = true;
1042af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            DialogInterface.OnKeyListener keyListener;
1043af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            keyListener = new DialogInterface.OnKeyListener() {
1044af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
1045af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    log("Ignoring key events...");
1046af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    return true;
1047af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                }};
1048af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            mOtaWidgetData.spcErrorDialog = new AlertDialog.Builder(mInCallScreen)
1049af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    .setMessage(R.string.ota_spc_failure)
1050af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    .setOnKeyListener(keyListener)
1051af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    .create();
1052af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            mOtaWidgetData.spcErrorDialog.getWindow().addFlags(
1053af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
1054af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
1055af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            mOtaWidgetData.spcErrorDialog.show();
1056af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            //close the dialer if open
1057e4a6da04f5ed72f8be2e578b91d041493277e248Paul Berman            if (isDialerOpened()) {
10587c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown                mOtaCallCardDtmfDialer.closeDialer(false);
1059af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            }
1060af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            long noticeTime = length*1000;
10617c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            if (DBG) log("otaShowSpcErrorNotice(), remaining SPC noticeTime" + noticeTime);
1062325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown            mInCallScreen.requestCloseSpcErrorNotice(noticeTime);
1063af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
1064af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1065af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1066af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
1067af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * When SPC notice times out, force phone to power down.
1068af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
1069af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public void onOtaCloseSpcNotice() {
107017c36a10d09fac3e2312c0bcb839e0a704f42105w        if (DBG) log("onOtaCloseSpcNotice(), send shutdown intent");
107117c36a10d09fac3e2312c0bcb839e0a704f42105w        Intent shutdown = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
107217c36a10d09fac3e2312c0bcb839e0a704f42105w        shutdown.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
107317c36a10d09fac3e2312c0bcb839e0a704f42105w        shutdown.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
107417c36a10d09fac3e2312c0bcb839e0a704f42105w        mContext.startActivity(shutdown);
1075af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1076af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1077af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
1078af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Show two-second notice when OTA provisioning fails and number of failed attempts
1079af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * is less then 3.
1080af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
1081af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private void otaShowProgramFailureNotice(int length) {
10827c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        if (DBG) log("otaShowProgramFailureNotice()...");
1083af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (mOtaWidgetData.otaFailureDialog == null) {
1084af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            mOtaWidgetData.otaFailureDialog = new AlertDialog.Builder(mInCallScreen)
1085af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    .setMessage(R.string.ota_failure)
1086af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    .create();
1087af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            mOtaWidgetData.otaFailureDialog.getWindow().addFlags(
1088af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
1089af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
1090af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            mOtaWidgetData.otaFailureDialog.show();
1091af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1092af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            long noticeTime = length*1000;
1093325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown            mInCallScreen.requestCloseOtaFailureNotice(noticeTime);
1094af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
1095af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1096af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1097af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
1098af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Handle OTA unsuccessful notice expiry. Dismisses the
1099af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * two-second notice and shows the activation screen.
1100af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
1101af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public void onOtaCloseFailureNotice() {
1102af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (DBG) log("onOtaCloseFailureNotice()...");
1103af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (mOtaWidgetData.otaFailureDialog != null) {
1104af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            mOtaWidgetData.otaFailureDialog.dismiss();
1105af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            mOtaWidgetData.otaFailureDialog = null;
1106af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
1107af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        otaShowActivateScreen();
1108af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1109af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1110af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
1111af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Initialize all OTA UI elements to be gone. Also set inCallPanel,
11128df5c508da2c836b841ee24120fa7c5cc92df387David Brown     * callCard and the dialpad handle to be gone. This is called before any OTA screen
1113af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * gets drawn.
1114af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
1115af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private void otaScreenInitialize() {
1116b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (DBG) log("otaScreenInitialize()...");
1117b154630235935e1aab2a41eff9ed794d40084a02David Brown
1118b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (!mInteractive) {
1119b154630235935e1aab2a41eff9ed794d40084a02David Brown            // We should never be doing anything with UI elements in
1120b154630235935e1aab2a41eff9ed794d40084a02David Brown            // non-interactive mode.
1121b154630235935e1aab2a41eff9ed794d40084a02David Brown            Log.w(LOG_TAG, "otaScreenInitialize: not interactive!");
1122b154630235935e1aab2a41eff9ed794d40084a02David Brown            return;
1123b154630235935e1aab2a41eff9ed794d40084a02David Brown        }
1124af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1125af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (mInCallPanel != null) mInCallPanel.setVisibility(View.GONE);
1126ed6c435b8ce38a269982385071b720cc98819239David Brown        if (mInCallTouchUi != null) mInCallTouchUi.setVisibility(View.GONE);
1127af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (mCallCard != null) mCallCard.hideCallCardElements();
1128af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1129986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mOtaWidgetData.otaTitle.setText(R.string.ota_title_activate);
1130af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaTextActivate.setVisibility(View.GONE);
11317c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        mOtaWidgetData.otaTextListenProgress.setVisibility(View.GONE);
1132af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaTextProgressBar.setVisibility(View.GONE);
1133af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaTextSuccessFail.setVisibility(View.GONE);
1134af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.GONE);
1135af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE);
1136af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE);
1137986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mOtaWidgetData.otaDtmfDialerView.setVisibility(View.GONE);
1138986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mOtaWidgetData.otaSpeakerButton.setVisibility(View.GONE);
1139986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mOtaWidgetData.otaTryAgainButton.setVisibility(View.GONE);
1140986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mOtaWidgetData.otaNextButton.setVisibility(View.GONE);
11417c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        mOtaWidgetData.otaUpperWidgets.setVisibility(View.VISIBLE);
114213660626500d047d4a3a097e832bb175e1c4f894Freeman Ng        mOtaWidgetData.otaSkipButton.setVisibility(View.VISIBLE);
1143af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1144af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1145af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public void hideOtaScreen() {
1146af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (DBG) log("hideOtaScreen()...");
1147af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1148af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.GONE);
1149af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE);
1150af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE);
11517c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        mOtaWidgetData.otaUpperWidgets.setVisibility(View.GONE);
1152af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1153af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1154e4a6da04f5ed72f8be2e578b91d041493277e248Paul Berman    public boolean isDialerOpened() {
11557c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        boolean retval = (mOtaCallCardDtmfDialer != null && mOtaCallCardDtmfDialer.isOpened());
11567c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        if (DBG) log("- isDialerOpened() ==> " + retval);
11577c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        return retval;
1158e4a6da04f5ed72f8be2e578b91d041493277e248Paul Berman    }
1159e4a6da04f5ed72f8be2e578b91d041493277e248Paul Berman
1160af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
1161af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Show the appropriate OTA screen based on the current state of OTA call.
1162b154630235935e1aab2a41eff9ed794d40084a02David Brown     *
1163b154630235935e1aab2a41eff9ed794d40084a02David Brown     * This is called from the InCallScreen when the screen needs to be
1164b154630235935e1aab2a41eff9ed794d40084a02David Brown     * refreshed (and thus is only ever used in interactive mode.)
1165ed6c435b8ce38a269982385071b720cc98819239David Brown     *
1166ed6c435b8ce38a269982385071b720cc98819239David Brown     * Since this is called as part of the InCallScreen.updateScreen() sequence,
1167ed6c435b8ce38a269982385071b720cc98819239David Brown     * this method does *not* post an mInCallScreen.requestUpdateScreen()
1168ed6c435b8ce38a269982385071b720cc98819239David Brown     * request.
1169af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
1170af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public void otaShowProperScreen() {
1171af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (DBG) log("otaShowProperScreen()...");
1172b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (!mInteractive) {
1173b154630235935e1aab2a41eff9ed794d40084a02David Brown            // We shouldn't ever get here in non-interactive mode!
1174b154630235935e1aab2a41eff9ed794d40084a02David Brown            Log.w(LOG_TAG, "otaShowProperScreen: not interactive!");
1175b154630235935e1aab2a41eff9ed794d40084a02David Brown            return;
1176b154630235935e1aab2a41eff9ed794d40084a02David Brown        }
1177b154630235935e1aab2a41eff9ed794d40084a02David Brown
1178211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if ((mInCallScreen != null) && mInCallScreen.isForegroundActivity()) {
1179211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            if (DBG) log("otaShowProperScreen(): InCallScreen in foreground, currentstate = "
1180af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    + mApplication.cdmaOtaScreenState.otaScreenState);
1181af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            if (mInCallPanel != null) {
1182af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                mInCallPanel.setVisibility(View.GONE);
1183af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            }
1184ed6c435b8ce38a269982385071b720cc98819239David Brown            if (mInCallTouchUi != null) {
1185ed6c435b8ce38a269982385071b720cc98819239David Brown                mInCallTouchUi.setVisibility(View.GONE);
1186ed6c435b8ce38a269982385071b720cc98819239David Brown            }
1187af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            if (mApplication.cdmaOtaScreenState.otaScreenState
1188af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION) {
1189af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                otaShowActivateScreen();
1190af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            } else if (mApplication.cdmaOtaScreenState.otaScreenState
1191af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_LISTENING) {
1192af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                otaShowListeningScreen();
1193af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            } else if (mApplication.cdmaOtaScreenState.otaScreenState
1194af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_PROGRESS) {
1195af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                otaShowInProgressScreen();
1196af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            }
1197af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1198af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            if (mApplication.cdmaOtaProvisionData.inOtaSpcState) {
1199af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                otaShowSpcErrorNotice(getOtaSpcDisplayTime());
1200af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            }
1201af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
1202af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1203af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1204af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
1205af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Read configuration values for each OTA screen from config.xml.
1206af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * These configuration values control visibility of each screen.
1207af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
1208af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private void readXmlSettings() {
1209af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (DBG) log("readXmlSettings()...");
1210af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (mApplication.cdmaOtaConfigData.configComplete) {
1211af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            return;
1212af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
1213af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1214af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mApplication.cdmaOtaConfigData.configComplete = true;
1215af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        int tmpOtaShowActivationScreen =
1216af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                mContext.getResources().getInteger(R.integer.OtaShowActivationScreen);
1217af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mApplication.cdmaOtaConfigData.otaShowActivationScreen = tmpOtaShowActivationScreen;
12187c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        if (DBG) log("readXmlSettings(), otaShowActivationScreen = "
1219af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                + mApplication.cdmaOtaConfigData.otaShowActivationScreen);
1220af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1221af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        int tmpOtaShowListeningScreen =
1222af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                mContext.getResources().getInteger(R.integer.OtaShowListeningScreen);
1223af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mApplication.cdmaOtaConfigData.otaShowListeningScreen = tmpOtaShowListeningScreen;
12247c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        if (DBG) log("readXmlSettings(), otaShowListeningScreen = "
1225af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                + mApplication.cdmaOtaConfigData.otaShowListeningScreen);
1226af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1227af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        int tmpOtaShowActivateFailTimes =
1228af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                mContext.getResources().getInteger(R.integer.OtaShowActivateFailTimes);
1229af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mApplication.cdmaOtaConfigData.otaShowActivateFailTimes = tmpOtaShowActivateFailTimes;
12307c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        if (DBG) log("readXmlSettings(), otaShowActivateFailTimes = "
1231af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                + mApplication.cdmaOtaConfigData.otaShowActivateFailTimes);
1232af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1233af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        int tmpOtaPlaySuccessFailureTone =
1234af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                mContext.getResources().getInteger(R.integer.OtaPlaySuccessFailureTone);
1235af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mApplication.cdmaOtaConfigData.otaPlaySuccessFailureTone = tmpOtaPlaySuccessFailureTone;
12367c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        if (DBG) log("readXmlSettings(), otaPlaySuccessFailureTone = "
1237af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                + mApplication.cdmaOtaConfigData.otaPlaySuccessFailureTone);
1238af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1239af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1240af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
1241af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Handle the click events for OTA buttons.
1242af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
1243af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public void onClickHandler(int id) {
1244af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        switch (id) {
1245af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            case R.id.otaEndButton:
1246af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                onClickOtaEndButton();
1247af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                break;
1248af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1249af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            case R.id.otaSpeakerButton:
1250af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                onClickOtaSpeakerButton();
1251af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                break;
1252af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1253af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            case R.id.otaActivateButton:
1254af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                onClickOtaActivateButton();
1255af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                break;
1256af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
125713660626500d047d4a3a097e832bb175e1c4f894Freeman Ng            case R.id.otaSkipButton:
125813660626500d047d4a3a097e832bb175e1c4f894Freeman Ng                onClickOtaActivateSkipButton();
1259af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                break;
1260af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1261986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller            case R.id.otaNextButton:
1262986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller                onClickOtaActivateNextButton();
1263af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                break;
1264af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1265986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller            case R.id.otaTryAgainButton:
1266986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller                onClickOtaTryAgainButton();
1267af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                break;
1268af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1269af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            default:
1270af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                if (DBG) log ("onClickHandler: received a click event for unrecognized id");
1271af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                break;
1272af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
1273af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1274af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1275986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller    private void onClickOtaTryAgainButton() {
1276986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        if (DBG) log("Activation Try Again Clicked!");
1277986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
1278986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller            otaShowActivateScreen();
1279986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        }
1280986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller    }
1281986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller
1282af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private void onClickOtaEndButton() {
1283986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        if (DBG) log("Activation End Call Button Clicked!");
1284af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
12858343169cc89621d46dce86449f5ee1ff5d3a4919John Wang            if (PhoneUtils.hangup(mApplication.mCM) == false) {
1286a44a437fae34920b0ecbf66400ac50e10e5ae49eEric Laurent                // If something went wrong when placing the OTA call,
1287a44a437fae34920b0ecbf66400ac50e10e5ae49eEric Laurent                // the screen is not updated by the call disconnect
1288a44a437fae34920b0ecbf66400ac50e10e5ae49eEric Laurent                // handler and we have to do it here
1289a44a437fae34920b0ecbf66400ac50e10e5ae49eEric Laurent                setSpeaker(false);
1290a44a437fae34920b0ecbf66400ac50e10e5ae49eEric Laurent                mInCallScreen.handleOtaCallEnd();
1291a44a437fae34920b0ecbf66400ac50e10e5ae49eEric Laurent            }
1292af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
1293af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1294af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1295af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private void onClickOtaSpeakerButton() {
1296af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (DBG) log("OTA Speaker button Clicked!");
1297af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
1298af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            boolean isChecked = !PhoneUtils.isSpeakerOn(mContext);
1299af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            setSpeaker(isChecked);
1300af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
1301af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1302af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1303af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private void onClickOtaActivateButton() {
1304af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (DBG) log("Call Activation Clicked!");
130513660626500d047d4a3a097e832bb175e1c4f894Freeman Ng        otaPerformActivation();
1306af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1307af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
130813660626500d047d4a3a097e832bb175e1c4f894Freeman Ng    private void onClickOtaActivateSkipButton() {
130913660626500d047d4a3a097e832bb175e1c4f894Freeman Ng        if (DBG) log("Activation Skip Clicked!");
131013660626500d047d4a3a097e832bb175e1c4f894Freeman Ng        DialogInterface.OnKeyListener keyListener;
131113660626500d047d4a3a097e832bb175e1c4f894Freeman Ng        keyListener = new DialogInterface.OnKeyListener() {
131213660626500d047d4a3a097e832bb175e1c4f894Freeman Ng            public boolean onKey(DialogInterface dialog, int keyCode,
131313660626500d047d4a3a097e832bb175e1c4f894Freeman Ng                    KeyEvent event) {
131413660626500d047d4a3a097e832bb175e1c4f894Freeman Ng                if (DBG) log("Ignoring key events...");
131513660626500d047d4a3a097e832bb175e1c4f894Freeman Ng                return true;
131613660626500d047d4a3a097e832bb175e1c4f894Freeman Ng            }
131713660626500d047d4a3a097e832bb175e1c4f894Freeman Ng        };
131813660626500d047d4a3a097e832bb175e1c4f894Freeman Ng        mOtaWidgetData.otaSkipConfirmationDialog = new AlertDialog.Builder(mInCallScreen)
131913660626500d047d4a3a097e832bb175e1c4f894Freeman Ng                .setTitle(R.string.ota_skip_activation_dialog_title)
132013660626500d047d4a3a097e832bb175e1c4f894Freeman Ng                .setMessage(R.string.ota_skip_activation_dialog_message)
132113660626500d047d4a3a097e832bb175e1c4f894Freeman Ng                .setPositiveButton(
1322d23dc59768909d8e18b42c908764c7d340935796David Brown                    android.R.string.ok,
1323d23dc59768909d8e18b42c908764c7d340935796David Brown                    // "OK" means "skip activation".
132413660626500d047d4a3a097e832bb175e1c4f894Freeman Ng                    new AlertDialog.OnClickListener() {
132513660626500d047d4a3a097e832bb175e1c4f894Freeman Ng                        public void onClick(DialogInterface dialog, int which) {
132613660626500d047d4a3a097e832bb175e1c4f894Freeman Ng                            otaSkipActivation();
132713660626500d047d4a3a097e832bb175e1c4f894Freeman Ng                        }
132813660626500d047d4a3a097e832bb175e1c4f894Freeman Ng                    })
132913660626500d047d4a3a097e832bb175e1c4f894Freeman Ng                .setNegativeButton(
1330d23dc59768909d8e18b42c908764c7d340935796David Brown                    android.R.string.cancel,
1331d23dc59768909d8e18b42c908764c7d340935796David Brown                    // "Cancel" means just dismiss the dialog.
1332d23dc59768909d8e18b42c908764c7d340935796David Brown                    // Don't actually start an activation call.
1333d23dc59768909d8e18b42c908764c7d340935796David Brown                    null)
133413660626500d047d4a3a097e832bb175e1c4f894Freeman Ng                .setOnKeyListener(keyListener)
133513660626500d047d4a3a097e832bb175e1c4f894Freeman Ng                .create();
133613660626500d047d4a3a097e832bb175e1c4f894Freeman Ng        mOtaWidgetData.otaSkipConfirmationDialog.show();
1337af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1338af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1339986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller    private void onClickOtaActivateNextButton() {
1340986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        if (DBG) log("Dialog Next Clicked!");
1341af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
1342af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            mApplication.cdmaOtaScreenState.otaScreenState =
1343af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                    CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED;
1344af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            otaShowHome();
1345af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
1346af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1347af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1348af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public void dismissAllOtaDialogs() {
1349211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if (mOtaWidgetData != null) {
1350211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            if (mOtaWidgetData.spcErrorDialog != null) {
1351211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown                if (DBG) log("- DISMISSING mSpcErrorDialog.");
1352211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown                mOtaWidgetData.spcErrorDialog.dismiss();
1353211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown                mOtaWidgetData.spcErrorDialog = null;
1354211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            }
1355211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            if (mOtaWidgetData.otaFailureDialog != null) {
1356211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown                if (DBG) log("- DISMISSING mOtaFailureDialog.");
1357211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown                mOtaWidgetData.otaFailureDialog.dismiss();
1358211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown                mOtaWidgetData.otaFailureDialog = null;
1359211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown            }
1360af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
1361af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1362af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1363af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private int getOtaSpcDisplayTime() {
1364af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (DBG) log("getOtaSpcDisplayTime()...");
1365af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        int tmpSpcTime = 1;
1366af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (mApplication.cdmaOtaProvisionData.inOtaSpcState) {
1367af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            long tmpOtaSpcRunningTime = 0;
1368af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            long tmpOtaSpcLeftTime = 0;
1369af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            tmpOtaSpcRunningTime = SystemClock.elapsedRealtime();
1370af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            tmpOtaSpcLeftTime =
1371af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                tmpOtaSpcRunningTime - mApplication.cdmaOtaProvisionData.otaSpcUptime;
137217c36a10d09fac3e2312c0bcb839e0a704f42105w            if (tmpOtaSpcLeftTime >= OTA_SPC_TIMEOUT*1000) {
1373af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                tmpSpcTime = 1;
1374af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            } else {
1375af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                tmpSpcTime = OTA_SPC_TIMEOUT - (int)tmpOtaSpcLeftTime/1000;
1376af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            }
1377af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
1378af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (DBG) log("getOtaSpcDisplayTime(), time for SPC error notice: " + tmpSpcTime);
1379af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        return tmpSpcTime;
1380af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1381af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1382af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
1383af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Initialize the OTA widgets for all OTA screens.
1384af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
1385af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private void initOtaInCallScreen() {
1386af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (DBG) log("initOtaInCallScreen()...");
1387986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mOtaWidgetData.otaTitle = (TextView) mInCallScreen.findViewById(R.id.otaTitle);
1388af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaTextActivate = (TextView) mInCallScreen.findViewById(R.id.otaActivate);
1389af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaTextActivate.setVisibility(View.GONE);
1390af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaTextListenProgress =
1391af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                (TextView) mInCallScreen.findViewById(R.id.otaListenProgress);
1392af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaTextProgressBar =
1393af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                (ProgressBar) mInCallScreen.findViewById(R.id.progress_large);
1394af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaTextProgressBar.setIndeterminate(true);
1395af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaTextSuccessFail =
1396af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                (TextView) mInCallScreen.findViewById(R.id.otaSuccessFailStatus);
1397af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
13987c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        mOtaWidgetData.otaUpperWidgets =
13997c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown                (ViewGroup) mInCallScreen.findViewById(R.id.otaUpperWidgets);
1400af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.callCardOtaButtonsListenProgress =
1401af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                (View) mInCallScreen.findViewById(R.id.callCardOtaListenProgress);
1402af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.callCardOtaButtonsActivate =
1403af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                (View) mInCallScreen.findViewById(R.id.callCardOtaActivate);
1404af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.callCardOtaButtonsFailSuccess =
1405af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                (View) mInCallScreen.findViewById(R.id.callCardOtaFailOrSuccessful);
1406af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1407af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaEndButton = (Button) mInCallScreen.findViewById(R.id.otaEndButton);
1408af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaEndButton.setOnClickListener(mInCallScreen);
1409af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaSpeakerButton =
1410af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                (ToggleButton) mInCallScreen.findViewById(R.id.otaSpeakerButton);
1411af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaSpeakerButton.setOnClickListener(mInCallScreen);
1412af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaActivateButton =
1413af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville                (Button) mInCallScreen.findViewById(R.id.otaActivateButton);
1414af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        mOtaWidgetData.otaActivateButton.setOnClickListener(mInCallScreen);
141513660626500d047d4a3a097e832bb175e1c4f894Freeman Ng        mOtaWidgetData.otaSkipButton = (Button) mInCallScreen.findViewById(R.id.otaSkipButton);
141613660626500d047d4a3a097e832bb175e1c4f894Freeman Ng        mOtaWidgetData.otaSkipButton.setOnClickListener(mInCallScreen);
1417986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mOtaWidgetData.otaNextButton = (Button) mInCallScreen.findViewById(R.id.otaNextButton);
1418986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mOtaWidgetData.otaNextButton.setOnClickListener(mInCallScreen);
1419986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mOtaWidgetData.otaTryAgainButton =
1420986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller                (Button) mInCallScreen.findViewById(R.id.otaTryAgainButton);
1421986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mOtaWidgetData.otaTryAgainButton.setOnClickListener(mInCallScreen);
1422a44a437fae34920b0ecbf66400ac50e10e5ae49eEric Laurent
1423dfa83d531cdb88513f09e913424b7a16628b37d3David Brown        mOtaWidgetData.otaDtmfDialerView =
14247c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown                (DTMFTwelveKeyDialerView) mInCallScreen.findViewById(R.id.otaDtmfDialerView);
14257c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown        // Sanity-check: the otaDtmfDialerView widget should *always* be present.
1426dfa83d531cdb88513f09e913424b7a16628b37d3David Brown        if (mOtaWidgetData.otaDtmfDialerView == null) {
14277c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            throw new IllegalStateException("initOtaInCallScreen: couldn't find otaDtmfDialerView");
1428af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
14292f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown
14302f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown        // Create a new DTMFTwelveKeyDialer instance purely for use by the
14312f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown        // DTMFTwelveKeyDialerView ("otaDtmfDialerView") that comes from
14322f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown        // otacall_card.xml.
14332f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown        mOtaCallCardDtmfDialer = new DTMFTwelveKeyDialer(mInCallScreen,
14344ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown                                                         mOtaWidgetData.otaDtmfDialerView);
14352f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown
14362f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown        // Initialize the new DTMFTwelveKeyDialer instance.  This is
14372f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown        // needed to play local DTMF tones.
14382f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown        mOtaCallCardDtmfDialer.startDialerSession();
14392f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown
14402f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown        mOtaWidgetData.otaDtmfDialerView.setDialer(mOtaCallCardDtmfDialer);
1441af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1442af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1443af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
1444af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Clear out all OTA UI widget elements. Needs to get called
1445af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * when OTA call ends or InCallScreen is destroyed.
14464a5a966f0d43e04d336be1b94182346399a931f6Wink Saville     * @param disableSpeaker parameter control whether Speaker should be turned off.
1447af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
14484a5a966f0d43e04d336be1b94182346399a931f6Wink Saville    public void cleanOtaScreen(boolean disableSpeaker) {
1449af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if (DBG) log("OTA ends, cleanOtaScreen!");
1450af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1451986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mApplication.cdmaOtaScreenState.otaScreenState =
1452986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller                CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED;
1453986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mApplication.cdmaOtaProvisionData.isOtaCallCommitted = false;
1454986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mApplication.cdmaOtaProvisionData.isOtaCallIntentProcessed = false;
1455986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mApplication.cdmaOtaProvisionData.inOtaSpcState = false;
1456986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mApplication.cdmaOtaProvisionData.activationCount = 0;
1457986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller        mApplication.cdmaOtaProvisionData.otaSpcUptime = 0;
14585c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville        mApplication.cdmaOtaInCallScreenUiState.state = State.UNDEFINED;
1459986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller
1460211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown        if (mInteractive && (mOtaWidgetData != null)) {
1461b154630235935e1aab2a41eff9ed794d40084a02David Brown            if (mInCallPanel != null) mInCallPanel.setVisibility(View.VISIBLE);
1462ed6c435b8ce38a269982385071b720cc98819239David Brown            if (mInCallTouchUi != null) mInCallTouchUi.setVisibility(View.VISIBLE);
1463b154630235935e1aab2a41eff9ed794d40084a02David Brown            if (mCallCard != null) mCallCard.hideCallCardElements();
1464986d2f46bd9572b563b89627fa60a9ea0853a91fJim Miller
1465b154630235935e1aab2a41eff9ed794d40084a02David Brown            // Free resources from the DTMFTwelveKeyDialer instance we created
1466b154630235935e1aab2a41eff9ed794d40084a02David Brown            // in initOtaInCallScreen().
1467b154630235935e1aab2a41eff9ed794d40084a02David Brown            if (mOtaCallCardDtmfDialer != null) {
1468b154630235935e1aab2a41eff9ed794d40084a02David Brown                mOtaCallCardDtmfDialer.stopDialerSession();
1469b154630235935e1aab2a41eff9ed794d40084a02David Brown            }
14702f22a9001166458ef4b04f6142b6d6a480af1c9dDavid Brown
1471b154630235935e1aab2a41eff9ed794d40084a02David Brown            mOtaWidgetData.otaTextActivate.setVisibility(View.GONE);
14727c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            mOtaWidgetData.otaTextListenProgress.setVisibility(View.GONE);
1473b154630235935e1aab2a41eff9ed794d40084a02David Brown            mOtaWidgetData.otaTextProgressBar.setVisibility(View.GONE);
1474b154630235935e1aab2a41eff9ed794d40084a02David Brown            mOtaWidgetData.otaTextSuccessFail.setVisibility(View.GONE);
1475b154630235935e1aab2a41eff9ed794d40084a02David Brown            mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.GONE);
1476b154630235935e1aab2a41eff9ed794d40084a02David Brown            mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE);
1477b154630235935e1aab2a41eff9ed794d40084a02David Brown            mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE);
14787c8cb32060a685b2f20c1e0cf181fc392be840e0David Brown            mOtaWidgetData.otaUpperWidgets.setVisibility(View.GONE);
1479b154630235935e1aab2a41eff9ed794d40084a02David Brown            mOtaWidgetData.otaDtmfDialerView.setVisibility(View.GONE);
1480b154630235935e1aab2a41eff9ed794d40084a02David Brown            mOtaWidgetData.otaNextButton.setVisibility(View.GONE);
1481b154630235935e1aab2a41eff9ed794d40084a02David Brown            mOtaWidgetData.otaTryAgainButton.setVisibility(View.GONE);
1482b154630235935e1aab2a41eff9ed794d40084a02David Brown        }
1483a44a437fae34920b0ecbf66400ac50e10e5ae49eEric Laurent
1484a44a437fae34920b0ecbf66400ac50e10e5ae49eEric Laurent        // turn off the speaker in case it was turned on
1485a44a437fae34920b0ecbf66400ac50e10e5ae49eEric Laurent        // but the OTA call could not be completed
14864a5a966f0d43e04d336be1b94182346399a931f6Wink Saville        if (disableSpeaker) {
14874a5a966f0d43e04d336be1b94182346399a931f6Wink Saville            setSpeaker(false);
14884a5a966f0d43e04d336be1b94182346399a931f6Wink Saville        }
1489af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1490af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1491af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
1492af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Defines OTA information that needs to be maintained during
1493af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * an OTA call when display orientation changes.
1494af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
1495af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public static class CdmaOtaProvisionData {
1496af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public boolean isOtaCallCommitted;
1497af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public boolean isOtaCallIntentProcessed;
1498af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public boolean inOtaSpcState;
1499af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public int activationCount;
1500af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public long otaSpcUptime;
1501af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1502af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1503af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
1504af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Defines OTA screen configuration items read from config.xml
1505af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * and used to control OTA display.
1506af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
1507af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public static class CdmaOtaConfigData {
1508af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public int otaShowActivationScreen;
1509af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public int otaShowListeningScreen;
1510af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public int otaShowActivateFailTimes;
1511af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public int otaPlaySuccessFailureTone;
1512af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public boolean configComplete;
1513af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public CdmaOtaConfigData() {
1514af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            if (DBG) log("CdmaOtaConfigData constructor!");
1515af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            otaShowActivationScreen = OTA_SHOW_ACTIVATION_SCREEN_OFF;
1516af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            otaShowListeningScreen = OTA_SHOW_LISTENING_SCREEN_OFF;
1517af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            otaShowActivateFailTimes = OTA_SHOW_ACTIVATE_FAIL_COUNT_OFF;
1518af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            otaPlaySuccessFailureTone = OTA_PLAY_SUCCESS_FAILURE_TONE_OFF;
1519af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
1520af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1521af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1522af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
1523f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville     * The state of the OTA InCallScreen UI.
1524f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville     */
1525f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville    public static class CdmaOtaInCallScreenUiState {
1526f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville        public enum State {
1527f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville            UNDEFINED,
1528f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville            NORMAL,
1529f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville            ENDED
1530f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville        }
1531f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville
1532f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville        public State state;
1533f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville
1534f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville        public CdmaOtaInCallScreenUiState() {
1535f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville            if (DBG) log("CdmaOtaInCallScreenState: constructor init to UNDEFINED");
1536f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville            state = CdmaOtaInCallScreenUiState.State.UNDEFINED;
1537f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville        }
1538f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville    }
1539f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville
1540f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville    /**
1541f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville     * Save the Ota InCallScreen UI state
1542f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville     */
1543f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville    public void setCdmaOtaInCallScreenUiState(CdmaOtaInCallScreenUiState.State state) {
1544f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville        if (DBG) log("setCdmaOtaInCallScreenState: " + state);
1545f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville        mApplication.cdmaOtaInCallScreenUiState.state = state;
1546f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville    }
1547f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville
1548f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville    /**
1549f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville     * Get the Ota InCallScreen UI state
1550f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville     */
1551f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville    public CdmaOtaInCallScreenUiState.State getCdmaOtaInCallScreenUiState() {
1552b154630235935e1aab2a41eff9ed794d40084a02David Brown        if (DBG) log("getCdmaOtaInCallScreenState: "
1553b154630235935e1aab2a41eff9ed794d40084a02David Brown                     + mApplication.cdmaOtaInCallScreenUiState.state);
1554f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville        return mApplication.cdmaOtaInCallScreenUiState.state;
1555f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville    }
1556f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville
1557f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville    /**
1558af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * The OTA screen state machine.
1559af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
1560af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public static class CdmaOtaScreenState {
1561af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public enum OtaScreenState {
1562af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            OTA_STATUS_UNDEFINED,
1563af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            OTA_STATUS_ACTIVATION,
1564af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            OTA_STATUS_LISTENING,
1565af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            OTA_STATUS_PROGRESS,
1566af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            OTA_STATUS_SUCCESS_FAILURE_DLG
1567af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
1568af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1569af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public OtaScreenState otaScreenState;
1570af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1571af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        public CdmaOtaScreenState() {
1572af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville            otaScreenState = OtaScreenState.OTA_STATUS_UNDEFINED;
1573af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        }
1574b154630235935e1aab2a41eff9ed794d40084a02David Brown
1575b154630235935e1aab2a41eff9ed794d40084a02David Brown        // PendingIntent used to report an OTASP result status code back
1576b154630235935e1aab2a41eff9ed794d40084a02David Brown        // to our caller.
1577b154630235935e1aab2a41eff9ed794d40084a02David Brown        //
1578b154630235935e1aab2a41eff9ed794d40084a02David Brown        // Our caller (presumably SetupWizard) creates this PendingIntent,
1579b154630235935e1aab2a41eff9ed794d40084a02David Brown        // pointing back at itself, and passes it along as an extra with the
1580b154630235935e1aab2a41eff9ed794d40084a02David Brown        // ACTION_PERFORM_CDMA_PROVISIONING intent.  Then, when there's an
1581b154630235935e1aab2a41eff9ed794d40084a02David Brown        // OTASP result to report, we send that PendingIntent back, adding an
1582b154630235935e1aab2a41eff9ed794d40084a02David Brown        // extra called EXTRA_OTASP_RESULT_CODE to indicate the result.
1583b154630235935e1aab2a41eff9ed794d40084a02David Brown        //
1584b154630235935e1aab2a41eff9ed794d40084a02David Brown        // Possible result values are the OTASP_RESULT_* constants.
1585b154630235935e1aab2a41eff9ed794d40084a02David Brown        public PendingIntent otaspResultCodePendingIntent;
1586b154630235935e1aab2a41eff9ed794d40084a02David Brown    }
1587b154630235935e1aab2a41eff9ed794d40084a02David Brown
1588b154630235935e1aab2a41eff9ed794d40084a02David Brown    /** @see com.android.internal.telephony.Phone */
1589b154630235935e1aab2a41eff9ed794d40084a02David Brown    private static String otaProvisionStatusToString(int status) {
1590b154630235935e1aab2a41eff9ed794d40084a02David Brown        switch (status) {
1591b154630235935e1aab2a41eff9ed794d40084a02David Brown            case Phone.CDMA_OTA_PROVISION_STATUS_SPL_UNLOCKED:
1592b154630235935e1aab2a41eff9ed794d40084a02David Brown                return "SPL_UNLOCKED";
1593b154630235935e1aab2a41eff9ed794d40084a02David Brown            case Phone.CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED:
1594b154630235935e1aab2a41eff9ed794d40084a02David Brown                return "SPC_RETRIES_EXCEEDED";
1595b154630235935e1aab2a41eff9ed794d40084a02David Brown            case Phone.CDMA_OTA_PROVISION_STATUS_A_KEY_EXCHANGED:
1596b154630235935e1aab2a41eff9ed794d40084a02David Brown                return "A_KEY_EXCHANGED";
1597b154630235935e1aab2a41eff9ed794d40084a02David Brown            case Phone.CDMA_OTA_PROVISION_STATUS_SSD_UPDATED:
1598b154630235935e1aab2a41eff9ed794d40084a02David Brown                return "SSD_UPDATED";
1599b154630235935e1aab2a41eff9ed794d40084a02David Brown            case Phone.CDMA_OTA_PROVISION_STATUS_NAM_DOWNLOADED:
1600b154630235935e1aab2a41eff9ed794d40084a02David Brown                return "NAM_DOWNLOADED";
1601b154630235935e1aab2a41eff9ed794d40084a02David Brown            case Phone.CDMA_OTA_PROVISION_STATUS_MDN_DOWNLOADED:
1602b154630235935e1aab2a41eff9ed794d40084a02David Brown                return "MDN_DOWNLOADED";
1603b154630235935e1aab2a41eff9ed794d40084a02David Brown            case Phone.CDMA_OTA_PROVISION_STATUS_IMSI_DOWNLOADED:
1604b154630235935e1aab2a41eff9ed794d40084a02David Brown                return "IMSI_DOWNLOADED";
1605b154630235935e1aab2a41eff9ed794d40084a02David Brown            case Phone.CDMA_OTA_PROVISION_STATUS_PRL_DOWNLOADED:
1606b154630235935e1aab2a41eff9ed794d40084a02David Brown                return "PRL_DOWNLOADED";
1607b154630235935e1aab2a41eff9ed794d40084a02David Brown            case Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED:
1608b154630235935e1aab2a41eff9ed794d40084a02David Brown                return "COMMITTED";
1609b154630235935e1aab2a41eff9ed794d40084a02David Brown            case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STARTED:
1610b154630235935e1aab2a41eff9ed794d40084a02David Brown                return "OTAPA_STARTED";
1611b154630235935e1aab2a41eff9ed794d40084a02David Brown            case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED:
1612b154630235935e1aab2a41eff9ed794d40084a02David Brown                return "OTAPA_STOPPED";
1613b154630235935e1aab2a41eff9ed794d40084a02David Brown            case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_ABORTED:
1614b154630235935e1aab2a41eff9ed794d40084a02David Brown                return "OTAPA_ABORTED";
1615b154630235935e1aab2a41eff9ed794d40084a02David Brown            default:
1616b154630235935e1aab2a41eff9ed794d40084a02David Brown                return "<unknown status" + status + ">";
1617b154630235935e1aab2a41eff9ed794d40084a02David Brown        }
1618af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1619af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1620a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng    private static int getLteOnCdmaMode(Context context) {
1621a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng        final TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(
1622a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng                Context.TELEPHONY_SERVICE);
1623a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng        // If the telephony manager is not available yet, or if it doesn't know the answer yet,
1624a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng        // try falling back on the system property that may or may not be there
1625a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng        if (telephonyManager == null
1626a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng                || telephonyManager.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_UNKNOWN) {
1627a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng            return SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE,
1628a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng                    Phone.LTE_ON_CDMA_UNKNOWN);
1629a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng        }
1630a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng        return telephonyManager.getLteOnCdmaMode();
1631a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng    }
1632a57dd655ab3959f0985567393e17f69d138cfeb7Freeman Ng
1633af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    private static void log(String msg) {
1634af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        Log.d(LOG_TAG, msg);
1635af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1636af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville}
1637