100d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon/* 200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * Copyright (C) 2013 The Android Open Source Project 300d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * 400d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * Licensed under the Apache License, Version 2.0 (the "License"); 500d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * you may not use this file except in compliance with the License. 600d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * You may obtain a copy of the License at 700d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * 800d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * http://www.apache.org/licenses/LICENSE-2.0 900d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * 1000d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * Unless required by applicable law or agreed to in writing, software 1100d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * distributed under the License is distributed on an "AS IS" BASIS, 1200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1300d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * See the License for the specific language governing permissions and 1400d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * limitations under the License. 1500d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon */ 1600d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 1700d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordonpackage com.android.phone; 1800d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 19cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordonimport android.app.PendingIntent; 20cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordonimport android.app.PendingIntent.CanceledException; 2100d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordonimport android.content.BroadcastReceiver; 2200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordonimport android.content.Context; 2300d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordonimport android.content.Intent; 2400d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordonimport android.content.IntentFilter; 2500d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordonimport android.os.AsyncResult; 2600d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordonimport android.os.Handler; 2700d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordonimport android.os.Message; 2800d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordonimport android.telephony.ServiceState; 2900d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordonimport android.util.Log; 3000d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 3100d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordonimport com.android.internal.telephony.Phone; 3200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordonimport com.google.common.base.Preconditions; 3300d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 3400d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon/** 3500d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * Starts and displays status for Hands Free Activation (HFA). 3600d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * 3700d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * This class operates with Hands Free Activation apps. 3800d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * It starts by broadcasting the intent com.android.action.START_HFA. 3900d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * An HFA app will pick that up and start the HFA process. 4000d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * If it fails it return ERROR_HFA Intent and upon success returns COMPLETE_HFA. 4100d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * 4200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * If successful, we bounce the radio so that the service picks up the new number. 4300d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * Once the radio is back on we callback the requestor. 4400d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * 4500d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * If there is an error, we do not bounce the radio but still callback with a failure. 4600d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * 4700d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon * TODO(klp): We need system-only permissions for the HFA intents. 4800d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon */ 4900d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordonpublic class HfaLogic { 5000d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private static final String TAG = HfaLogic.class.getSimpleName(); 5100d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 5200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private static final String ACTION_START = "com.android.action.START_HFA"; 5300d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private static final String ACTION_ERROR = "com.android.action.ERROR_HFA"; 5400d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private static final String ACTION_CANCEL = "com.android.action.CANCEL_HFA"; 5500d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private static final String ACTION_COMPLETE = "com.android.action.COMPLETE_HFA"; 5600d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 5700d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private static final int SERVICE_STATE_CHANGED = 1; 5800d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 5900d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon public static final int NOT_WAITING = 0; 6000d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon public static final int WAITING_FOR_RADIO_OFF = 1; 6100d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon public static final int WAITING_FOR_RADIO_ON = 2; 6200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 63cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon public static final int OTASP_UNKNOWN = 0; 64cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon public static final int OTASP_USER_SKIPPED = 1; 65cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon public static final int OTASP_SUCCESS = 2; 66cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon public static final int OTASP_FAILURE = 3; 67cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon 6800d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private int mPhoneMonitorState = NOT_WAITING; 6900d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private BroadcastReceiver mReceiver; 7000d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private HfaLogicCallback mCallback; 71cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon private PendingIntent mResponseIntent; 7200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private Context mContext; 7300d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 74d6883697c932aa7e9d15e34275dcd3a5df8df071Santos Cordon // No retry at the moment. Increase later if necessary. 75d6883697c932aa7e9d15e34275dcd3a5df8df071Santos Cordon private static final int DEFAULT_RETRY_COUNT = 0; 76fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville private int mRetryCount; 77fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville 7800d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon public interface HfaLogicCallback { 7900d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon public void onSuccess(); 8000d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon public void onError(String errorMsg); 8100d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 8200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 83cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon public HfaLogic(Context context, HfaLogicCallback callback, PendingIntent intent) { 8400d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon mCallback = Preconditions.checkNotNull(callback); 8500d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon mContext = Preconditions.checkNotNull(context); 86cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon mResponseIntent = intent; 8700d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 8800d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 8900d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon public void start() { 90fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville Log.i(TAG, "start:"); 91fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville mRetryCount = DEFAULT_RETRY_COUNT; 9200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon startHfaIntentReceiver(); 9300d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon startProvisioning(); 9400d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 9500d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 9600d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private void startProvisioning() { 97fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville Log.i(TAG, "startProvisioning:"); 9800d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon sendHfaCommand(ACTION_START); 9900d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 10000d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 10100d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private void sendHfaCommand(String action) { 102fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville Log.i(TAG, "sendHfaCommand: command=" + action); 10300d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon mContext.sendBroadcast(new Intent(action)); 10400d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 10500d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 10600d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private void onHfaError(String errorMsg) { 107fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville Log.i(TAG, "onHfaError: call mCallBack.onError errorMsg=" + errorMsg 108fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville + " mRetryCount=" + mRetryCount); 109fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville mRetryCount -= 1; 110fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville if (mRetryCount >= 0) { 111fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville Log.i(TAG, "onHfaError: retry"); 112fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville startProvisioning(); 113fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville } else { 114fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville Log.i(TAG, "onHfaError: Declare OTASP_FAILURE"); 115fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville mRetryCount = 0; 116fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville stopHfaIntentReceiver(); 117fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville sendFinalResponse(OTASP_FAILURE, errorMsg); 118fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville mCallback.onError(errorMsg); 119fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville } 12000d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 12100d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 12200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private void onHfaSuccess() { 123fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville Log.i(TAG, "onHfaSuccess: NOT bouncing radio call onTotalSuccess"); 12400d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon stopHfaIntentReceiver(); 125fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville // bounceRadio(); 126fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville onTotalSuccess(); 12700d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 12800d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 12900d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private void onTotalSuccess() { 130fc57843ecd4eae238d193c9c3e68c0176c17d99dWink Saville Log.i(TAG, "onTotalSuccess: call mCallBack.onSuccess"); 131cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon sendFinalResponse(OTASP_SUCCESS, null); 13200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon mCallback.onSuccess(); 13300d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 13400d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 13500d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private void bounceRadio() { 13600d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon final Phone phone = PhoneGlobals.getInstance().getPhone(); 13700d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon phone.registerForServiceStateChanged(mHandler, SERVICE_STATE_CHANGED, null); 13800d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 13900d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon mPhoneMonitorState = WAITING_FOR_RADIO_OFF; 14000d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon phone.setRadioPower(false); 14100d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon onServiceStateChange(phone.getServiceState()); 14200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 14300d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 14400d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private void onServiceStateChange(ServiceState state) { 14500d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon final boolean radioIsOff = state.getVoiceRegState() == ServiceState.STATE_POWER_OFF; 14600d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon final Phone phone = PhoneGlobals.getInstance().getPhone(); 14700d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 148cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon Log.i(TAG, "Radio is on: " + !radioIsOff); 14900d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 15000d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon if (mPhoneMonitorState == WAITING_FOR_RADIO_OFF) { 15100d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon if (radioIsOff) { 15200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon mPhoneMonitorState = WAITING_FOR_RADIO_ON; 15300d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon phone.setRadioPower(true); 15400d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 15500d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } else if (mPhoneMonitorState == WAITING_FOR_RADIO_ON) { 15600d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon if (!radioIsOff) { 15700d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon mPhoneMonitorState = NOT_WAITING; 15800d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon phone.unregisterForServiceStateChanged(mHandler); 15900d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 16000d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon onTotalSuccess(); 16100d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 16200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 16300d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 16400d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 16500d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private void startHfaIntentReceiver() { 16600d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon final IntentFilter filter = new IntentFilter(ACTION_COMPLETE); 16700d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon filter.addAction(ACTION_ERROR); 16800d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 16900d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon mReceiver = new BroadcastReceiver() { 17000d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon @Override 17100d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon public void onReceive(Context context, Intent intent) { 17200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon final String action = intent.getAction(); 17300d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon if (action.equals(ACTION_ERROR)) { 17400d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon onHfaError(intent.getStringExtra("errorCode")); 17500d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } else if (action.equals(ACTION_COMPLETE)) { 176cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon Log.i(TAG, "Hfa Successful"); 17700d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon onHfaSuccess(); 17800d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 17900d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 18000d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon }; 18100d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 18200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon mContext.registerReceiver(mReceiver, filter); 18300d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 18400d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 18500d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private void stopHfaIntentReceiver() { 18600d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon if (mReceiver != null) { 18700d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon mContext.unregisterReceiver(mReceiver); 18800d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon mReceiver = null; 18900d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 19000d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 19100d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 192cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon private void sendFinalResponse(int responseCode, String errorCode) { 193cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon if (mResponseIntent != null) { 194cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon final Intent extraStuff = new Intent(); 195cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon extraStuff.putExtra(OtaUtils.EXTRA_OTASP_RESULT_CODE, responseCode); 196cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon 197cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon if (responseCode == OTASP_FAILURE && errorCode != null) { 198cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon extraStuff.putExtra(OtaUtils.EXTRA_OTASP_ERROR_CODE, errorCode); 199cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon } 200cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon 201cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon try { 202cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon Log.i(TAG, "Sending OTASP confirmation with result code: " 203cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon + responseCode); 204cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon mResponseIntent.send(mContext, 0 /* resultCode (not used) */, extraStuff); 205cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon } catch (CanceledException e) { 206cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon Log.e(TAG, "Pending Intent canceled"); 207cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon } 208cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon } 209cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon } 210cd76f8b160e0e4b2e5ccf34c0c5e1e58a0bb8b72Santos Cordon 21100d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon private Handler mHandler = new Handler() { 21200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon @Override 21300d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon public void handleMessage(Message msg) { 21400d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon switch (msg.what) { 21500d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon case SERVICE_STATE_CHANGED: 21600d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon ServiceState state = (ServiceState) ((AsyncResult) msg.obj).result; 21700d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon onServiceStateChange(state); 21800d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon break; 21900d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon default: 22000d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon break; 22100d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 22200d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon } 22300d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon }; 22400d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon 22500d7a430ac98cd65b7ae3afca5fa9509f1480edaSantos Cordon} 226