1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.telephony; 18 19 import android.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.IntentFilter; 23 import android.content.SharedPreferences; 24 import android.net.Uri; 25 import android.os.BadParcelableException; 26 import android.os.Build; 27 import android.preference.PreferenceManager; 28 import android.telephony.Rlog; 29 import android.telephony.ServiceState; 30 31 import com.android.ims.ImsCall; 32 import com.android.ims.ImsCallProfile; 33 import com.android.ims.ImsConferenceState; 34 import com.android.ims.ImsExternalCallState; 35 import com.android.ims.ImsReasonInfo; 36 import com.android.internal.telephony.imsphone.ImsExternalCallTracker; 37 import com.android.internal.telephony.imsphone.ImsPhone; 38 import com.android.internal.telephony.imsphone.ImsPhoneCall; 39 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker; 40 import com.android.internal.telephony.test.TestConferenceEventPackageParser; 41 42 import java.io.File; 43 import java.io.FileInputStream; 44 import java.io.FileNotFoundException; 45 import java.util.ArrayList; 46 import java.util.List; 47 48 /** 49 * Telephony tester receives the following intents where {name} is the phone name 50 * 51 * adb shell am broadcast -a com.android.internal.telephony.{name}.action_detached 52 * adb shell am broadcast -a com.android.internal.telephony.{name}.action_attached 53 * adb shell am broadcast -a com.android.internal.telephony.TestConferenceEventPackage -e filename 54 * test_filename.xml 55 */ 56 public class TelephonyTester { 57 private static final String LOG_TAG = "TelephonyTester"; 58 private static final boolean DBG = true; 59 60 /** 61 * Test-only intent used to send a test conference event package to the IMS framework. 62 */ 63 private static final String ACTION_TEST_CONFERENCE_EVENT_PACKAGE = 64 "com.android.internal.telephony.TestConferenceEventPackage"; 65 66 /** 67 * Test-only intent used to send a test dialog event package to the IMS framework. 68 */ 69 private static final String ACTION_TEST_DIALOG_EVENT_PACKAGE = 70 "com.android.internal.telephony.TestDialogEventPackage"; 71 72 private static final String EXTRA_FILENAME = "filename"; 73 private static final String EXTRA_STARTPACKAGE = "startPackage"; 74 private static final String EXTRA_SENDPACKAGE = "sendPackage"; 75 private static final String EXTRA_DIALOGID = "dialogId"; 76 private static final String EXTRA_NUMBER = "number"; 77 private static final String EXTRA_STATE = "state"; 78 private static final String EXTRA_CANPULL = "canPull"; 79 80 /** 81 * Test-only intent used to trigger the signalling which occurs when a handover to WIFI fails. 82 */ 83 private static final String ACTION_TEST_HANDOVER_FAIL = 84 "com.android.internal.telephony.TestHandoverFail"; 85 86 private static List<ImsExternalCallState> mImsExternalCallStates = null; 87 88 private Phone mPhone; 89 90 // The static intent receiver one for all instances and we assume this 91 // is running on the same thread as Dcc. 92 protected BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 93 @Override 94 public void onReceive(Context context, Intent intent) { 95 String action = intent.getAction(); 96 try { 97 if (DBG) log("sIntentReceiver.onReceive: action=" + action); 98 if (action.equals(mPhone.getActionDetached())) { 99 log("simulate detaching"); 100 mPhone.getServiceStateTracker().mDetachedRegistrants.notifyRegistrants(); 101 } else if (action.equals(mPhone.getActionAttached())) { 102 log("simulate attaching"); 103 mPhone.getServiceStateTracker().mAttachedRegistrants.notifyRegistrants(); 104 } else if (action.equals(ACTION_TEST_CONFERENCE_EVENT_PACKAGE)) { 105 log("inject simulated conference event package"); 106 handleTestConferenceEventPackage(context, 107 intent.getStringExtra(EXTRA_FILENAME)); 108 } else if (action.equals(ACTION_TEST_DIALOG_EVENT_PACKAGE)) { 109 log("handle test dialog event package intent"); 110 handleTestDialogEventPackageIntent(intent); 111 } else if (action.equals(ACTION_TEST_HANDOVER_FAIL)) { 112 log("handle handover fail test intent"); 113 handleHandoverFailedIntent(); 114 } else { 115 if (DBG) log("onReceive: unknown action=" + action); 116 } 117 } catch (BadParcelableException e) { 118 Rlog.w(LOG_TAG, e); 119 } 120 } 121 }; 122 TelephonyTester(Phone phone)123 TelephonyTester(Phone phone) { 124 mPhone = phone; 125 126 if (Build.IS_DEBUGGABLE) { 127 IntentFilter filter = new IntentFilter(); 128 129 filter.addAction(mPhone.getActionDetached()); 130 log("register for intent action=" + mPhone.getActionDetached()); 131 132 filter.addAction(mPhone.getActionAttached()); 133 log("register for intent action=" + mPhone.getActionAttached()); 134 135 if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) { 136 log("register for intent action=" + ACTION_TEST_CONFERENCE_EVENT_PACKAGE); 137 filter.addAction(ACTION_TEST_CONFERENCE_EVENT_PACKAGE); 138 filter.addAction(ACTION_TEST_DIALOG_EVENT_PACKAGE); 139 filter.addAction(ACTION_TEST_HANDOVER_FAIL); 140 mImsExternalCallStates = new ArrayList<ImsExternalCallState>(); 141 } 142 143 phone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone.getHandler()); 144 } 145 } 146 dispose()147 void dispose() { 148 if (Build.IS_DEBUGGABLE) { 149 mPhone.getContext().unregisterReceiver(mIntentReceiver); 150 } 151 } 152 log(String s)153 private static void log(String s) { 154 Rlog.d(LOG_TAG, s); 155 } 156 handleHandoverFailedIntent()157 private void handleHandoverFailedIntent() { 158 // Attempt to get the active IMS call 159 ImsPhone imsPhone = (ImsPhone) mPhone; 160 if (imsPhone == null) { 161 return; 162 } 163 164 ImsPhoneCall imsPhoneCall = imsPhone.getForegroundCall(); 165 if (imsPhoneCall == null) { 166 return; 167 } 168 169 ImsCall imsCall = imsPhoneCall.getImsCall(); 170 if (imsCall == null) { 171 return; 172 } 173 174 imsCall.getImsCallSessionListenerProxy().callSessionHandoverFailed(imsCall.getCallSession(), 175 ServiceState.RIL_RADIO_TECHNOLOGY_LTE, ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN, 176 new ImsReasonInfo()); 177 } 178 179 /** 180 * Handles request to send a test conference event package to the active Ims call. 181 * 182 * @see com.android.internal.telephony.test.TestConferenceEventPackageParser 183 * @param context The context. 184 * @param fileName The name of the test conference event package file to read. 185 */ handleTestConferenceEventPackage(Context context, String fileName)186 private void handleTestConferenceEventPackage(Context context, String fileName) { 187 // Attempt to get the active IMS call before parsing the test XML file. 188 ImsPhone imsPhone = (ImsPhone) mPhone; 189 if (imsPhone == null) { 190 return; 191 } 192 193 ImsPhoneCall imsPhoneCall = imsPhone.getForegroundCall(); 194 if (imsPhoneCall == null) { 195 return; 196 } 197 198 ImsCall imsCall = imsPhoneCall.getImsCall(); 199 if (imsCall == null) { 200 return; 201 } 202 203 File packageFile = new File(context.getFilesDir(), fileName); 204 final FileInputStream is; 205 try { 206 is = new FileInputStream(packageFile); 207 } catch (FileNotFoundException ex) { 208 log("Test conference event package file not found: " + packageFile.getAbsolutePath()); 209 return; 210 } 211 212 TestConferenceEventPackageParser parser = new TestConferenceEventPackageParser(is); 213 ImsConferenceState imsConferenceState = parser.parse(); 214 if (imsConferenceState == null) { 215 return; 216 } 217 218 imsCall.conferenceStateUpdated(imsConferenceState); 219 } 220 221 /** 222 * Handles intents containing test dialog event package data. 223 * 224 * @param intent 225 */ handleTestDialogEventPackageIntent(Intent intent)226 private void handleTestDialogEventPackageIntent(Intent intent) { 227 ImsPhone imsPhone = (ImsPhone) mPhone; 228 if (imsPhone == null) { 229 return; 230 } 231 ImsExternalCallTracker externalCallTracker = imsPhone.getExternalCallTracker(); 232 if (externalCallTracker == null) { 233 return; 234 } 235 236 if (intent.hasExtra(EXTRA_STARTPACKAGE)) { 237 mImsExternalCallStates.clear(); 238 } else if (intent.hasExtra(EXTRA_SENDPACKAGE)) { 239 externalCallTracker.refreshExternalCallState(mImsExternalCallStates); 240 mImsExternalCallStates.clear(); 241 } else if (intent.hasExtra(EXTRA_DIALOGID)) { 242 ImsExternalCallState state = new ImsExternalCallState( 243 intent.getIntExtra(EXTRA_DIALOGID, 0), 244 Uri.parse(intent.getStringExtra(EXTRA_NUMBER)), 245 intent.getBooleanExtra(EXTRA_CANPULL, true), 246 intent.getIntExtra(EXTRA_STATE, 247 ImsExternalCallState.CALL_STATE_CONFIRMED), 248 ImsCallProfile.CALL_TYPE_VOICE, 249 false /* isHeld */ 250 ); 251 mImsExternalCallStates.add(state); 252 } 253 } 254 } 255