1b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project/* 2b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 3b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 4b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * you may not use this file except in compliance with the License. 6b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * You may obtain a copy of the License at 7b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 8b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 10b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * See the License for the specific language governing permissions and 14b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * limitations under the License. 15b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 16b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 17b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectpackage com.android.phone; 18b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 19b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.app.Activity; 2007d801323833fd50c89c060910030c81d6af6d10Daisuke Miyakawaimport android.app.ActivityOptions; 21b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.app.AlertDialog; 22b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.app.Dialog; 233426afaf85d33d454fad8d341a1a895fd7e21c10David Brownimport android.app.ProgressDialog; 241d417d7ede71bbcf72a7edebf528efbfcf9b82bbJaikumar Ganeshimport android.bluetooth.BluetoothAdapter; 25db065e9834bcad9b0cb16c272b4b272dee8bdf62Nick Pellyimport android.bluetooth.BluetoothDevice; 26b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.bluetooth.BluetoothHeadset; 271d417d7ede71bbcf72a7edebf528efbfcf9b82bbJaikumar Ganeshimport android.bluetooth.BluetoothProfile; 2859d39bc3d1f3930550dc572172e144831ac91c31Matthew Xieimport android.bluetooth.IBluetoothHeadsetPhone; 293ff152c80b97c32a5764c54d2aeb888509cf84adDavid Brownimport android.content.ActivityNotFoundException; 30b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.BroadcastReceiver; 31b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.Context; 32756fea4a5c82dbceda447bfa41fa8a0bd70288f0David Brownimport android.content.DialogInterface; 33b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawaimport android.content.DialogInterface.OnCancelListener; 34b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.Intent; 35b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.IntentFilter; 36ad465d2663816e822b07232b56b0fdf2863ee248David Brownimport android.content.res.Configuration; 37b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.res.Resources; 38b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.graphics.Typeface; 39b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.media.AudioManager; 40b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.AsyncResult; 41b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.Bundle; 42b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.Handler; 43b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.Message; 444bf466a6d117a6fc4ddfd480f7db7606a29cb4ffMindy Pereiraimport android.os.PowerManager; 4559d39bc3d1f3930550dc572172e144831ac91c31Matthew Xieimport android.os.RemoteException; 46b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.SystemClock; 47b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.SystemProperties; 48b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.telephony.ServiceState; 49b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.text.TextUtils; 50b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.text.method.DialerKeyListener; 51cd89106dcd1038666f992cea3cc79e067245187fDan Egnorimport android.util.EventLog; 52b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.util.Log; 53b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.KeyEvent; 54b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.View; 55b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.ViewGroup; 56dc855d9bbb450c65a3fb2a75e3cd995c975b32f3Martin Hibdonimport android.view.ViewStub; 57b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.Window; 58b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.WindowManager; 59dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brownimport android.view.accessibility.AccessibilityEvent; 60b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.EditText; 613cd7e14cd8514ad60b7764ee8b758a153d1af780Martin Hibdonimport android.widget.ImageView; 6251eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdonimport android.widget.LinearLayout; 63b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.TextView; 64b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.Toast; 65b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 667b793e4c994f30b08abb065709ef26bf305f0a24David Brownimport com.android.internal.telephony.Call; 67c97fea097483c6e58c199e857b279ec92e64d8e3John Wangimport com.android.internal.telephony.CallManager; 687b793e4c994f30b08abb065709ef26bf305f0a24David Brownimport com.android.internal.telephony.Connection; 697b793e4c994f30b08abb065709ef26bf305f0a24David Brownimport com.android.internal.telephony.MmiCode; 707b793e4c994f30b08abb065709ef26bf305f0a24David Brownimport com.android.internal.telephony.Phone; 71b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Savilleimport com.android.internal.telephony.PhoneConstants; 72f8a9fbe31969b4f97ea03d233684efc117888879Daisuke Miyakawaimport com.android.internal.telephony.TelephonyCapabilities; 7375e3711d82d0c98444f6c438437cad41d862fca6David Brownimport com.android.phone.Constants.CallStatusCode; 7475e3711d82d0c98444f6c438437cad41d862fca6David Brownimport com.android.phone.InCallUiState.InCallScreenMode; 75af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Savilleimport com.android.phone.OtaUtils.CdmaOtaScreenState; 76af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville 77b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport java.util.List; 7875e3711d82d0c98444f6c438437cad41d862fca6David Brown 79b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 80b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project/** 81b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Phone app "in call" screen. 82b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 83b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectpublic class InCallScreen extends Activity 844ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown implements View.OnClickListener { 85796c70c99bc39295bf685061056f06ab8949c742David Brown private static final String LOG_TAG = "InCallScreen"; 86b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 87b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final boolean DBG = 88a1a9601840e50e18ff8ca4be9b888e592287577bDianne Hackborn (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1); 89a1a9601840e50e18ff8ca4be9b888e592287577bDianne Hackborn private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2); 90b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 91b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 92b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Intent extra used to specify whether the DTMF dialpad should be 93b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * initially visible when bringing up the InCallScreen. (If this 94b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * extra is present, the dialpad will be initially shown if the extra 95b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * has the boolean value true, and initially hidden otherwise.) 96b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 975398ca30f57b928c2dd9bf175c5e083726279494Nicolas Catania // TODO: Should be EXTRA_SHOW_DIALPAD for consistency. 98b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project static final String SHOW_DIALPAD_EXTRA = "com.android.phone.ShowDialpad"; 99b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1005398ca30f57b928c2dd9bf175c5e083726279494Nicolas Catania /** 101d94cc5e209bf871e4b6d5e84bcf6bd4e38d8ac65Nicolas Catania * Intent extra to specify the package name of the gateway 102d94cc5e209bf871e4b6d5e84bcf6bd4e38d8ac65Nicolas Catania * provider. Used to get the name displayed in the in-call screen 103d94cc5e209bf871e4b6d5e84bcf6bd4e38d8ac65Nicolas Catania * during the call setup. The value is a string. 1047a2ee085993bc9cae01bf9daa993b1551ed64a7bNicolas Catania */ 105d94cc5e209bf871e4b6d5e84bcf6bd4e38d8ac65Nicolas Catania // TODO: This extra is currently set by the gateway application as 106d94cc5e209bf871e4b6d5e84bcf6bd4e38d8ac65Nicolas Catania // a temporary measure. Ultimately, the framework will securely 107d94cc5e209bf871e4b6d5e84bcf6bd4e38d8ac65Nicolas Catania // set it. 108d94cc5e209bf871e4b6d5e84bcf6bd4e38d8ac65Nicolas Catania /* package */ static final String EXTRA_GATEWAY_PROVIDER_PACKAGE = 109d94cc5e209bf871e4b6d5e84bcf6bd4e38d8ac65Nicolas Catania "com.android.phone.extra.GATEWAY_PROVIDER_PACKAGE"; 110d94cc5e209bf871e4b6d5e84bcf6bd4e38d8ac65Nicolas Catania 111d94cc5e209bf871e4b6d5e84bcf6bd4e38d8ac65Nicolas Catania /** 112d94cc5e209bf871e4b6d5e84bcf6bd4e38d8ac65Nicolas Catania * Intent extra to specify the URI of the provider to place the 113d94cc5e209bf871e4b6d5e84bcf6bd4e38d8ac65Nicolas Catania * call. The value is a string. It holds the gateway address 114d94cc5e209bf871e4b6d5e84bcf6bd4e38d8ac65Nicolas Catania * (phone gateway URL should start with the 'tel:' scheme) that 115d94cc5e209bf871e4b6d5e84bcf6bd4e38d8ac65Nicolas Catania * will actually be contacted to call the number passed in the 116d94cc5e209bf871e4b6d5e84bcf6bd4e38d8ac65Nicolas Catania * intent URL or in the EXTRA_PHONE_NUMBER extra. 117d94cc5e209bf871e4b6d5e84bcf6bd4e38d8ac65Nicolas Catania */ 1182cbf80dfbbc28ae24e093fb089973b3e59d4508aNicolas Catania // TODO: Should the value be a Uri (Parcelable)? Need to make sure 1192cbf80dfbbc28ae24e093fb089973b3e59d4508aNicolas Catania // MMI code '#' don't get confused as URI fragments. 120d94cc5e209bf871e4b6d5e84bcf6bd4e38d8ac65Nicolas Catania /* package */ static final String EXTRA_GATEWAY_URI = 121d94cc5e209bf871e4b6d5e84bcf6bd4e38d8ac65Nicolas Catania "com.android.phone.extra.GATEWAY_URI"; 1227a2ee085993bc9cae01bf9daa993b1551ed64a7bNicolas Catania 123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Amount of time (in msec) that we display the "Call ended" state. 124b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // The "short" value is for calls ended by the local user, and the 125b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "long" value is for calls ended by the remote caller. 126b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int CALL_ENDED_SHORT_DELAY = 200; // msec 127b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int CALL_ENDED_LONG_DELAY = 2000; // msec 1286ca271d15ab7c3196854ada94fd6d90ebc644731Daisuke Miyakawa private static final int CALL_ENDED_EXTRA_LONG_DELAY = 5000; // msec 129b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 13028dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal // Amount of time that we display the PAUSE alert Dialog showing the 13128dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal // post dial string yet to be send out to the n/w 13228dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal private static final int PAUSE_PROMPT_DIALOG_TIMEOUT = 2000; //msec 13328dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal 134b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa // Amount of time that we display the provider info if applicable. 135b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa private static final int PROVIDER_INFO_TIMEOUT = 5000; // msec 1366238feb36f40a9ccd52e03f4d155f9a4c9dd1cc8Nicolas Catania 1373800ac871d6548790ac6119bb68b9be0640af261David Krause // These are values for the settings of the auto retry mode: 1383800ac871d6548790ac6119bb68b9be0640af261David Krause // 0 = disabled 1393800ac871d6548790ac6119bb68b9be0640af261David Krause // 1 = enabled 1403800ac871d6548790ac6119bb68b9be0640af261David Krause // TODO (Moto):These constants don't really belong here, 1413800ac871d6548790ac6119bb68b9be0640af261David Krause // they should be moved to Settings where the value is being looked up in the first place 1423800ac871d6548790ac6119bb68b9be0640af261David Krause static final int AUTO_RETRY_OFF = 0; 1433800ac871d6548790ac6119bb68b9be0640af261David Krause static final int AUTO_RETRY_ON = 1; 1443800ac871d6548790ac6119bb68b9be0640af261David Krause 145b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Message codes; see mHandler below. 146b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Note message codes < 100 are reserved for the PhoneApp. 147b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int PHONE_STATE_CHANGED = 101; 148b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int PHONE_DISCONNECT = 102; 149b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int EVENT_HEADSET_PLUG_STATE_CHANGED = 103; 150b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int POST_ON_DIAL_CHARS = 104; 151b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int WILD_PROMPT_CHAR_ENTERED = 105; 152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int ADD_VOICEMAIL_NUMBER = 106; 153b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int DONT_ADD_VOICEMAIL_NUMBER = 107; 154b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int DELAYED_CLEANUP_AFTER_DISCONNECT = 108; 155b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int SUPP_SERVICE_FAILED = 110; 156325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown private static final int REQUEST_UPDATE_BLUETOOTH_INDICATION = 114; 1570fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville private static final int PHONE_CDMA_CALL_WAITING = 115; 158325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown private static final int REQUEST_CLOSE_SPC_ERROR_NOTICE = 118; 159325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown private static final int REQUEST_CLOSE_OTA_FAILURE_NOTICE = 119; 16028dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal private static final int EVENT_PAUSE_DIALOG_COMPLETE = 120; 161b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa private static final int EVENT_HIDE_PROVIDER_INFO = 121; // Time to remove the info. 16275e3711d82d0c98444f6c438437cad41d862fca6David Brown private static final int REQUEST_UPDATE_SCREEN = 122; 163493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown private static final int PHONE_INCOMING_RING = 123; 164fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown private static final int PHONE_NEW_RINGING_CONNECTION = 124; 165b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1665c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // When InCallScreenMode is UNDEFINED set the default action 1675c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // to ACTION_UNDEFINED so if we are resumed the activity will 1685c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // know its undefined. In particular checkIsOtaCall will return 1695c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // false. 1705c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville public static final String ACTION_UNDEFINED = "com.android.phone.InCallScreen.UNDEFINED"; 1715c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville 17275e3711d82d0c98444f6c438437cad41d862fca6David Brown /** Status codes returned from syncWithPhoneState(). */ 17375e3711d82d0c98444f6c438437cad41d862fca6David Brown private enum SyncWithPhoneStateStatus { 174b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 17575e3711d82d0c98444f6c438437cad41d862fca6David Brown * Successfully updated our internal state based on the telephony state. 176b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 17775e3711d82d0c98444f6c438437cad41d862fca6David Brown SUCCESS, 17875e3711d82d0c98444f6c438437cad41d862fca6David Brown 179af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville /** 18075e3711d82d0c98444f6c438437cad41d862fca6David Brown * There was no phone state to sync with (i.e. the phone was 18175e3711d82d0c98444f6c438437cad41d862fca6David Brown * completely idle). In most cases this means that the 18275e3711d82d0c98444f6c438437cad41d862fca6David Brown * in-call UI shouldn't be visible in the first place, unless 18375e3711d82d0c98444f6c438437cad41d862fca6David Brown * we need to remain in the foreground while displaying an 18475e3711d82d0c98444f6c438437cad41d862fca6David Brown * error message. 185af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville */ 18675e3711d82d0c98444f6c438437cad41d862fca6David Brown PHONE_NOT_IN_USE 187b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 188b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 189b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private boolean mRegisteredForPhoneStates; 190b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 191a1a9601840e50e18ff8ca4be9b888e592287577bDianne Hackborn private PhoneGlobals mApp; 192c97fea097483c6e58c199e857b279ec92e64d8e3John Wang private CallManager mCM; 193c97fea097483c6e58c199e857b279ec92e64d8e3John Wang 19475e3711d82d0c98444f6c438437cad41d862fca6David Brown // TODO: need to clean up all remaining uses of mPhone. 19575e3711d82d0c98444f6c438437cad41d862fca6David Brown // (There may be more than one Phone instance on the device, so it's wrong 19675e3711d82d0c98444f6c438437cad41d862fca6David Brown // to just keep a single mPhone field. Instead, any time we need a Phone 19775e3711d82d0c98444f6c438437cad41d862fca6David Brown // reference we should get it dynamically from the CallManager, probably 19875e3711d82d0c98444f6c438437cad41d862fca6David Brown // based on the current foreground Call.) 199b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private Phone mPhone; 200b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 201b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private BluetoothHeadset mBluetoothHeadset; 20259d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie private BluetoothAdapter mBluetoothAdapter; 203b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private boolean mBluetoothConnectionPending; 204b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private long mBluetoothConnectionRequestTime; 205b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2060d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa /** Main in-call UI elements. */ 207b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private CallCard mCallCard; 20847e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown 20947e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown // UI controls: 21047e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown private InCallControlState mInCallControlState; 2114ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown private InCallTouchUi mInCallTouchUi; 212524486403a387c324dee5aff7fb78ca784d15255David Brown private RespondViaSmsManager mRespondViaSmsManager; // see internalRespondViaSms() 2137b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown private ManageConferenceUtils mManageConferenceUtils; 214b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2152c76ab3fb8e86f630b027aec1c4ac8e294501f1eNicolas Catania // DTMF Dialer controller and its view: 216b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private DTMFTwelveKeyDialer mDialer; 217b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 218b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private EditText mWildPromptText; 219b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 220d1b19c70340c258796e7c2ebe6459c65cb16245fDavid Brown // Various dialogs we bring up (see dismissAllDialogs()). 221d1b19c70340c258796e7c2ebe6459c65cb16245fDavid Brown // TODO: convert these all to use the "managed dialogs" framework. 222d1b19c70340c258796e7c2ebe6459c65cb16245fDavid Brown // 223b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // The MMI started dialog can actually be one of 2 items: 224b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 1. An alert dialog if the MMI code is a normal MMI 225b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 2. A progress dialog if the user requested a USSD 226b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private Dialog mMmiStartedDialog; 227b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private AlertDialog mMissingVoicemailDialog; 228b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private AlertDialog mGenericErrorDialog; 229b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private AlertDialog mSuppServiceFailureDialog; 230b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private AlertDialog mWaitPromptDialog; 231b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private AlertDialog mWildPromptDialog; 2323800ac871d6548790ac6119bb68b9be0640af261David Krause private AlertDialog mCallLostDialog; 23328dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal private AlertDialog mPausePromptDialog; 234a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown private AlertDialog mExitingECMDialog; 235d1b19c70340c258796e7c2ebe6459c65cb16245fDavid Brown // NOTE: if you add a new dialog here, be sure to add it to dismissAllDialogs() also. 236b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2373426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // ProgressDialog created by showProgressIndication() 2383426afaf85d33d454fad8d341a1a895fd7e21c10David Brown private ProgressDialog mProgressDialog; 2393426afaf85d33d454fad8d341a1a895fd7e21c10David Brown 240b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: If the Activity class ever provides an easy way to get the 241b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // current "activity lifecycle" state, we can remove these flags. 242b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private boolean mIsDestroyed = false; 243b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private boolean mIsForegroundActivity = false; 2444bf466a6d117a6fc4ddfd480f7db7606a29cb4ffMindy Pereira private boolean mIsForegroundActivityForProximity = false; 2454bf466a6d117a6fc4ddfd480f7db7606a29cb4ffMindy Pereira private PowerManager mPowerManager; 246b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 24751eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon // For use with Pause/Wait dialogs 24828dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal private String mPostDialStrAfterPause; 24928dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal private boolean mPauseInProgress = false; 25028dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal 251d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // Info about the most-recently-disconnected Connection, which is used 252d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // to determine what should happen when exiting the InCallScreen after a 253d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // call. (This info is set by onDisconnect(), and used by 254d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // delayedCleanupAfterDisconnect().) 255d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown private Connection.DisconnectCause mLastDisconnectCause; 256d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown 257b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown /** In-call audio routing options; see switchInCallAudio(). */ 258b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown public enum InCallAudioMode { 259b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown SPEAKER, // Speakerphone 260b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown BLUETOOTH, // Bluetooth headset (if available) 26118410cf5cd54564fdcbf693ee6a4f4b5a8d479e4David Brown EARPIECE, // Handset earpiece (or wired headset, if connected) 262b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown } 263b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown 264d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown 265b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private Handler mHandler = new Handler() { 266b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 267b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void handleMessage(Message msg) { 268b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mIsDestroyed) { 269b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("Handler: ignoring message " + msg + "; we're destroyed!"); 270b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 271b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 272b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (!mIsForegroundActivity) { 273b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("Handler: handling message " + msg + " while not in foreground"); 274b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Continue anyway; some of the messages below *want* to 275b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // be handled even if we're not the foreground activity 276b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (like DELAYED_CLEANUP_AFTER_DISCONNECT), and they all 277b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // should at least be safe to handle if we're not in the 278b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // foreground... 279b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 280b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 281b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (msg.what) { 282b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case SUPP_SERVICE_FAILED: 283b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project onSuppServiceFailed((AsyncResult) msg.obj); 284b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 285b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 286b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case PHONE_STATE_CHANGED: 287b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project onPhoneStateChanged((AsyncResult) msg.obj); 288b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 289b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 290b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case PHONE_DISCONNECT: 291b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project onDisconnect((AsyncResult) msg.obj); 292b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 293b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 294b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case EVENT_HEADSET_PLUG_STATE_CHANGED: 2954ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // Update the in-call UI, since some UI elements (such 29618410cf5cd54564fdcbf693ee6a4f4b5a8d479e4David Brown // as the "Speaker" button) may change state depending on 2974ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // whether a headset is plugged in. 298b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: A full updateScreen() is overkill here, since 299b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the value of PhoneApp.isHeadsetPlugged() only affects a 3004ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // single onscreen UI element. (But even a full updateScreen() 301b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // is still pretty cheap, so let's keep this simple 302b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // for now.) 303b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project updateScreen(); 30418410cf5cd54564fdcbf693ee6a4f4b5a8d479e4David Brown 30518410cf5cd54564fdcbf693ee6a4f4b5a8d479e4David Brown // Also, force the "audio mode" popup to refresh itself if 30618410cf5cd54564fdcbf693ee6a4f4b5a8d479e4David Brown // it's visible, since one of its items is either "Wired 30718410cf5cd54564fdcbf693ee6a4f4b5a8d479e4David Brown // headset" or "Handset earpiece" depending on whether the 30818410cf5cd54564fdcbf693ee6a4f4b5a8d479e4David Brown // headset is plugged in or not. 30918410cf5cd54564fdcbf693ee6a4f4b5a8d479e4David Brown mInCallTouchUi.refreshAudioModePopup(); // safe even if the popup's not active 31018410cf5cd54564fdcbf693ee6a4f4b5a8d479e4David Brown 311b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 312b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 313eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // TODO: sort out MMI code (probably we should remove this method entirely). 314eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // See also MMI handling code in onResume() 315eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // case PhoneApp.MMI_INITIATE: 316eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // onMMIInitiate((AsyncResult) msg.obj); 317eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // break; 318b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 319a1a9601840e50e18ff8ca4be9b888e592287577bDianne Hackborn case PhoneGlobals.MMI_CANCEL: 320b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project onMMICancel(); 321b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 322b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 323b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // handle the mmi complete message. 324b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // since the message display class has been replaced with 325b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // a system dialog in PhoneUtils.displayMMIComplete(), we 326b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // should finish the activity here to close the window. 327a1a9601840e50e18ff8ca4be9b888e592287577bDianne Hackborn case PhoneGlobals.MMI_COMPLETE: 328eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa onMMIComplete((MmiCode) ((AsyncResult) msg.obj).result); 329b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 330b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 331b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case POST_ON_DIAL_CHARS: 332b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project handlePostOnDialChars((AsyncResult) msg.obj, (char) msg.arg1); 333b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 334b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 335b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case ADD_VOICEMAIL_NUMBER: 336b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project addVoiceMailNumberPanel(); 337b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 338b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 339b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case DONT_ADD_VOICEMAIL_NUMBER: 340b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project dontAddVoiceMailNumber(); 341b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 342b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 343b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case DELAYED_CLEANUP_AFTER_DISCONNECT: 344b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project delayedCleanupAfterDisconnect(); 345b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 346b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 347325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown case REQUEST_UPDATE_BLUETOOTH_INDICATION: 348325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown if (VDBG) log("REQUEST_UPDATE_BLUETOOTH_INDICATION..."); 3498bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // The bluetooth headset state changed, so some UI 3508bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // elements may need to update. (There's no need to 3518bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // look up the current state here, since any UI 3528bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // elements that care about the bluetooth state get it 3538bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // directly from PhoneApp.showBluetoothIndication().) 3548bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project updateScreen(); 3558bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project break; 3560fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 3570fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville case PHONE_CDMA_CALL_WAITING: 3580fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (DBG) log("Received PHONE_CDMA_CALL_WAITING event ..."); 359c97fea097483c6e58c199e857b279ec92e64d8e3John Wang Connection cn = mCM.getFirstActiveRingingCall().getLatestConnection(); 3600fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 3610fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Only proceed if we get a valid connection object 3620fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (cn != null) { 3630fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Finally update screen with Call waiting info and request 3640fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // screen to wake up 3650fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville updateScreen(); 36675e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.updateWakeState(); 3670fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 3680fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville break; 369af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville 370325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown case REQUEST_CLOSE_SPC_ERROR_NOTICE: 37175e3711d82d0c98444f6c438437cad41d862fca6David Brown if (mApp.otaUtils != null) { 37275e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.otaUtils.onOtaCloseSpcNotice(); 373af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 374af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville break; 375af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville 376325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown case REQUEST_CLOSE_OTA_FAILURE_NOTICE: 37775e3711d82d0c98444f6c438437cad41d862fca6David Brown if (mApp.otaUtils != null) { 37875e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.otaUtils.onOtaCloseFailureNotice(); 379af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 380af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville break; 38128dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal 38228dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal case EVENT_PAUSE_DIALOG_COMPLETE: 38328dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal if (mPausePromptDialog != null) { 38428dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal if (DBG) log("- DISMISSING mPausePromptDialog."); 38528dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal mPausePromptDialog.dismiss(); // safe even if already dismissed 38628dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal mPausePromptDialog = null; 38728dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal } 38828dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal break; 3896238feb36f40a9ccd52e03f4d155f9a4c9dd1cc8Nicolas Catania 390b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa case EVENT_HIDE_PROVIDER_INFO: 391b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa mApp.inCallUiState.providerInfoVisible = false; 392b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa if (mCallCard != null) { 393b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa mCallCard.updateState(mCM); 394b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa } 3956238feb36f40a9ccd52e03f4d155f9a4c9dd1cc8Nicolas Catania break; 39675e3711d82d0c98444f6c438437cad41d862fca6David Brown case REQUEST_UPDATE_SCREEN: 39775e3711d82d0c98444f6c438437cad41d862fca6David Brown updateScreen(); 398b8df8173e1a0ea8ba89cea984176216201c4d5e7Paul Berman break; 399493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown 400493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown case PHONE_INCOMING_RING: 401493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown onIncomingRing(); 402493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown break; 403493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown 404fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown case PHONE_NEW_RINGING_CONNECTION: 405fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown onNewRingingConnection(); 406fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown break; 407fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown 408493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown default: 409493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown Log.wtf(LOG_TAG, "mHandler: unexpected message: " + msg); 410493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown break; 411b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 412b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 413b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project }; 414b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 415b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 416b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 417b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onReceive(Context context, Intent intent) { 418b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project String action = intent.getAction(); 419b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (action.equals(Intent.ACTION_HEADSET_PLUG)) { 420b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Listen for ACTION_HEADSET_PLUG broadcasts so that we 421b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // can update the onscreen UI when the headset state changes. 422b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if (DBG) log("mReceiver: ACTION_HEADSET_PLUG"); 423b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if (DBG) log("==> intent: " + intent); 424b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if (DBG) log(" state: " + intent.getIntExtra("state", 0)); 425b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if (DBG) log(" name: " + intent.getStringExtra("name")); 426b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // send the event and add the state as an argument. 427b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Message message = Message.obtain(mHandler, EVENT_HEADSET_PLUG_STATE_CHANGED, 428b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project intent.getIntExtra("state", 0), 0); 429b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mHandler.sendMessage(message); 430b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 431b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 432b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project }; 433b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 434b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 435b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 436b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project protected void onCreate(Bundle icicle) { 437ae6bb3d59ba1c1551ef626de51c11c70231d2653David Brown Log.i(LOG_TAG, "onCreate()... this = " + this); 438b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Profiler.callScreenOnCreate(); 439b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project super.onCreate(icicle); 440b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 4416c5cf46a2a31f0bffe9df36da8922971f7ee296bDavid Brown // Make sure this is a voice-capable device. 442a1a9601840e50e18ff8ca4be9b888e592287577bDianne Hackborn if (!PhoneGlobals.sVoiceCapable) { 4436c5cf46a2a31f0bffe9df36da8922971f7ee296bDavid Brown // There should be no way to ever reach the InCallScreen on a 4446c5cf46a2a31f0bffe9df36da8922971f7ee296bDavid Brown // non-voice-capable device, since this activity is not exported by 4456c5cf46a2a31f0bffe9df36da8922971f7ee296bDavid Brown // our manifest, and we explicitly disable any other external APIs 4466c5cf46a2a31f0bffe9df36da8922971f7ee296bDavid Brown // like the CALL intent and ITelephony.showCallScreen(). 4476c5cf46a2a31f0bffe9df36da8922971f7ee296bDavid Brown // So the fact that we got here indicates a phone app bug. 448c3098c14cb1c0444d61ba1b6d0b81175e93bbd75David Brown Log.wtf(LOG_TAG, "onCreate() reached on non-voice-capable device"); 449c3098c14cb1c0444d61ba1b6d0b81175e93bbd75David Brown finish(); 450c3098c14cb1c0444d61ba1b6d0b81175e93bbd75David Brown return; 4516c5cf46a2a31f0bffe9df36da8922971f7ee296bDavid Brown } 4526c5cf46a2a31f0bffe9df36da8922971f7ee296bDavid Brown 453a1a9601840e50e18ff8ca4be9b888e592287577bDianne Hackborn mApp = PhoneGlobals.getInstance(); 45475e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.setInCallScreenInstance(this); 455b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 4566a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood // set this flag so this activity will stay in front of the keyguard 45734f76bf791cba483f2fc94416bf0c0882bcf03cbJeff Brown int flags = WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED 45834f76bf791cba483f2fc94416bf0c0882bcf03cbJeff Brown | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON; 459b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville if (mApp.getPhoneState() == PhoneConstants.State.OFFHOOK) { 4606a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood // While we are in call, the in-call screen should dismiss the keyguard. 4616a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood // This allows the user to press Home to go directly home without going through 4626a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood // an insecure lock screen. 4636a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood // But we do not want to do this if there is no active call so we do not 4646a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood // bypass the keyguard if the call is not answered or declined. 4656a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood flags |= WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; 4666a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood } 4674e7a7580764eada975d7a2bf4b8a1507a10ff4daJeff Brown 4684e7a7580764eada975d7a2bf4b8a1507a10ff4daJeff Brown WindowManager.LayoutParams lp = getWindow().getAttributes(); 4694e7a7580764eada975d7a2bf4b8a1507a10ff4daJeff Brown lp.flags |= flags; 4704e7a7580764eada975d7a2bf4b8a1507a10ff4daJeff Brown if (!mApp.proximitySensorModeEnabled()) { 4714e7a7580764eada975d7a2bf4b8a1507a10ff4daJeff Brown // If we don't have a proximity sensor, then the in-call screen explicitly 4724e7a7580764eada975d7a2bf4b8a1507a10ff4daJeff Brown // controls user activity. This is to prevent spurious touches from waking 4734e7a7580764eada975d7a2bf4b8a1507a10ff4daJeff Brown // the display. 4744e7a7580764eada975d7a2bf4b8a1507a10ff4daJeff Brown lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY; 4754e7a7580764eada975d7a2bf4b8a1507a10ff4daJeff Brown } 4764e7a7580764eada975d7a2bf4b8a1507a10ff4daJeff Brown getWindow().setAttributes(lp); 4776a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood 47875e3711d82d0c98444f6c438437cad41d862fca6David Brown setPhone(mApp.phone); // Sets mPhone 479c97fea097483c6e58c199e857b279ec92e64d8e3John Wang 48075e3711d82d0c98444f6c438437cad41d862fca6David Brown mCM = mApp.mCM; 48123d416d92d99bc258a82d3e3d590783766898184David Brown log("- onCreate: phone state = " + mCM.getState()); 482b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 48359d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 48459d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie if (mBluetoothAdapter != null) { 48559d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie mBluetoothAdapter.getProfileProxy(getApplicationContext(), mBluetoothProfileServiceListener, 4861d417d7ede71bbcf72a7edebf528efbfcf9b82bbJaikumar Ganesh BluetoothProfile.HEADSET); 487b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 488b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 489b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project requestWindowFeature(Window.FEATURE_NO_TITLE); 490b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 491b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Inflate everything in incall_screen.xml and add it to the screen. 492b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project setContentView(R.layout.incall_screen); 493b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 4948aca6a3c591a5dea28c69d4ddae722a13bfbe3cfGeobio Boo // If in landscape, then one of the ViewStubs (instead of <include>) is used for the 4958aca6a3c591a5dea28c69d4ddae722a13bfbe3cfGeobio Boo // incall_touch_ui, because CDMA and GSM button layouts are noticeably different. 4968aca6a3c591a5dea28c69d4ddae722a13bfbe3cfGeobio Boo final ViewStub touchUiStub = (ViewStub) findViewById( 4978aca6a3c591a5dea28c69d4ddae722a13bfbe3cfGeobio Boo mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA 4988aca6a3c591a5dea28c69d4ddae722a13bfbe3cfGeobio Boo ? R.id.inCallTouchUiCdmaStub : R.id.inCallTouchUiStub); 4998aca6a3c591a5dea28c69d4ddae722a13bfbe3cfGeobio Boo if (touchUiStub != null) touchUiStub.inflate(); 5008aca6a3c591a5dea28c69d4ddae722a13bfbe3cfGeobio Boo 501b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project initInCallScreen(); 502b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 503b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project registerForPhoneStates(); 504b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 505b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // No need to change wake state here; that happens in onResume() when we 506b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // are actually displayed. 507b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 508b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Handle the Intent we were launched with, but only if this is the 509b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the very first time we're being launched (ie. NOT if we're being 510b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // re-initialized after previously being shut down.) 511b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Once we're up and running, any future Intents we need 512b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // to handle will come in via the onNewIntent() method. 513b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (icicle == null) { 514b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("onCreate(): this is our very first launch, checking intent..."); 51575e3711d82d0c98444f6c438437cad41d862fca6David Brown internalResolveIntent(getIntent()); 516b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 517b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 518b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Profiler.callScreenCreated(); 519f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville if (DBG) log("onCreate(): exit"); 520b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 521b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 5221d417d7ede71bbcf72a7edebf528efbfcf9b82bbJaikumar Ganesh private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener = 523b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa new BluetoothProfile.ServiceListener() { 524b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa @Override 525b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa public void onServiceConnected(int profile, BluetoothProfile proxy) { 526b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa mBluetoothHeadset = (BluetoothHeadset) proxy; 527b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa if (VDBG) log("- Got BluetoothHeadset: " + mBluetoothHeadset); 528b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa } 529b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa 530b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa @Override 531b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa public void onServiceDisconnected(int profile) { 532b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa mBluetoothHeadset = null; 533b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa } 5341d417d7ede71bbcf72a7edebf528efbfcf9b82bbJaikumar Ganesh }; 5351d417d7ede71bbcf72a7edebf528efbfcf9b82bbJaikumar Ganesh 536b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 537b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Sets the Phone object used internally by the InCallScreen. 538b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 539b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * In normal operation this is called from onCreate(), and the 540b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * passed-in Phone object comes from the PhoneApp. 541b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * For testing, test classes can use this method to 542b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * inject a test Phone instance. 543b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 544b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /* package */ void setPhone(Phone phone) { 545b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhone = phone; 546b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 547b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 548b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 549b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project protected void onResume() { 550b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("onResume()..."); 551b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project super.onResume(); 552b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 553b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mIsForegroundActivity = true; 5544bf466a6d117a6fc4ddfd480f7db7606a29cb4ffMindy Pereira mIsForegroundActivityForProximity = true; 555b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 5566522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // The flag shouldn't be turned on when there are actual phone calls. 5576522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa if (mCM.hasActiveFgCall() || mCM.hasActiveBgCall() || mCM.hasActiveRingingCall()) { 5586522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa mApp.inCallUiState.showAlreadyDisconnectedState = false; 5596522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa } 5606522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa 56175e3711d82d0c98444f6c438437cad41d862fca6David Brown final InCallUiState inCallUiState = mApp.inCallUiState; 56275e3711d82d0c98444f6c438437cad41d862fca6David Brown if (VDBG) inCallUiState.dumpState(); 563b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 56437bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa updateExpandedViewState(); 56537bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa 566e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown // ...and update the in-call notification too, since the status bar 567e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown // icon needs to be hidden while we're the foreground activity: 568df266ade99188365d4a52f89a6d26b549c2aaf9aDavid Brown mApp.notificationMgr.updateInCallNotification(); 569b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 5708bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // Listen for broadcast intents that might affect the onscreen UI. 571b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG)); 572b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 5731066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown // Keep a "dialer session" active when we're in the foreground. 5741066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown // (This is needed to play DTMF tones.) 5751066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown mDialer.startDialerSession(); 5761066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown 577211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // Restore various other state from the InCallUiState object: 578211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown 579211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // Update the onscreen dialpad state to match the InCallUiState. 5803426afaf85d33d454fad8d341a1a895fd7e21c10David Brown if (inCallUiState.showDialpad) { 581b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa openDialpadInternal(false); // no "opening" animation 582211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown } else { 583b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa closeDialpadInternal(false); // no "closing" animation 584211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown } 585083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon 586083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon // Reset the dialpad context 587083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon // TODO: Dialpad digits should be set here as well (once they are saved) 588083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon mDialer.setDialpadContext(inCallUiState.dialpadContextText); 58975e3711d82d0c98444f6c438437cad41d862fca6David Brown 590524486403a387c324dee5aff7fb78ca784d15255David Brown // If there's a "Respond via SMS" popup still around since the 591dc716952ab15e7ebf52949eea4cef1740aafa168David Brown // last time we were the foreground activity, make sure it's not 592dc716952ab15e7ebf52949eea4cef1740aafa168David Brown // still active! 593dc716952ab15e7ebf52949eea4cef1740aafa168David Brown // (The popup should *never* be visible initially when we first 594dc716952ab15e7ebf52949eea4cef1740aafa168David Brown // come to the foreground; it only ever comes up in response to 595dc716952ab15e7ebf52949eea4cef1740aafa168David Brown // the user selecting the "SMS" option from the incoming call 596dc716952ab15e7ebf52949eea4cef1740aafa168David Brown // widget.) 597f4ef613d8e6f203248d459cd77a3a7074c8f817cDaisuke Miyakawa mRespondViaSmsManager.dismissPopup(); // safe even if already dismissed 598dc716952ab15e7ebf52949eea4cef1740aafa168David Brown 59975e3711d82d0c98444f6c438437cad41d862fca6David Brown // Display an error / diagnostic indication if necessary. 60075e3711d82d0c98444f6c438437cad41d862fca6David Brown // 60175e3711d82d0c98444f6c438437cad41d862fca6David Brown // When the InCallScreen comes to the foreground, we normally we 60275e3711d82d0c98444f6c438437cad41d862fca6David Brown // display the in-call UI in whatever state is appropriate based on 60375e3711d82d0c98444f6c438437cad41d862fca6David Brown // the state of the telephony framework (e.g. an outgoing call in 60475e3711d82d0c98444f6c438437cad41d862fca6David Brown // DIALING state, an incoming call, etc.) 60575e3711d82d0c98444f6c438437cad41d862fca6David Brown // 60675e3711d82d0c98444f6c438437cad41d862fca6David Brown // But if the InCallUiState has a "pending call status code" set, 60775e3711d82d0c98444f6c438437cad41d862fca6David Brown // that means we need to display some kind of status or error 60875e3711d82d0c98444f6c438437cad41d862fca6David Brown // indication to the user instead of the regular in-call UI. (The 60975e3711d82d0c98444f6c438437cad41d862fca6David Brown // most common example of this is when there's some kind of 61075e3711d82d0c98444f6c438437cad41d862fca6David Brown // failure while initiating an outgoing call; see 61175e3711d82d0c98444f6c438437cad41d862fca6David Brown // CallController.placeCall().) 61275e3711d82d0c98444f6c438437cad41d862fca6David Brown // 613a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown boolean handledStartupError = false; 61475e3711d82d0c98444f6c438437cad41d862fca6David Brown if (inCallUiState.hasPendingCallStatusCode()) { 61575e3711d82d0c98444f6c438437cad41d862fca6David Brown if (DBG) log("- onResume: need to show status indication!"); 61675e3711d82d0c98444f6c438437cad41d862fca6David Brown showStatusIndication(inCallUiState.getPendingCallStatusCode()); 617b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 61875e3711d82d0c98444f6c438437cad41d862fca6David Brown // Set handledStartupError to ensure that we won't bail out below. 61975e3711d82d0c98444f6c438437cad41d862fca6David Brown // (We need to stay here in the InCallScreen so that the user 62075e3711d82d0c98444f6c438437cad41d862fca6David Brown // is able to see the error dialog!) 621a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown handledStartupError = true; 622b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 623b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 624b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Set the volume control handler while we are in the foreground. 6252c76ab3fb8e86f630b027aec1c4ac8e294501f1eNicolas Catania final boolean bluetoothConnected = isBluetoothAudioConnected(); 6262c76ab3fb8e86f630b027aec1c4ac8e294501f1eNicolas Catania 6272c76ab3fb8e86f630b027aec1c4ac8e294501f1eNicolas Catania if (bluetoothConnected) { 628b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project setVolumeControlStream(AudioManager.STREAM_BLUETOOTH_SCO); 629b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 630b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project setVolumeControlStream(AudioManager.STREAM_VOICE_CALL); 631b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 632b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 633b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project takeKeyEvents(true); 634b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 635211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // If an OTASP call is in progress, use the special OTASP-specific UI. 6369d3a3d147a543ec23113fa59732f9f73ba28386fWink Saville boolean inOtaCall = false; 6379e22d35e5f1d33613ce13745d83d59fcfc2e506eDavid Brown if (TelephonyCapabilities.supportsOtasp(mPhone)) { 638211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown inOtaCall = checkOtaspStateOnResume(); 639af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 6409d3a3d147a543ec23113fa59732f9f73ba28386fWink Saville if (!inOtaCall) { 641af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville // Always start off in NORMAL mode 642af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville setInCallScreenMode(InCallScreenMode.NORMAL); 643af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 644b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 6458343169cc89621d46dce86449f5ee1ff5d3a4919John Wang // Before checking the state of the CallManager, clean up any 646b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // connections in the DISCONNECTED state. 647b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (The DISCONNECTED state is used only to drive the "call ended" 648b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // UI; it's totally useless when *entering* the InCallScreen.) 6498343169cc89621d46dce86449f5ee1ff5d3a4919John Wang mCM.clearDisconnected(); 650b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 65196af4b62835c1d0d023d285b896226386621e283David Brown // Update the onscreen UI to reflect the current telephony state. 65275e3711d82d0c98444f6c438437cad41d862fca6David Brown SyncWithPhoneStateStatus status = syncWithPhoneState(); 653211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown 65496af4b62835c1d0d023d285b896226386621e283David Brown // Note there's no need to call updateScreen() here; 65596af4b62835c1d0d023d285b896226386621e283David Brown // syncWithPhoneState() already did that if necessary. 65696af4b62835c1d0d023d285b896226386621e283David Brown 65775e3711d82d0c98444f6c438437cad41d862fca6David Brown if (status != SyncWithPhoneStateStatus.SUCCESS) { 658a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown if (DBG) log("- onResume: syncWithPhoneState failed! status = " + status); 659b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Couldn't update the UI, presumably because the phone is totally 660a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown // idle. 661a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown 6623426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // Even though the phone is idle, though, we do still need to 6633426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // stay here on the InCallScreen if we're displaying an 6643426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // error dialog (see "showStatusIndication()" above). 6653426afaf85d33d454fad8d341a1a895fd7e21c10David Brown 666a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown if (handledStartupError) { 6673426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // Stay here for now. We'll eventually leave the 6683426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // InCallScreen when the user presses the dialog's OK 6693426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // button (see bailOutAfterErrorDialog()), or when the 6703426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // progress indicator goes away. 67195bef36fa7efe381db81ec08b6244daf02414a28David Brown Log.i(LOG_TAG, " ==> syncWithPhoneState failed, but staying here anyway."); 672a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown } else { 673a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown // The phone is idle, and we did NOT handle a 674a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown // startup error during this pass thru onResume. 675a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown // 676a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown // This basically means that we're being resumed because of 677a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown // some action *other* than a new intent. (For example, 678a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown // the user pressing POWER to wake up the device, causing 679a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown // the InCallScreen to come back to the foreground.) 680a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown // 681a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown // In this scenario we do NOT want to stay here on the 682a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown // InCallScreen: we're not showing any useful info to the 683a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown // user (like a dialog), and the in-call UI itself is 684a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown // useless if there's no active call. So bail out. 68575e3711d82d0c98444f6c438437cad41d862fca6David Brown 68695bef36fa7efe381db81ec08b6244daf02414a28David Brown Log.i(LOG_TAG, " ==> syncWithPhoneState failed; bailing out!"); 687a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown dismissAllDialogs(); 68895407b4abc7b7fcb518b6b86c2231711192b4f40David Brown 68995407b4abc7b7fcb518b6b86c2231711192b4f40David Brown // Force the InCallScreen to truly finish(), rather than just 69095407b4abc7b7fcb518b6b86c2231711192b4f40David Brown // moving it to the back of the activity stack (which is what 69195407b4abc7b7fcb518b6b86c2231711192b4f40David Brown // our finish() method usually does.) 69295407b4abc7b7fcb518b6b86c2231711192b4f40David Brown // This is necessary to avoid an obscure scenario where the 69395407b4abc7b7fcb518b6b86c2231711192b4f40David Brown // InCallScreen can get stuck in an inconsistent state, somehow 69495407b4abc7b7fcb518b6b86c2231711192b4f40David Brown // causing a *subsequent* outgoing call to fail (bug 4172599). 69595407b4abc7b7fcb518b6b86c2231711192b4f40David Brown endInCallScreenSession(true /* force a real finish() call */); 696a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown return; 697a0b61c4559f9d8046a8330da7f0d9b42ccbad7e2David Brown } 6989e22d35e5f1d33613ce13745d83d59fcfc2e506eDavid Brown } else if (TelephonyCapabilities.supportsOtasp(mPhone)) { 69975e3711d82d0c98444f6c438437cad41d862fca6David Brown if (inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL || 70075e3711d82d0c98444f6c438437cad41d862fca6David Brown inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED) { 7010d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa if (mCallCard != null) mCallCard.setVisibility(View.GONE); 702af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville updateScreen(); 703af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville return; 704af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 705b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 706b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 707cd89106dcd1038666f992cea3cc79e067245187fDan Egnor // InCallScreen is now active. 708cd89106dcd1038666f992cea3cc79e067245187fDan Egnor EventLog.writeEvent(EventLogTags.PHONE_UI_ENTER); 709b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 710f4ef613d8e6f203248d459cd77a3a7074c8f817cDaisuke Miyakawa // Update the poke lock and wake lock when we move to the foreground. 711f4ef613d8e6f203248d459cd77a3a7074c8f817cDaisuke Miyakawa // This will be no-op when prox sensor is effective. 71275e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.updateWakeState(); 713b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 714b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Restore the mute state if the last mute state change was NOT 715b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // done by the user. 71675e3711d82d0c98444f6c438437cad41d862fca6David Brown if (mApp.getRestoreMuteOnInCallResume()) { 7178343169cc89621d46dce86449f5ee1ff5d3a4919John Wang // Mute state is based on the foreground call 718a50e10e2efadac960987eaadc0938c6f92d3ee90John Wang PhoneUtils.restoreMuteState(); 71975e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.setRestoreMuteOnInCallResume(false); 720b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 721b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 722b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Profiler.profileViewCreate(getWindow(), InCallScreen.class.getName()); 7236522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa 724eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // If there's a pending MMI code, we'll show a dialog here. 725eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // 726eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // Note: previously we had shown the dialog when MMI_INITIATE event's coming 727eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // from telephony layer, while right now we don't because the event comes 728eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // too early (before in-call screen is prepared). 729eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // Now we instead check pending MMI code and show the dialog here. 730eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // 731eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // This *may* cause some problem, e.g. when the user really quickly starts 732eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // MMI sequence and calls an actual phone number before the MMI request 733eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // being completed, which is rather rare. 734eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // 735eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // TODO: streamline this logic and have a UX in a better manner. 736eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // Right now syncWithPhoneState() above will return SUCCESS based on 737eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // mPhone.getPendingMmiCodes().isEmpty(), while we check it again here. 738eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // Also we show pre-populated in-call UI under the dialog, which looks 739eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // not great. (issue 5210375, 5545506) 740eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // After cleaning them, remove commented-out MMI handling code elsewhere. 741eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa if (!mPhone.getPendingMmiCodes().isEmpty()) { 742eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa if (mMmiStartedDialog == null) { 743eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa MmiCode mmiCode = mPhone.getPendingMmiCodes().get(0); 744a1a9601840e50e18ff8ca4be9b888e592287577bDianne Hackborn Message message = Message.obtain(mHandler, PhoneGlobals.MMI_CANCEL); 745eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa mMmiStartedDialog = PhoneUtils.displayMMIInitiate(this, mmiCode, 746eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa message, mMmiStartedDialog); 747eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // mInCallScreen needs to receive MMI_COMPLETE/MMI_CANCEL event from telephony, 748eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // which will dismiss the entire screen. 749eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa } 750eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa } 751eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa 7526522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // This means the screen is shown even though there's no connection, which only happens 7536522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // when the phone call has hung up while the screen is turned off at that moment. 7546522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // We want to show "disconnected" state with photos with appropriate elapsed time for 7556522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // the finished phone call. 7566522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa if (mApp.inCallUiState.showAlreadyDisconnectedState) { 7576522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // if (DBG) { 7586522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa log("onResume(): detected \"show already disconnected state\" situation." 7596522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa + " set up DELAYED_CLEANUP_AFTER_DISCONNECT message with " 7606522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa + CALL_ENDED_LONG_DELAY + " msec delay."); 7616522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa //} 7626522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa mHandler.removeMessages(DELAYED_CLEANUP_AFTER_DISCONNECT); 7636522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa mHandler.sendEmptyMessageDelayed(DELAYED_CLEANUP_AFTER_DISCONNECT, 7646522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa CALL_ENDED_LONG_DELAY); 7656522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa } 7666522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa 767796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("onResume() done."); 768b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 769b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 770b8db8aaa81157526ef8d0ee6ee7db91401cf3c14Nicolas Catania // onPause is guaranteed to be called when the InCallScreen goes 771b8db8aaa81157526ef8d0ee6ee7db91401cf3c14Nicolas Catania // in the background. 772b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 773b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project protected void onPause() { 774b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("onPause()..."); 775b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project super.onPause(); 776b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 7774bf466a6d117a6fc4ddfd480f7db7606a29cb4ffMindy Pereira if (mPowerManager.isScreenOn()) { 7786522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // Set to false when the screen went background *not* by screen turned off. Probably 7796522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // the user bailed out of the in-call screen (by pressing BACK, HOME, etc.) 7804bf466a6d117a6fc4ddfd480f7db7606a29cb4ffMindy Pereira mIsForegroundActivityForProximity = false; 7814bf466a6d117a6fc4ddfd480f7db7606a29cb4ffMindy Pereira } 782b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mIsForegroundActivity = false; 783b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 784b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa // Force a clear of the provider info frame. Since the 785b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa // frame is removed using a timed message, it is 786b8db8aaa81157526ef8d0ee6ee7db91401cf3c14Nicolas Catania // possible we missed it if the prev call was interrupted. 787b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa mApp.inCallUiState.providerInfoVisible = false; 788b8db8aaa81157526ef8d0ee6ee7db91401cf3c14Nicolas Catania 7896522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // "show-already-disconnected-state" should be effective just during the first wake-up. 7906522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // We should never allow it to stay true after that. 7916522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa mApp.inCallUiState.showAlreadyDisconnectedState = false; 7926522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa 793445c9030dc93750a8209ace086ea3820ee33f0b1Mike Lockwood // A safety measure to disable proximity sensor in case call failed 794445c9030dc93750a8209ace086ea3820ee33f0b1Mike Lockwood // and the telephony state did not change. 79575e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.setBeginningCall(false); 796445c9030dc93750a8209ace086ea3820ee33f0b1Mike Lockwood 7977b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown // Make sure the "Manage conference" chronometer is stopped when 7987b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown // we move away from the foreground. 7997b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown mManageConferenceUtils.stopConferenceTime(); 800b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 801b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // as a catch-all, make sure that any dtmf tones are stopped 802b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // when the UI is no longer in the foreground. 803b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDialer.onDialerKeyUp(null); 804b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 8051066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown // Release any "dialer session" resources, now that we're no 8061066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown // longer in the foreground. 8071066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown mDialer.stopDialerSession(); 8081066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown 809b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // If the device is put to sleep as the phone call is ending, 810b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // we may see cases where the DELAYED_CLEANUP_AFTER_DISCONNECT 811b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // event gets handled AFTER the device goes to sleep and wakes 812b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // up again. 813b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 814b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // This is because it is possible for a sleep command 815b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (executed with the End Call key) to come during the 2 816b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // seconds that the "Call Ended" screen is up. Sleep then 817b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // pauses the device (including the cleanup event) and 818b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // resumes the event when it wakes up. 819b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 820b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // To fix this, we introduce a bit of code that pushes the UI 821b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // to the background if we pause and see a request to 822b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // DELAYED_CLEANUP_AFTER_DISCONNECT. 823b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 824b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Note: We can try to finish directly, by: 825b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 1. Removing the DELAYED_CLEANUP_AFTER_DISCONNECT messages 826b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 2. Calling delayedCleanupAfterDisconnect directly 827b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 828b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // However, doing so can cause problems between the phone 829b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // app and the keyguard - the keyguard is trying to sleep at 830b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the same time that the phone state is changing. This can 831b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // end up causing the sleep request to be ignored. 832f717662ca0f2a8aeb7f1740b000a458253afc97cPeng Zhu if (mHandler.hasMessages(DELAYED_CLEANUP_AFTER_DISCONNECT) 833b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville && mCM.getState() != PhoneConstants.State.RINGING) { 8346f11c0b721507e762af13d60856fcf53ab6e089aDaisuke Miyakawa if (DBG) log("DELAYED_CLEANUP_AFTER_DISCONNECT detected, moving UI to background."); 8354a5a966f0d43e04d336be1b94182346399a931f6Wink Saville endInCallScreenSession(); 836b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 837b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 838cd89106dcd1038666f992cea3cc79e067245187fDan Egnor EventLog.writeEvent(EventLogTags.PHONE_UI_EXIT); 839b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 840b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Dismiss any dialogs we may have brought up, just to be 100% 841b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // sure they won't still be around when we get back here. 842b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project dismissAllDialogs(); 843b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 84437bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa updateExpandedViewState(); 84537bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa 846e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown // ...and the in-call notification too: 847df266ade99188365d4a52f89a6d26b549c2aaf9aDavid Brown mApp.notificationMgr.updateInCallNotification(); 848c3e9fcc498a0212fde17f1b4ef09356c42b1af55David Brown // ...and *always* reset the system bar back to its normal state 849c3e9fcc498a0212fde17f1b4ef09356c42b1af55David Brown // when leaving the in-call UI. 850c3e9fcc498a0212fde17f1b4ef09356c42b1af55David Brown // (While we're the foreground activity, we disable navigation in 851c3e9fcc498a0212fde17f1b4ef09356c42b1af55David Brown // some call states; see InCallTouchUi.updateState().) 852c3e9fcc498a0212fde17f1b4ef09356c42b1af55David Brown mApp.notificationMgr.statusBarHelper.enableSystemBarNavigation(true); 853b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 8548bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // Unregister for broadcast intents. (These affect the visible UI 8558bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // of the InCallScreen, so we only care about them while we're in the 856b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // foreground.) 857b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project unregisterReceiver(mReceiver); 858b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 859b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Make sure we revert the poke lock and wake lock when we move to 860b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the background. 86175e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.updateWakeState(); 8626a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood 8636a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood // clear the dismiss keyguard flag so we are back to the default state 8646a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood // when we next resume 8656a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood updateKeyguardPolicy(false); 866b86f9397f1b1d3d385b9ff3f393fcd8f2ecac44dDaisuke Miyakawa 867b86f9397f1b1d3d385b9ff3f393fcd8f2ecac44dDaisuke Miyakawa // See also PhoneApp#updatePhoneState(), which takes care of all the other release() calls. 868b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville if (mApp.getUpdateLock().isHeld() && mApp.getPhoneState() == PhoneConstants.State.IDLE) { 869b86f9397f1b1d3d385b9ff3f393fcd8f2ecac44dDaisuke Miyakawa if (DBG) { 870b86f9397f1b1d3d385b9ff3f393fcd8f2ecac44dDaisuke Miyakawa log("Release UpdateLock on onPause() because there's no active phone call."); 871b86f9397f1b1d3d385b9ff3f393fcd8f2ecac44dDaisuke Miyakawa } 872b86f9397f1b1d3d385b9ff3f393fcd8f2ecac44dDaisuke Miyakawa mApp.getUpdateLock().release(); 873b86f9397f1b1d3d385b9ff3f393fcd8f2ecac44dDaisuke Miyakawa } 874b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 875b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 876b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 877b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project protected void onStop() { 8785c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville if (DBG) log("onStop()..."); 879b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project super.onStop(); 880b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 881b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project stopTimer(); 882b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 883b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville PhoneConstants.State state = mCM.getState(); 8845c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville if (DBG) log("onStop: state = " + state); 885b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 886b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville if (state == PhoneConstants.State.IDLE) { 887f4ef613d8e6f203248d459cd77a3a7074c8f817cDaisuke Miyakawa if (mRespondViaSmsManager.isShowingPopup()) { 888552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa // This means that the user has been opening the "Respond via SMS" dialog even 889552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa // after the incoming call hanging up, and the screen finally went background. 890552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa // In that case we just close the dialog and exit the whole in-call screen. 891552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa mRespondViaSmsManager.dismissPopup(); 892552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa } 893552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa 894af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville // when OTA Activation, OTA Success/Failure dialog or OTA SPC 895af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville // failure dialog is running, do not destroy inCallScreen. Because call 896af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville // is already ended and dialog will not get redrawn on slider event. 89775e3711d82d0c98444f6c438437cad41d862fca6David Brown if ((mApp.cdmaOtaProvisionData != null) && (mApp.cdmaOtaScreenState != null) 89875e3711d82d0c98444f6c438437cad41d862fca6David Brown && ((mApp.cdmaOtaScreenState.otaScreenState != 899af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION) 90075e3711d82d0c98444f6c438437cad41d862fca6David Brown && (mApp.cdmaOtaScreenState.otaScreenState != 901af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG) 90275e3711d82d0c98444f6c438437cad41d862fca6David Brown && (!mApp.cdmaOtaProvisionData.inOtaSpcState))) { 903af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville // we don't want the call screen to remain in the activity history 904af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville // if there are not active or ringing calls. 905af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville if (DBG) log("- onStop: calling finish() to clear activity history..."); 9064a5a966f0d43e04d336be1b94182346399a931f6Wink Saville moveTaskToBack(true); 90775e3711d82d0c98444f6c438437cad41d862fca6David Brown if (mApp.otaUtils != null) { 90875e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.otaUtils.cleanOtaScreen(true); 909af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 910af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 911b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 912b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 913b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 914b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 915b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project protected void onDestroy() { 916ae6bb3d59ba1c1551ef626de51c11c70231d2653David Brown Log.i(LOG_TAG, "onDestroy()... this = " + this); 917b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project super.onDestroy(); 918b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 919b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Set the magic flag that tells us NOT to handle any handler 920b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // messages that come in asynchronously after we get destroyed. 921b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mIsDestroyed = true; 922b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 92375e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.setInCallScreenInstance(null); 924b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 9258bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // Clear out the InCallScreen references in various helper objects 9268bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // (to let them know we've been destroyed). 9278bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project if (mCallCard != null) { 9288bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project mCallCard.setInCallScreenInstance(null); 9298bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project } 9304d910f9df60b820d3461995c1d85d0581041b531David Brown if (mInCallTouchUi != null) { 9314d910f9df60b820d3461995c1d85d0581041b531David Brown mInCallTouchUi.setInCallScreenInstance(null); 9324d910f9df60b820d3461995c1d85d0581041b531David Brown } 933f4ef613d8e6f203248d459cd77a3a7074c8f817cDaisuke Miyakawa mRespondViaSmsManager.setInCallScreenInstance(null); 934b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 935b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDialer.clearInCallScreenReference(); 936b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDialer = null; 937b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 938b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project unregisterForPhoneStates(); 939b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // No need to change wake state here; that happens in onPause() when we 940b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // are moving out of the foreground. 941b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 942b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mBluetoothHeadset != null) { 94359d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset); 944b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mBluetoothHeadset = null; 945b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 9465eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown 9475eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown // Dismiss all dialogs, to be absolutely sure we won't leak any of 9485eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown // them while changing orientation. 9495eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown dismissAllDialogs(); 950211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown 951211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // If there's an OtaUtils instance around, clear out its 952211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // references to our internal widgets. 953211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown if (mApp.otaUtils != null) { 954211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown mApp.otaUtils.clearUiWidgets(); 955211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown } 956b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 957b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 958b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 959b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Dismisses the in-call screen. 960b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 961b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * We never *really* finish() the InCallScreen, since we don't want to 962b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * get destroyed and then have to be re-created from scratch for the 963b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * next call. Instead, we just move ourselves to the back of the 964b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * activity stack. 965b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 966b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * This also means that we'll no longer be reachable via the BACK 967b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * button (since moveTaskToBack() puts us behind the Home app, but the 968b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * home app doesn't allow the BACK key to move you any farther down in 969b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * the history stack.) 970b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 971b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * (Since the Phone app itself is never killed, this basically means 972b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * that we'll keep a single InCallScreen instance around for the 973b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * entire uptime of the device. This noticeably improves the UI 974b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * responsiveness for incoming calls.) 975b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 976b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 977b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void finish() { 978279cb7a45f86875939fb3bbb65a27f71b5f690fbDavid Brown if (DBG) log("finish()..."); 979b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project moveTaskToBack(true); 9804a5a966f0d43e04d336be1b94182346399a931f6Wink Saville } 9814a5a966f0d43e04d336be1b94182346399a931f6Wink Saville 9824a5a966f0d43e04d336be1b94182346399a931f6Wink Saville /** 9834a5a966f0d43e04d336be1b94182346399a931f6Wink Saville * End the current in call screen session. 9844a5a966f0d43e04d336be1b94182346399a931f6Wink Saville * 9854a5a966f0d43e04d336be1b94182346399a931f6Wink Saville * This must be called when an InCallScreen session has 9864a5a966f0d43e04d336be1b94182346399a931f6Wink Saville * complete so that the next invocation via an onResume will 9874a5a966f0d43e04d336be1b94182346399a931f6Wink Saville * not be in an old state. 9884a5a966f0d43e04d336be1b94182346399a931f6Wink Saville */ 9894a5a966f0d43e04d336be1b94182346399a931f6Wink Saville public void endInCallScreenSession() { 9903bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown if (DBG) log("endInCallScreenSession()... phone state = " + mCM.getState()); 99195407b4abc7b7fcb518b6b86c2231711192b4f40David Brown endInCallScreenSession(false); 99295407b4abc7b7fcb518b6b86c2231711192b4f40David Brown } 99395407b4abc7b7fcb518b6b86c2231711192b4f40David Brown 99495407b4abc7b7fcb518b6b86c2231711192b4f40David Brown /** 99595407b4abc7b7fcb518b6b86c2231711192b4f40David Brown * Internal version of endInCallScreenSession(). 99695407b4abc7b7fcb518b6b86c2231711192b4f40David Brown * 99795407b4abc7b7fcb518b6b86c2231711192b4f40David Brown * @param forceFinish If true, force the InCallScreen to 99895407b4abc7b7fcb518b6b86c2231711192b4f40David Brown * truly finish() rather than just calling moveTaskToBack(). 99995407b4abc7b7fcb518b6b86c2231711192b4f40David Brown * @see finish() 100095407b4abc7b7fcb518b6b86c2231711192b4f40David Brown */ 100195407b4abc7b7fcb518b6b86c2231711192b4f40David Brown private void endInCallScreenSession(boolean forceFinish) { 10026f11c0b721507e762af13d60856fcf53ab6e089aDaisuke Miyakawa if (DBG) { 10036f11c0b721507e762af13d60856fcf53ab6e089aDaisuke Miyakawa log("endInCallScreenSession(" + forceFinish + ")... phone state = " + mCM.getState()); 10046f11c0b721507e762af13d60856fcf53ab6e089aDaisuke Miyakawa } 100595407b4abc7b7fcb518b6b86c2231711192b4f40David Brown if (forceFinish) { 100695407b4abc7b7fcb518b6b86c2231711192b4f40David Brown Log.i(LOG_TAG, "endInCallScreenSession(): FORCING a call to super.finish()!"); 100795407b4abc7b7fcb518b6b86c2231711192b4f40David Brown super.finish(); // Call super.finish() rather than our own finish() method, 100895407b4abc7b7fcb518b6b86c2231711192b4f40David Brown // which actually just calls moveTaskToBack(). 100995407b4abc7b7fcb518b6b86c2231711192b4f40David Brown } else { 101095407b4abc7b7fcb518b6b86c2231711192b4f40David Brown moveTaskToBack(true); 101195407b4abc7b7fcb518b6b86c2231711192b4f40David Brown } 1012af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville setInCallScreenMode(InCallScreenMode.UNDEFINED); 1013ce6beda7395695a9637eb207ec946a8a173be0b3Santos Cordon 1014ce6beda7395695a9637eb207ec946a8a173be0b3Santos Cordon // Call update screen so that the in-call screen goes back to a normal state. 1015ce6beda7395695a9637eb207ec946a8a173be0b3Santos Cordon // This avoids bugs where a previous state will filcker the next time phone is 1016ce6beda7395695a9637eb207ec946a8a173be0b3Santos Cordon // opened. 1017ce6beda7395695a9637eb207ec946a8a173be0b3Santos Cordon updateScreen(); 101872f5cb409eb590a93fed80cf9d49c72d699ee285Chiao Cheng 101972f5cb409eb590a93fed80cf9d49c72d699ee285Chiao Cheng if (mCallCard != null) { 102072f5cb409eb590a93fed80cf9d49c72d699ee285Chiao Cheng mCallCard.clear(); 102172f5cb409eb590a93fed80cf9d49c72d699ee285Chiao Cheng } 1022b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1023b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 10246522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa /** 10256522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa * True when this Activity is in foreground (between onResume() and onPause()). 10266522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa */ 1027b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /* package */ boolean isForegroundActivity() { 1028b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return mIsForegroundActivity; 1029b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1030b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 10316522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa /** 10326522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa * Returns true when the Activity is in foreground (between onResume() and onPause()), 10336522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa * or, is in background due to user's bailing out of the screen, not by screen turning off. 10346522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa * 10356522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa * @see #isForegroundActivity() 10366522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa */ 10374bf466a6d117a6fc4ddfd480f7db7606a29cb4ffMindy Pereira /* package */ boolean isForegroundActivityForProximity() { 10384bf466a6d117a6fc4ddfd480f7db7606a29cb4ffMindy Pereira return mIsForegroundActivityForProximity; 10394bf466a6d117a6fc4ddfd480f7db7606a29cb4ffMindy Pereira } 10404bf466a6d117a6fc4ddfd480f7db7606a29cb4ffMindy Pereira 10416a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood /* package */ void updateKeyguardPolicy(boolean dismissKeyguard) { 10426a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood if (dismissKeyguard) { 10436a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); 10446a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood } else { 10456a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); 10466a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood } 10476a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood } 10486a8928a7265b6586b561e60ee93b23f5fa6f30eaMike Lockwood 1049b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void registerForPhoneStates() { 1050b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (!mRegisteredForPhoneStates) { 10518343169cc89621d46dce86449f5ee1ff5d3a4919John Wang mCM.registerForPreciseCallStateChanged(mHandler, PHONE_STATE_CHANGED, null); 10528343169cc89621d46dce86449f5ee1ff5d3a4919John Wang mCM.registerForDisconnect(mHandler, PHONE_DISCONNECT, null); 1053eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // TODO: sort out MMI code (probably we should remove this method entirely). 1054eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // See also MMI handling code in onResume() 1055eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // mCM.registerForMmiInitiate(mHandler, PhoneApp.MMI_INITIATE, null); 1056eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa 105734b17481486fc41e99627d68dda9b5c075b4cc8eJohn Wang // register for the MMI complete message. Upon completion, 105834b17481486fc41e99627d68dda9b5c075b4cc8eJohn Wang // PhoneUtils will bring up a system dialog instead of the 105934b17481486fc41e99627d68dda9b5c075b4cc8eJohn Wang // message display class in PhoneUtils.displayMMIComplete(). 106034b17481486fc41e99627d68dda9b5c075b4cc8eJohn Wang // We'll listen for that message too, so that we can finish 106134b17481486fc41e99627d68dda9b5c075b4cc8eJohn Wang // the activity at the same time. 1062a1a9601840e50e18ff8ca4be9b888e592287577bDianne Hackborn mCM.registerForMmiComplete(mHandler, PhoneGlobals.MMI_COMPLETE, null); 106334b17481486fc41e99627d68dda9b5c075b4cc8eJohn Wang mCM.registerForCallWaiting(mHandler, PHONE_CDMA_CALL_WAITING, null); 106434b17481486fc41e99627d68dda9b5c075b4cc8eJohn Wang mCM.registerForPostDialCharacter(mHandler, POST_ON_DIAL_CHARS, null); 10659afe1de771110096822a2501d78135575101421dJohn Wang mCM.registerForSuppServiceFailed(mHandler, SUPP_SERVICE_FAILED, null); 1066493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown mCM.registerForIncomingRing(mHandler, PHONE_INCOMING_RING, null); 1067fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown mCM.registerForNewRingingConnection(mHandler, PHONE_NEW_RINGING_CONNECTION, null); 1068b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mRegisteredForPhoneStates = true; 1069b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1070b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1071b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1072b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void unregisterForPhoneStates() { 10738343169cc89621d46dce86449f5ee1ff5d3a4919John Wang mCM.unregisterForPreciseCallStateChanged(mHandler); 10748343169cc89621d46dce86449f5ee1ff5d3a4919John Wang mCM.unregisterForDisconnect(mHandler); 10758343169cc89621d46dce86449f5ee1ff5d3a4919John Wang mCM.unregisterForMmiInitiate(mHandler); 107634b17481486fc41e99627d68dda9b5c075b4cc8eJohn Wang mCM.unregisterForMmiComplete(mHandler); 10778343169cc89621d46dce86449f5ee1ff5d3a4919John Wang mCM.unregisterForCallWaiting(mHandler); 107834b17481486fc41e99627d68dda9b5c075b4cc8eJohn Wang mCM.unregisterForPostDialCharacter(mHandler); 1079493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown mCM.unregisterForSuppServiceFailed(mHandler); 1080493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown mCM.unregisterForIncomingRing(mHandler); 1081fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown mCM.unregisterForNewRingingConnection(mHandler); 1082b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mRegisteredForPhoneStates = false; 1083b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1084b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 108587258b2b589c3afea4b89b840251012378e0d3b4David Brown /* package */ void updateAfterRadioTechnologyChange() { 108687258b2b589c3afea4b89b840251012378e0d3b4David Brown if (DBG) Log.d(LOG_TAG, "updateAfterRadioTechnologyChange()..."); 1087065752d0b858268bd1fe3208f64129638fcdf411Wink Saville 1088065752d0b858268bd1fe3208f64129638fcdf411Wink Saville // Reset the call screen since the calls cannot be transferred 1089065752d0b858268bd1fe3208f64129638fcdf411Wink Saville // across radio technologies. 1090065752d0b858268bd1fe3208f64129638fcdf411Wink Saville resetInCallScreenMode(); 1091065752d0b858268bd1fe3208f64129638fcdf411Wink Saville 109287258b2b589c3afea4b89b840251012378e0d3b4David Brown // Unregister for all events from the old obsolete phone 109387258b2b589c3afea4b89b840251012378e0d3b4David Brown unregisterForPhoneStates(); 109487258b2b589c3afea4b89b840251012378e0d3b4David Brown 109587258b2b589c3afea4b89b840251012378e0d3b4David Brown // (Re)register for all events relevant to the new active phone 109687258b2b589c3afea4b89b840251012378e0d3b4David Brown registerForPhoneStates(); 109796af4b62835c1d0d023d285b896226386621e283David Brown 109896af4b62835c1d0d023d285b896226386621e283David Brown // And finally, refresh the onscreen UI. (Note that it's safe 109996af4b62835c1d0d023d285b896226386621e283David Brown // to call requestUpdateScreen() even if the radio change ended up 110096af4b62835c1d0d023d285b896226386621e283David Brown // causing us to exit the InCallScreen.) 110196af4b62835c1d0d023d285b896226386621e283David Brown requestUpdateScreen(); 110287258b2b589c3afea4b89b840251012378e0d3b4David Brown } 110387258b2b589c3afea4b89b840251012378e0d3b4David Brown 1104b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 1105b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project protected void onNewIntent(Intent intent) { 110623d416d92d99bc258a82d3e3d590783766898184David Brown log("onNewIntent: intent = " + intent + ", phone state = " + mCM.getState()); 1107b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1108211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // We're being re-launched with a new Intent. Since it's possible for a 1109211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // single InCallScreen instance to persist indefinitely (even if we 1110211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // finish() ourselves), this sequence can potentially happen any time 1111211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // the InCallScreen needs to be displayed. 111242901988b4b746fb17c70e9eb40951ed395fd078David Brown 111342901988b4b746fb17c70e9eb40951ed395fd078David Brown // Stash away the new intent so that we can get it in the future 111442901988b4b746fb17c70e9eb40951ed395fd078David Brown // by calling getIntent(). (Otherwise getIntent() will return the 111542901988b4b746fb17c70e9eb40951ed395fd078David Brown // original Intent from when we first got created!) 111642901988b4b746fb17c70e9eb40951ed395fd078David Brown setIntent(intent); 111742901988b4b746fb17c70e9eb40951ed395fd078David Brown 1118b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Activities are always paused before receiving a new intent, so 1119b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // we can count on our onResume() method being called next. 112042901988b4b746fb17c70e9eb40951ed395fd078David Brown 112175e3711d82d0c98444f6c438437cad41d862fca6David Brown // Just like in onCreate(), handle the intent. 112275e3711d82d0c98444f6c438437cad41d862fca6David Brown internalResolveIntent(intent); 1123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1124b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 112575e3711d82d0c98444f6c438437cad41d862fca6David Brown private void internalResolveIntent(Intent intent) { 1126b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (intent == null || intent.getAction() == null) { 112775e3711d82d0c98444f6c438437cad41d862fca6David Brown return; 1128b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1129b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project String action = intent.getAction(); 113042901988b4b746fb17c70e9eb40951ed395fd078David Brown if (DBG) log("internalResolveIntent: action=" + action); 1131b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1132211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // In gingerbread and earlier releases, the InCallScreen used to 1133211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // directly handle certain intent actions that could initiate phone 1134211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // calls, namely ACTION_CALL and ACTION_CALL_EMERGENCY, and also 1135211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // OtaUtils.ACTION_PERFORM_CDMA_PROVISIONING. 113658e4707b6cc021a663deae3e614364545ec9ee6aDavid Brown // 1137211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // But it doesn't make sense to tie those actions to the InCallScreen 1138211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // (or especially to the *activity lifecycle* of the InCallScreen). 1139211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // Instead, the InCallScreen should only be concerned with running the 1140211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // onscreen UI while in a call. So we've now offloaded the call-control 1141211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // functionality to a new module called CallController, and OTASP calls 1142211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // are now launched from the OtaUtils startInteractiveOtasp() or 1143211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // startNonInteractiveOtasp() methods. 1144211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // 1145211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // So now, the InCallScreen is only ever launched using the ACTION_MAIN 1146211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // action, and (upon launch) performs no functionality other than 1147211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // displaying the UI in a state that matches the current telephony 1148211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // state. 1149b154630235935e1aab2a41eff9ed794d40084a02David Brown 1150211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown if (action.equals(intent.ACTION_MAIN)) { 1151211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // This action is the normal way to bring up the in-call UI. 1152211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // 1153211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // Most of the interesting work of updating the onscreen UI (to 1154211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // match the current telephony state) happens in the 1155211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // syncWithPhoneState() => updateScreen() sequence that happens in 1156211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // onResume(). 1157211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // 1158211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // But we do check here for one extra that can come along with the 1159211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // ACTION_MAIN intent: 116075e3711d82d0c98444f6c438437cad41d862fca6David Brown 1161b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (intent.hasExtra(SHOW_DIALPAD_EXTRA)) { 1162211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // SHOW_DIALPAD_EXTRA can be used here to specify whether the DTMF 1163211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // dialpad should be initially visible. If the extra isn't 1164211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // present at all, we just leave the dialpad in its previous state. 1165211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown 1166b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean showDialpad = intent.getBooleanExtra(SHOW_DIALPAD_EXTRA, false); 1167d1b19c70340c258796e7c2ebe6459c65cb16245fDavid Brown if (VDBG) log("- internalResolveIntent: SHOW_DIALPAD_EXTRA: " + showDialpad); 116875e3711d82d0c98444f6c438437cad41d862fca6David Brown 116975e3711d82d0c98444f6c438437cad41d862fca6David Brown // If SHOW_DIALPAD_EXTRA is specified, that overrides whatever 117075e3711d82d0c98444f6c438437cad41d862fca6David Brown // the previous state of inCallUiState.showDialpad was. 117175e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.inCallUiState.showDialpad = showDialpad; 11728aa857142fb0fb0fa708483a3bc6a4719a2a1b2eDaisuke Miyakawa 11738aa857142fb0fb0fa708483a3bc6a4719a2a1b2eDaisuke Miyakawa final boolean hasActiveCall = mCM.hasActiveFgCall(); 11748aa857142fb0fb0fa708483a3bc6a4719a2a1b2eDaisuke Miyakawa final boolean hasHoldingCall = mCM.hasActiveBgCall(); 11758aa857142fb0fb0fa708483a3bc6a4719a2a1b2eDaisuke Miyakawa 11768aa857142fb0fb0fa708483a3bc6a4719a2a1b2eDaisuke Miyakawa // There's only one line in use, AND it's on hold, at which we're sure the user 11778aa857142fb0fb0fa708483a3bc6a4719a2a1b2eDaisuke Miyakawa // wants to use the dialpad toward the exact line, so un-hold the holding line. 11788aa857142fb0fb0fa708483a3bc6a4719a2a1b2eDaisuke Miyakawa if (showDialpad && !hasActiveCall && hasHoldingCall) { 11798aa857142fb0fb0fa708483a3bc6a4719a2a1b2eDaisuke Miyakawa PhoneUtils.switchHoldingAndActive(mCM.getFirstActiveBgCall()); 11808aa857142fb0fb0fa708483a3bc6a4719a2a1b2eDaisuke Miyakawa } 118175e3711d82d0c98444f6c438437cad41d862fca6David Brown } 1182211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // ...and in onResume() we'll update the onscreen dialpad state to 1183211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // match the InCallUiState. 118475e3711d82d0c98444f6c438437cad41d862fca6David Brown 118575e3711d82d0c98444f6c438437cad41d862fca6David Brown return; 1186211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown } 1187b154630235935e1aab2a41eff9ed794d40084a02David Brown 1188eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown if (action.equals(OtaUtils.ACTION_DISPLAY_ACTIVATION_SCREEN)) { 1189eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown // Bring up the in-call UI in the OTASP-specific "activate" state; 1190eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown // see OtaUtils.startInteractiveOtasp(). Note that at this point 1191eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown // the OTASP call has not been started yet; we won't actually make 1192eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown // the call until the user presses the "Activate" button. 1193eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown 1194eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown if (!TelephonyCapabilities.supportsOtasp(mPhone)) { 1195eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown throw new IllegalStateException( 1196eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown "Received ACTION_DISPLAY_ACTIVATION_SCREEN intent on non-OTASP-capable device: " 1197eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown + intent); 1198eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown } 1199eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown 1200eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown setInCallScreenMode(InCallScreenMode.OTA_NORMAL); 1201eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown if ((mApp.cdmaOtaProvisionData != null) 1202eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown && (!mApp.cdmaOtaProvisionData.isOtaCallIntentProcessed)) { 1203eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown mApp.cdmaOtaProvisionData.isOtaCallIntentProcessed = true; 1204eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown mApp.cdmaOtaScreenState.otaScreenState = 1205eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION; 1206eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown } 1207eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown return; 1208eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown } 1209eef9637aa8fd5463ca3f29e36953499f9f1468a2David Brown 1210211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // Various intent actions that should no longer come here directly: 1211211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown if (action.equals(OtaUtils.ACTION_PERFORM_CDMA_PROVISIONING)) { 1212211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // This intent is now handled by the InCallScreenShowActivation 1213211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // activity, which translates it into a call to 1214211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // OtaUtils.startInteractiveOtasp(). 1215211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown throw new IllegalStateException( 1216211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown "Unexpected ACTION_PERFORM_CDMA_PROVISIONING received by InCallScreen: " 1217211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown + intent); 1218211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown } else if (action.equals(Intent.ACTION_CALL) 1219211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown || action.equals(Intent.ACTION_CALL_EMERGENCY)) { 1220211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // ACTION_CALL* intents go to the OutgoingCallBroadcaster, which now 1221211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // translates them into CallController.placeCall() calls rather than 1222211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // launching the InCallScreen directly. 1223211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown throw new IllegalStateException("Unexpected CALL action received by InCallScreen: " 1224211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown + intent); 12255c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville } else if (action.equals(ACTION_UNDEFINED)) { 122675e3711d82d0c98444f6c438437cad41d862fca6David Brown // This action is only used for internal bookkeeping; we should 122775e3711d82d0c98444f6c438437cad41d862fca6David Brown // never actually get launched with it. 122875e3711d82d0c98444f6c438437cad41d862fca6David Brown Log.wtf(LOG_TAG, "internalResolveIntent: got launched with ACTION_UNDEFINED"); 122975e3711d82d0c98444f6c438437cad41d862fca6David Brown return; 1230b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 123175e3711d82d0c98444f6c438437cad41d862fca6David Brown Log.wtf(LOG_TAG, "internalResolveIntent: unexpected intent action: " + action); 1232b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // But continue the best we can (basically treating this case 1233b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // like ACTION_MAIN...) 123475e3711d82d0c98444f6c438437cad41d862fca6David Brown return; 1235b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1236b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1237b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1238b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void stopTimer() { 1239b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mCallCard != null) mCallCard.stopTimer(); 1240b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1241b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1242b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void initInCallScreen() { 1243796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("initInCallScreen()..."); 1244b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1245b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Have the WindowManager filter out touch events that are "too fat". 1246b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project getWindow().addFlags(WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES); 1247b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 12487b793e4c994f30b08abb065709ef26bf305f0a24David Brown // Initialize the CallCard. 12497b793e4c994f30b08abb065709ef26bf305f0a24David Brown mCallCard = (CallCard) findViewById(R.id.callCard); 1250796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log(" - mCallCard = " + mCallCard); 12518bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project mCallCard.setInCallScreenInstance(this); 1252b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 12534ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // Initialize the onscreen UI elements. 12544d910f9df60b820d3461995c1d85d0581041b531David Brown initInCallTouchUi(); 1255419426e206b3d8e76ebd4e3a19d8e5cddbdff658David Brown 125647e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown // Helper class to keep track of enabledness/state of UI controls 12578343169cc89621d46dce86449f5ee1ff5d3a4919John Wang mInCallControlState = new InCallControlState(this, mCM); 12587b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown 12597b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown // Helper class to run the "Manage conference" UI 1260b045b9344f339170d134cf814357361d96c349cfHung-ying Tyan mManageConferenceUtils = new ManageConferenceUtils(this, mCM); 1261dc855d9bbb450c65a3fb2a75e3cd995c975b32f3Martin Hibdon 12624ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // The DTMF Dialpad. 1263cbd492f15659eb79e53861643d4f2fcba0b6b0d3Daisuke Miyakawa ViewStub stub = (ViewStub) findViewById(R.id.dtmf_twelve_key_dialer_stub); 1264cbd492f15659eb79e53861643d4f2fcba0b6b0d3Daisuke Miyakawa mDialer = new DTMFTwelveKeyDialer(this, stub); 12654bf466a6d117a6fc4ddfd480f7db7606a29cb4ffMindy Pereira mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); 1266b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1267b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1268b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1269b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Returns true if the phone is "in use", meaning that at least one line 1270b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * is active (ie. off hook or ringing or dialing). Conversely, a return 1271b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * value of false means there's currently no phone activity at all. 1272b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1273b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private boolean phoneIsInUse() { 1274b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville return mCM.getState() != PhoneConstants.State.IDLE; 1275b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1276b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1277b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private boolean handleDialerKeyDown(int keyCode, KeyEvent event) { 1278796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("handleDialerKeyDown: keyCode " + keyCode + ", event " + event + "..."); 1279b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1280b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // As soon as the user starts typing valid dialable keys on the 1281b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // keyboard (presumably to type DTMF tones) we start passing the 1282b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // key events to the DTMFDialer's onDialerKeyDown. We do so 1283b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // only if the okToDialDTMFTones() conditions pass. 1284b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (okToDialDTMFTones()) { 1285b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return mDialer.onDialerKeyDown(event); 1286dfa83d531cdb88513f09e913424b7a16628b37d3David Brown 1287dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // TODO: If the dialpad isn't currently visible, maybe 1288dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // consider automatically bringing it up right now? 1289dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // (Just to make sure the user sees the digits widget...) 1290dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // But this probably isn't too critical since it's awkward to 1291dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // use the hard keyboard while in-call in the first place, 1292dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // especially now that the in-call UI is portrait-only... 1293b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1294b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1295b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return false; 1296b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1297b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1298e6345b794ec5a56f6379538c3ee953c23a2058baDavid Brown @Override 1299e6345b794ec5a56f6379538c3ee953c23a2058baDavid Brown public void onBackPressed() { 13004a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("onBackPressed()..."); 1301e6345b794ec5a56f6379538c3ee953c23a2058baDavid Brown 1302e6345b794ec5a56f6379538c3ee953c23a2058baDavid Brown // To consume this BACK press, the code here should just do 1303e6345b794ec5a56f6379538c3ee953c23a2058baDavid Brown // something and return. Otherwise, call super.onBackPressed() to 1304e6345b794ec5a56f6379538c3ee953c23a2058baDavid Brown // get the default implementation (which simply finishes the 1305e6345b794ec5a56f6379538c3ee953c23a2058baDavid Brown // current activity.) 1306b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1307c97fea097483c6e58c199e857b279ec92e64d8e3John Wang if (mCM.hasActiveRingingCall()) { 1308435662fc2982da833d7bd85aff342b41329d9c5bDavid Brown // The Back key, just like the Home key, is always disabled 1309435662fc2982da833d7bd85aff342b41329d9c5bDavid Brown // while an incoming call is ringing. (The user *must* either 1310435662fc2982da833d7bd85aff342b41329d9c5bDavid Brown // answer or reject the call before leaving the incoming-call 1311435662fc2982da833d7bd85aff342b41329d9c5bDavid Brown // screen.) 1312435662fc2982da833d7bd85aff342b41329d9c5bDavid Brown if (DBG) log("BACK key while ringing: ignored"); 1313435662fc2982da833d7bd85aff342b41329d9c5bDavid Brown 1314435662fc2982da833d7bd85aff342b41329d9c5bDavid Brown // And consume this event; *don't* call super.onBackPressed(). 1315435662fc2982da833d7bd85aff342b41329d9c5bDavid Brown return; 1316b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1317b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1318b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // BACK is also used to exit out of any "special modes" of the 1319b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // in-call UI: 1320b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1321b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mDialer.isOpened()) { 1322b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa closeDialpadInternal(true); // do the "closing" animation 1323e6345b794ec5a56f6379538c3ee953c23a2058baDavid Brown return; 1324b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1325b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 132675e3711d82d0c98444f6c438437cad41d862fca6David Brown if (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.MANAGE_CONFERENCE) { 1327b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Hide the Manage Conference panel, return to NORMAL mode. 1328b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project setInCallScreenMode(InCallScreenMode.NORMAL); 132996af4b62835c1d0d023d285b896226386621e283David Brown requestUpdateScreen(); 1330e6345b794ec5a56f6379538c3ee953c23a2058baDavid Brown return; 1331b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1332b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1333e6345b794ec5a56f6379538c3ee953c23a2058baDavid Brown // Nothing special to do. Fall back to the default behavior. 1334e6345b794ec5a56f6379538c3ee953c23a2058baDavid Brown super.onBackPressed(); 1335b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1336b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1337b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1338b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Handles the green CALL key while in-call. 1339b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * @return true if we consumed the event. 1340b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1341b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private boolean handleCallKey() { 1342b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // The green CALL button means either "Answer", "Unhold", or 1343b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "Swap calls", or can be a no-op, depending on the current state 1344b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // of the Phone. 1345b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1346c97fea097483c6e58c199e857b279ec92e64d8e3John Wang final boolean hasRingingCall = mCM.hasActiveRingingCall(); 1347c97fea097483c6e58c199e857b279ec92e64d8e3John Wang final boolean hasActiveCall = mCM.hasActiveFgCall(); 1348c97fea097483c6e58c199e857b279ec92e64d8e3John Wang final boolean hasHoldingCall = mCM.hasActiveBgCall(); 1349b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 135079b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink int phoneType = mPhone.getPhoneType(); 1351b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { 1352a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // The green CALL button means either "Answer", "Swap calls/On Hold", or 1353a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // "Add to 3WC", depending on the current state of the Phone. 13540fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 13550fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville CdmaPhoneCallState.PhoneCallState currCallState = 135675e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.cdmaPhoneCallState.getCurrentCallState(); 1357a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville if (hasRingingCall) { 13580fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville //Scenario 1: Accepting the First Incoming and Call Waiting call 13590fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (DBG) log("answerCall: First Incoming and Call Waiting scenario"); 1360b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project internalAnswerCall(); // Automatically holds the current active call, 1361b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if there is one 13620fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } else if ((currCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) 13630fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville && (hasActiveCall)) { 13640fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville //Scenario 2: Merging 3Way calls 13650fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (DBG) log("answerCall: Merge 3-way call scenario"); 13660fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Merge calls 1367b045b9344f339170d134cf814357361d96c349cfHung-ying Tyan PhoneUtils.mergeCalls(mCM); 13680fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } else if (currCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) { 13690fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville //Scenario 3: Switching between two Call waiting calls or drop the latest 13700fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // connection if in a 3Way merge scenario 13710fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (DBG) log("answerCall: Switch btwn 2 calls scenario"); 1372c9d9ed30aa547b79b81adc13a4d148a003b6ee62w internalSwapCalls(); 1373b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1374b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM) 1375b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) { 1376a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville if (hasRingingCall) { 1377a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // If an incoming call is ringing, the CALL button is actually 1378a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // handled by the PhoneWindowManager. (We do this to make 1379a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // sure that we'll respond to the key even if the InCallScreen 1380a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // hasn't come to the foreground yet.) 1381a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // 1382a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // We'd only ever get here in the extremely rare case that the 1383a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // incoming call started ringing *after* 1384a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // PhoneWindowManager.interceptKeyTq() but before the event 1385a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // got here, or else if the PhoneWindowManager had some 1386a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // problem connecting to the ITelephony service. 1387a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville Log.w(LOG_TAG, "handleCallKey: incoming call is ringing!" 1388a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville + " (PhoneWindowManager should have handled this key.)"); 1389a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // But go ahead and handle the key as normal, since the 1390a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // PhoneWindowManager presumably did NOT handle it: 1391a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville 1392a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // There's an incoming ringing call: CALL means "Answer". 13934d910f9df60b820d3461995c1d85d0581041b531David Brown internalAnswerCall(); 1394a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville } else if (hasActiveCall && hasHoldingCall) { 1395a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // Two lines are in use: CALL means "Swap calls". 1396a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville if (DBG) log("handleCallKey: both lines in use ==> swap calls."); 1397a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville internalSwapCalls(); 1398a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville } else if (hasHoldingCall) { 1399a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // There's only one line in use, AND it's on hold. 1400a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // In this case CALL is a shortcut for "unhold". 1401a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville if (DBG) log("handleCallKey: call on hold ==> unhold."); 140275e3711d82d0c98444f6c438437cad41d862fca6David Brown PhoneUtils.switchHoldingAndActive( 140375e3711d82d0c98444f6c438437cad41d862fca6David Brown mCM.getFirstActiveBgCall()); // Really means "unhold" in this state 1404a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville } else { 1405a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // The most common case: there's only one line in use, and 1406a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // it's an active call (i.e. it's not on hold.) 1407a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // In this case CALL is a no-op. 1408a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // (This used to be a shortcut for "add call", but that was a 1409a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // bad idea because "Add call" is so infrequently-used, and 1410a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // because the user experience is pretty confusing if you 1411a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // inadvertently trigger it.) 1412a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville if (VDBG) log("handleCallKey: call in foregound ==> ignoring."); 1413a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville // But note we still consume this key event; see below. 1414a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville } 141579b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } else { 141679b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink throw new IllegalStateException("Unexpected phone type: " + phoneType); 1417b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1418b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1419b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // We *always* consume the CALL key, since the system-wide default 1420b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // action ("go to the in-call screen") is useless here. 1421b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 1422b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1423b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1424b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean isKeyEventAcceptableDTMF (KeyEvent event) { 1425b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return (mDialer != null && mDialer.isKeyEventAcceptable(event)); 1426b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1427b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1428b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1429b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Overriden to track relevant focus changes. 1430b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1431b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * If a key is down and some time later the focus changes, we may 1432b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * NOT recieve the keyup event; logically the keyup event has not 1433b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * occured in this window. This issue is fixed by treating a focus 1434b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * changed event as an interruption to the keydown, making sure 1435b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * that any code that needs to be run in onKeyUp is ALSO run here. 1436b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1437b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 1438b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onWindowFocusChanged(boolean hasFocus) { 1439b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the dtmf tones should no longer be played 1440796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("onWindowFocusChanged(" + hasFocus + ")..."); 1441b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (!hasFocus && mDialer != null) { 1442796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- onWindowFocusChanged: faking onDialerKeyUp()..."); 1443b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDialer.onDialerKeyUp(null); 1444b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1445b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1446b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1447b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 1448b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public boolean onKeyUp(int keyCode, KeyEvent event) { 1449b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if (DBG) log("onKeyUp(keycode " + keyCode + ")..."); 1450b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1451b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // push input to the dialer. 1452b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if ((mDialer != null) && (mDialer.onDialerKeyUp(event))){ 1453b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 1454b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (keyCode == KeyEvent.KEYCODE_CALL) { 1455b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Always consume CALL to be sure the PhoneWindow won't do anything with it 1456b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 1457b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1458b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return super.onKeyUp(keyCode, event); 1459b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1460b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1461b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 1462b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public boolean onKeyDown(int keyCode, KeyEvent event) { 1463b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if (DBG) log("onKeyDown(keycode " + keyCode + ")..."); 1464b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1465b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (keyCode) { 1466b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case KeyEvent.KEYCODE_CALL: 1467b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean handled = handleCallKey(); 1468b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (!handled) { 1469b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Log.w(LOG_TAG, "InCallScreen should always handle KEYCODE_CALL in onKeyDown"); 1470b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1471b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Always consume CALL to be sure the PhoneWindow won't do anything with it 1472b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 1473b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1474b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Note there's no KeyEvent.KEYCODE_ENDCALL case here. 1475b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // The standard system-wide handling of the ENDCALL key 1476b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (see PhoneWindowManager's handling of KEYCODE_ENDCALL) 1477b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // already implements exactly what the UI spec wants, 1478b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // namely (1) "hang up" if there's a current active call, 1479b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // or (2) "don't answer" if there's a current ringing call. 1480b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1481b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case KeyEvent.KEYCODE_CAMERA: 1482b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Disable the CAMERA button while in-call since it's too 1483b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // easy to press accidentally. 1484b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 1485b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1486b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case KeyEvent.KEYCODE_VOLUME_UP: 1487b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case KeyEvent.KEYCODE_VOLUME_DOWN: 1488b4a07a1a5b185a91ac8bea62519d3295763ece9fJeff Brown case KeyEvent.KEYCODE_VOLUME_MUTE: 1489b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville if (mCM.getState() == PhoneConstants.State.RINGING) { 1490b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // If an incoming call is ringing, the VOLUME buttons are 1491b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // actually handled by the PhoneWindowManager. (We do 1492b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // this to make sure that we'll respond to them even if 1493b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the InCallScreen hasn't come to the foreground yet.) 1494b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 1495b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // We'd only ever get here in the extremely rare case that the 1496b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // incoming call started ringing *after* 1497b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // PhoneWindowManager.interceptKeyTq() but before the event 1498b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // got here, or else if the PhoneWindowManager had some 1499b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // problem connecting to the ITelephony service. 1500b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Log.w(LOG_TAG, "VOLUME key: incoming call is ringing!" 1501b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project + " (PhoneWindowManager should have handled this key.)"); 1502b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // But go ahead and handle the key as normal, since the 1503b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // PhoneWindowManager presumably did NOT handle it: 15049e25b785cc7edae682144536f58080edb3a374e4David Brown internalSilenceRinger(); 1505b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1506b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // As long as an incoming call is ringing, we always 1507b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // consume the VOLUME keys. 1508b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 1509b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1510b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1511b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1512b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case KeyEvent.KEYCODE_MUTE: 1513a50e10e2efadac960987eaadc0938c6f92d3ee90John Wang onMuteClick(); 1514b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 1515b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1516796c70c99bc39295bf685061056f06ab8949c742David Brown // Various testing/debugging features, enabled ONLY when VDBG == true. 1517b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case KeyEvent.KEYCODE_SLASH: 1518796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) { 1519b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project log("----------- InCallScreen View dump --------------"); 1520b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Dump starting from the top-level view of the entire activity: 1521b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Window w = this.getWindow(); 1522b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project View decorView = w.getDecorView(); 1523b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project decorView.debug(); 1524b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 1525b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1526b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1527b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case KeyEvent.KEYCODE_EQUALS: 1528796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) { 1529b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project log("----------- InCallScreen call state dump --------------"); 1530b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project PhoneUtils.dumpCallState(mPhone); 15318343169cc89621d46dce86449f5ee1ff5d3a4919John Wang PhoneUtils.dumpCallManager(); 1532b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 1533b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1534b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1535b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case KeyEvent.KEYCODE_GRAVE: 1536796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) { 1537b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Placeholder for other misc temp testing 1538b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project log("------------ Temp testing -----------------"); 1539b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 1540b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1541b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1542b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1543b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1544b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (event.getRepeatCount() == 0 && handleDialerKeyDown(keyCode, event)) { 1545b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 1546b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1547b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1548b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return super.onKeyDown(keyCode, event); 1549b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1550b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1551b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1552b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Handle a failure notification for a supplementary service 1553b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * (i.e. conference, switch, separate, transfer, etc.). 1554b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1555b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project void onSuppServiceFailed(AsyncResult r) { 1556b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Phone.SuppService service = (Phone.SuppService) r.result; 1557b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("onSuppServiceFailed: " + service); 1558b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1559b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int errorMessageResId; 1560b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (service) { 1561b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case SWITCH: 1562b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Attempt to switch foreground and background/incoming calls failed 1563b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // ("Failed to switch calls") 1564b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project errorMessageResId = R.string.incall_error_supp_service_switch; 1565b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1566b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1567b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case SEPARATE: 1568b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Attempt to separate a call from a conference call 1569b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // failed ("Failed to separate out call") 1570b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project errorMessageResId = R.string.incall_error_supp_service_separate; 1571b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1572b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1573b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case TRANSFER: 1574b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Attempt to connect foreground and background calls to 1575b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // each other (and hanging up user's line) failed ("Call 1576b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // transfer failed") 1577b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project errorMessageResId = R.string.incall_error_supp_service_transfer; 1578b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1579b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1580b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case CONFERENCE: 1581b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Attempt to add a call to conference call failed 1582b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // ("Conference call failed") 1583b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project errorMessageResId = R.string.incall_error_supp_service_conference; 1584b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1585b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1586b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case REJECT: 1587b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Attempt to reject an incoming call failed 1588b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // ("Call rejection failed") 1589b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project errorMessageResId = R.string.incall_error_supp_service_reject; 1590b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1591b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1592b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case HANGUP: 1593b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Attempt to release a call failed ("Failed to release call(s)") 1594b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project errorMessageResId = R.string.incall_error_supp_service_hangup; 1595b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1596b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1597b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case UNKNOWN: 1598b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project default: 1599b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Attempt to use a service we don't recognize or support 1600b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // ("Unsupported service" or "Selected service failed") 1601b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project errorMessageResId = R.string.incall_error_supp_service_unknown; 1602b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1603b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1604b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1605b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // mSuppServiceFailureDialog is a generic dialog used for any 1606b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // supp service failure, and there's only ever have one 1607b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // instance at a time. So just in case a previous dialog is 1608b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // still around, dismiss it. 1609b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mSuppServiceFailureDialog != null) { 1610b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- DISMISSING mSuppServiceFailureDialog."); 1611b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mSuppServiceFailureDialog.dismiss(); // It's safe to dismiss() a dialog 1612b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // that's already dismissed. 1613b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mSuppServiceFailureDialog = null; 1614b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1615b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1616b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mSuppServiceFailureDialog = new AlertDialog.Builder(this) 1617b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project .setMessage(errorMessageResId) 1618b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project .setPositiveButton(R.string.ok, null) 1619b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project .create(); 1620b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mSuppServiceFailureDialog.getWindow().addFlags( 1621b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project WindowManager.LayoutParams.FLAG_BLUR_BEHIND); 1622b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mSuppServiceFailureDialog.show(); 1623b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1624b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1625b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1626b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Something has changed in the phone's state. Update the UI. 1627b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1628b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void onPhoneStateChanged(AsyncResult r) { 1629b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville PhoneConstants.State state = mCM.getState(); 1630ee6be3c53945e69acce6c2c852ce1ebf69015c9dDavid Brown if (DBG) log("onPhoneStateChanged: current state = " + state); 1631b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1632b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // There's nothing to do here if we're not the foreground activity. 1633b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (When we *do* eventually come to the foreground, we'll do a 1634b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // full update then.) 1635b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (!mIsForegroundActivity) { 16364a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("onPhoneStateChanged: Activity not in foreground! Bailing out..."); 1637b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 1638b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1639b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 164037bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa updateExpandedViewState(); 164137bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa 164296af4b62835c1d0d023d285b896226386621e283David Brown // Update the onscreen UI. 164396af4b62835c1d0d023d285b896226386621e283David Brown // We use requestUpdateScreen() here (which posts a handler message) 164496af4b62835c1d0d023d285b896226386621e283David Brown // instead of calling updateScreen() directly, which allows us to avoid 164596af4b62835c1d0d023d285b896226386621e283David Brown // unnecessary work if multiple onPhoneStateChanged() events come in all 164696af4b62835c1d0d023d285b896226386621e283David Brown // at the same time. 164796af4b62835c1d0d023d285b896226386621e283David Brown 164896af4b62835c1d0d023d285b896226386621e283David Brown requestUpdateScreen(); 1649b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1650b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Make sure we update the poke lock and wake lock when certain 1651b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // phone state changes occur. 165275e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.updateWakeState(); 1653b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1654b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1655b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1656b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the UI after a phone connection is disconnected, as follows: 1657b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1658b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * - If this was a missed or rejected incoming call, and no other 1659b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * calls are active, dismiss the in-call UI immediately. (The 1660b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * CallNotifier will still create a "missed call" notification if 1661b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * necessary.) 1662b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1663b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * - With any other disconnect cause, if the phone is now totally 1664b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * idle, display the "Call ended" state for a couple of seconds. 1665b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1666b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * - Or, if the phone is still in use, stay on the in-call screen 1667b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * (and update the UI to reflect the current state of the Phone.) 1668b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1669b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * @param r r.result contains the connection that just ended 1670b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1671b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void onDisconnect(AsyncResult r) { 1672b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection c = (Connection) r.result; 1673b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection.DisconnectCause cause = c.getDisconnectCause(); 16746522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa if (DBG) log("onDisconnect: connection '" + c + "', cause = " + cause 16756522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa + ", showing screen: " + mApp.isShowingCallScreen()); 1676b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1677cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai boolean currentlyIdle = !phoneIsInUse(); 1678b43bcb438fb200f6653d8115583761c5c9b33fe4Kuanting Zhu int autoretrySetting = AUTO_RETRY_OFF; 1679b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville boolean phoneIsCdma = (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA); 168079b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneIsCdma) { 1681cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai // Get the Auto-retry setting only if Phone State is IDLE, 1682cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai // else let it stay as AUTO_RETRY_OFF 1683cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai if (currentlyIdle) { 16843979da597ee503082a0b94ef8823e8533f972f5aJeff Sharkey autoretrySetting = android.provider.Settings.Global.getInt(mPhone.getContext(). 16853979da597ee503082a0b94ef8823e8533f972f5aJeff Sharkey getContentResolver(), android.provider.Settings.Global.CALL_AUTO_RETRY, 0); 1686cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai } 16873800ac871d6548790ac6119bb68b9be0640af261David Krause } 16883800ac871d6548790ac6119bb68b9be0640af261David Krause 1689af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville // for OTA Call, only if in OTA NORMAL mode, handle OTA END scenario 169075e3711d82d0c98444f6c438437cad41d862fca6David Brown if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL) 169175e3711d82d0c98444f6c438437cad41d862fca6David Brown && ((mApp.cdmaOtaProvisionData != null) 169275e3711d82d0c98444f6c438437cad41d862fca6David Brown && (!mApp.cdmaOtaProvisionData.inOtaSpcState))) { 1693af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville setInCallScreenMode(InCallScreenMode.OTA_ENDED); 1694af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville updateScreen(); 1695af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville return; 169675e3711d82d0c98444f6c438437cad41d862fca6David Brown } else if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED) 169775e3711d82d0c98444f6c438437cad41d862fca6David Brown || ((mApp.cdmaOtaProvisionData != null) 169875e3711d82d0c98444f6c438437cad41d862fca6David Brown && mApp.cdmaOtaProvisionData.inOtaSpcState)) { 1699af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville if (DBG) log("onDisconnect: OTA Call end already handled"); 1700af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville return; 1701af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 1702af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville 1703b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Any time a call disconnects, clear out the "history" of DTMF 1704b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // digits you typed (to make sure it doesn't persist from one call 1705b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // to the next.) 1706b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDialer.clearDigits(); 1707b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1708b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Under certain call disconnected states, we want to alert the user 1709b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // with a dialog instead of going through the normal disconnect 1710b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // routine. 1711b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (cause == Connection.DisconnectCause.CALL_BARRED) { 1712b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project showGenericErrorDialog(R.string.callFailed_cb_enabled, false); 1713b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 1714b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (cause == Connection.DisconnectCause.FDN_BLOCKED) { 1715b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project showGenericErrorDialog(R.string.callFailed_fdn_only, false); 1716b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 1717278d5ab9339bf91a6d79fd9422265b4c0f7e037ePeng Zhu } else if (cause == Connection.DisconnectCause.CS_RESTRICTED) { 1718278d5ab9339bf91a6d79fd9422265b4c0f7e037ePeng Zhu showGenericErrorDialog(R.string.callFailed_dsac_restricted, false); 1719278d5ab9339bf91a6d79fd9422265b4c0f7e037ePeng Zhu return; 1720278d5ab9339bf91a6d79fd9422265b4c0f7e037ePeng Zhu } else if (cause == Connection.DisconnectCause.CS_RESTRICTED_EMERGENCY) { 1721278d5ab9339bf91a6d79fd9422265b4c0f7e037ePeng Zhu showGenericErrorDialog(R.string.callFailed_dsac_restricted_emergency, false); 1722278d5ab9339bf91a6d79fd9422265b4c0f7e037ePeng Zhu return; 1723278d5ab9339bf91a6d79fd9422265b4c0f7e037ePeng Zhu } else if (cause == Connection.DisconnectCause.CS_RESTRICTED_NORMAL) { 1724278d5ab9339bf91a6d79fd9422265b4c0f7e037ePeng Zhu showGenericErrorDialog(R.string.callFailed_dsac_restricted_normal, false); 1725278d5ab9339bf91a6d79fd9422265b4c0f7e037ePeng Zhu return; 17263800ac871d6548790ac6119bb68b9be0640af261David Krause } 17273800ac871d6548790ac6119bb68b9be0640af261David Krause 172879b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneIsCdma) { 172975e3711d82d0c98444f6c438437cad41d862fca6David Brown Call.State callState = mApp.notifier.getPreviousCdmaCallState(); 17303800ac871d6548790ac6119bb68b9be0640af261David Krause if ((callState == Call.State.ACTIVE) 17317b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown && (cause != Connection.DisconnectCause.INCOMING_MISSED) 17323800ac871d6548790ac6119bb68b9be0640af261David Krause && (cause != Connection.DisconnectCause.NORMAL) 17333800ac871d6548790ac6119bb68b9be0640af261David Krause && (cause != Connection.DisconnectCause.LOCAL) 17343800ac871d6548790ac6119bb68b9be0640af261David Krause && (cause != Connection.DisconnectCause.INCOMING_REJECTED)) { 17351066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown showCallLostDialog(); 17363800ac871d6548790ac6119bb68b9be0640af261David Krause } else if ((callState == Call.State.DIALING || callState == Call.State.ALERTING) 17373800ac871d6548790ac6119bb68b9be0640af261David Krause && (cause != Connection.DisconnectCause.INCOMING_MISSED) 17383800ac871d6548790ac6119bb68b9be0640af261David Krause && (cause != Connection.DisconnectCause.NORMAL) 17393800ac871d6548790ac6119bb68b9be0640af261David Krause && (cause != Connection.DisconnectCause.LOCAL) 17403800ac871d6548790ac6119bb68b9be0640af261David Krause && (cause != Connection.DisconnectCause.INCOMING_REJECTED)) { 1741b43bcb438fb200f6653d8115583761c5c9b33fe4Kuanting Zhu 174275e3711d82d0c98444f6c438437cad41d862fca6David Brown if (mApp.inCallUiState.needToShowCallLostDialog) { 174375e3711d82d0c98444f6c438437cad41d862fca6David Brown // Show the dialog now since the call that just failed was a retry. 174475e3711d82d0c98444f6c438437cad41d862fca6David Brown showCallLostDialog(); 174575e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.inCallUiState.needToShowCallLostDialog = false; 174675e3711d82d0c98444f6c438437cad41d862fca6David Brown } else { 174775e3711d82d0c98444f6c438437cad41d862fca6David Brown if (autoretrySetting == AUTO_RETRY_OFF) { 174875e3711d82d0c98444f6c438437cad41d862fca6David Brown // Show the dialog for failed call if Auto Retry is OFF in Settings. 1749b43bcb438fb200f6653d8115583761c5c9b33fe4Kuanting Zhu showCallLostDialog(); 175075e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.inCallUiState.needToShowCallLostDialog = false; 1751b43bcb438fb200f6653d8115583761c5c9b33fe4Kuanting Zhu } else { 175275e3711d82d0c98444f6c438437cad41d862fca6David Brown // Set the needToShowCallLostDialog flag now, so we'll know to show 175375e3711d82d0c98444f6c438437cad41d862fca6David Brown // the dialog if *this* call fails. 175475e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.inCallUiState.needToShowCallLostDialog = true; 17553800ac871d6548790ac6119bb68b9be0640af261David Krause } 175675e3711d82d0c98444f6c438437cad41d862fca6David Brown } 17573800ac871d6548790ac6119bb68b9be0640af261David Krause } 1758b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1759b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1760b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Explicitly clean up up any DISCONNECTED connections 1761b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // in a conference call. 1762b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // [Background: Even after a connection gets disconnected, its 1763b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Connection object still stays around for a few seconds, in the 1764b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // DISCONNECTED state. With regular calls, this state drives the 1765b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "call ended" UI. But when a single person disconnects from a 1766b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // conference call there's no "call ended" state at all; in that 1767b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // case we blow away any DISCONNECTED connections right now to make sure 1768b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the UI updates instantly to reflect the current state.] 17696522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa final Call call = c.getCall(); 1770b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (call != null) { 1771b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // We only care about situation of a single caller 1772b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // disconnecting from a conference call. In that case, the 1773b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // call will have more than one Connection (including the one 1774b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // that just disconnected, which will be in the DISCONNECTED 1775b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // state) *and* at least one ACTIVE connection. (If the Call 1776b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // has *no* ACTIVE connections, that means that the entire 1777b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // conference call just ended, so we *do* want to show the 1778b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "Call ended" state.) 1779b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project List<Connection> connections = call.getConnections(); 1780b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (connections != null && connections.size() > 1) { 1781b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project for (Connection conn : connections) { 1782b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (conn.getState() == Call.State.ACTIVE) { 1783b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // This call still has at least one ACTIVE connection! 1784b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // So blow away any DISCONNECTED connections 1785b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (including, presumably, the one that just 1786b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // disconnected from this conference call.) 1787b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1788b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // We also force the wake state to refresh, just in 1789b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // case the disconnected connections are removed 1790b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // before the phone state change. 1791796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- Still-active conf call; clearing DISCONNECTED..."); 179275e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.updateWakeState(); 17938343169cc89621d46dce86449f5ee1ff5d3a4919John Wang mCM.clearDisconnected(); // This happens synchronously. 1794b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1795b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1796b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1797b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1798b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1799b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1800b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Note: see CallNotifier.onDisconnect() for some other behavior 1801b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // that might be triggered by a disconnect event, like playing the 1802b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // busy/congestion tone. 1803b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1804d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // Stash away some info about the call that just disconnected. 1805d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // (This might affect what happens after we exit the InCallScreen; see 1806d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // delayedCleanupAfterDisconnect().) 1807d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // TODO: rather than stashing this away now and then reading it in 1808d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // delayedCleanupAfterDisconnect(), it would be cleaner to just pass 1809d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // this as an argument to delayedCleanupAfterDisconnect() (if we call 1810d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // it directly) or else pass it as a Message argument when we post the 1811d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // DELAYED_CLEANUP_AFTER_DISCONNECT message. 1812d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown mLastDisconnectCause = cause; 1813d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown 1814b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // We bail out immediately (and *don't* display the "call ended" 18153426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // state at all) if this was an incoming call. 1816b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean bailOutImmediately = 1817b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ((cause == Connection.DisconnectCause.INCOMING_MISSED) 18183426afaf85d33d454fad8d341a1a895fd7e21c10David Brown || (cause == Connection.DisconnectCause.INCOMING_REJECTED)) 1819b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project && currentlyIdle; 1820b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1821552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa boolean showingQuickResponseDialog = 1822552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa mRespondViaSmsManager != null && mRespondViaSmsManager.isShowingPopup(); 1823552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa 18243426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // Note: we also do some special handling for the case when a call 18253426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // disconnects with cause==OUT_OF_SERVICE while making an 18263426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // emergency call from airplane mode. That's handled by 18273426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // EmergencyCallHelper.onDisconnect(). 18283426afaf85d33d454fad8d341a1a895fd7e21c10David Brown 1829552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa if (bailOutImmediately && showingQuickResponseDialog) { 1830552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa if (DBG) log("- onDisconnect: Respond-via-SMS dialog is still being displayed..."); 1831fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown 1832552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa // Do *not* exit the in-call UI yet! 1833552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa // If the call was an incoming call that was missed *and* the user is using 1834552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa // quick response screen, we keep showing the screen for a moment, assuming the 1835552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa // user wants to reply the call anyway. 1836552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa // 1837552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa // For this case, we will exit the screen when: 1838552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa // - the message is sent (RespondViaSmsManager) 1839552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa // - the message is canceled (RespondViaSmsManager), or 1840552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa // - when the whole in-call UI becomes background (onPause()) 1841552eaf42c27575b408ed3087f3dbc7a33680bd56Daisuke Miyakawa } else if (bailOutImmediately) { 18423426afaf85d33d454fad8d341a1a895fd7e21c10David Brown if (DBG) log("- onDisconnect: bailOutImmediately..."); 184302d1c632adde606031c1fe6ea0e3be1e288fd6c6David Brown 1844b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Exit the in-call UI! 1845b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (This is basically the same "delayed cleanup" we do below, 1846b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // just with zero delay. Since the Phone is currently idle, 18474a5a966f0d43e04d336be1b94182346399a931f6Wink Saville // this call is guaranteed to immediately finish this activity.) 1848b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project delayedCleanupAfterDisconnect(); 1849b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 18503426afaf85d33d454fad8d341a1a895fd7e21c10David Brown if (DBG) log("- onDisconnect: delayed bailout..."); 1851b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Stay on the in-call screen for now. (Either the phone is 1852b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // still in use, or the phone is idle but we want to display 1853b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the "call ended" state for a couple of seconds.) 1854b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 185596af4b62835c1d0d023d285b896226386621e283David Brown // Switch to the special "Call ended" state when the phone is idle 1856b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // but there's still a call in the DISCONNECTED state: 1857b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (currentlyIdle 1858c97fea097483c6e58c199e857b279ec92e64d8e3John Wang && (mCM.hasDisconnectedFgCall() || mCM.hasDisconnectedBgCall())) { 18593426afaf85d33d454fad8d341a1a895fd7e21c10David Brown if (DBG) log("- onDisconnect: switching to 'Call ended' state..."); 1860b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project setInCallScreenMode(InCallScreenMode.CALL_ENDED); 1861b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1862b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 186396af4b62835c1d0d023d285b896226386621e283David Brown // Force a UI update in case we need to display anything 186496af4b62835c1d0d023d285b896226386621e283David Brown // special based on this connection's DisconnectCause 186596af4b62835c1d0d023d285b896226386621e283David Brown // (see CallCard.getCallFailedString()). 186696af4b62835c1d0d023d285b896226386621e283David Brown updateScreen(); 186796af4b62835c1d0d023d285b896226386621e283David Brown 1868b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Some other misc cleanup that we do if the call that just 1869b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // disconnected was the foreground call. 1870c97fea097483c6e58c199e857b279ec92e64d8e3John Wang final boolean hasActiveCall = mCM.hasActiveFgCall(); 1871b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (!hasActiveCall) { 18723426afaf85d33d454fad8d341a1a895fd7e21c10David Brown if (DBG) log("- onDisconnect: cleaning up after FG call disconnect..."); 1873b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1874b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Dismiss any dialogs which are only meaningful for an 1875b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // active call *and* which become moot if the call ends. 1876b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mWaitPromptDialog != null) { 1877796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- DISMISSING mWaitPromptDialog."); 1878b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWaitPromptDialog.dismiss(); // safe even if already dismissed 1879b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWaitPromptDialog = null; 1880b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1881b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mWildPromptDialog != null) { 1882796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- DISMISSING mWildPromptDialog."); 1883b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWildPromptDialog.dismiss(); // safe even if already dismissed 1884b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWildPromptDialog = null; 1885b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 188628dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal if (mPausePromptDialog != null) { 188728dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal if (DBG) log("- DISMISSING mPausePromptDialog."); 188828dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal mPausePromptDialog.dismiss(); // safe even if already dismissed 188928dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal mPausePromptDialog = null; 189028dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal } 1891b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1892b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1893b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Updating the screen wake state is done in onPhoneStateChanged(). 1894b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1895cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai 1896cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai // CDMA: We only clean up if the Phone state is IDLE as we might receive an 1897cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai // onDisconnect for a Call Collision case (rare but possible). 1898cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai // For Call collision cases i.e. when the user makes an out going call 1899cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai // and at the same time receives an Incoming Call, the Incoming Call is given 1900cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai // higher preference. At this time framework sends a disconnect for the Out going 1901cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai // call connection hence we should *not* bring down the InCallScreen as the Phone 1902cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai // State would be RINGING 1903b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 1904f717662ca0f2a8aeb7f1740b000a458253afc97cPeng Zhu if (!currentlyIdle) { 1905f717662ca0f2a8aeb7f1740b000a458253afc97cPeng Zhu // Clean up any connections in the DISCONNECTED state. 1906f717662ca0f2a8aeb7f1740b000a458253afc97cPeng Zhu // This is necessary cause in CallCollision the foreground call might have 1907f717662ca0f2a8aeb7f1740b000a458253afc97cPeng Zhu // connections in DISCONNECTED state which needs to be cleared. 19088343169cc89621d46dce86449f5ee1ff5d3a4919John Wang mCM.clearDisconnected(); 1909f717662ca0f2a8aeb7f1740b000a458253afc97cPeng Zhu 1910f717662ca0f2a8aeb7f1740b000a458253afc97cPeng Zhu // The phone is still in use. Stay here in this activity. 1911f717662ca0f2a8aeb7f1740b000a458253afc97cPeng Zhu // But we don't need to keep the screen on. 1912f717662ca0f2a8aeb7f1740b000a458253afc97cPeng Zhu if (DBG) log("onDisconnect: Call Collision case - staying on InCallScreen."); 1913f717662ca0f2a8aeb7f1740b000a458253afc97cPeng Zhu if (DBG) PhoneUtils.dumpCallState(mPhone); 1914f717662ca0f2a8aeb7f1740b000a458253afc97cPeng Zhu return; 1915f717662ca0f2a8aeb7f1740b000a458253afc97cPeng Zhu } 1916cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai } 1917cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai 19186522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // This is onDisconnect() request from the last phone call; no available call anymore. 19196522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // 19206522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // When the in-call UI is in background *because* the screen is turned off (unlike the 19216522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // other case where the other activity is being shown), we wake up the screen and 19226522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // show "DISCONNECTED" state once, with appropriate elapsed time. After showing that 19236522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // we *must* bail out of the screen again, showing screen lock if needed. 19246522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // 19256522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // See also comments for isForegroundActivityForProximity() 19266522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // 19276522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // TODO: Consider moving this to CallNotifier. This code assumes the InCallScreen 19286522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // never gets destroyed. For this exact case, it works (since InCallScreen won't be 19296522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // destroyed), while technically this isn't right; Activity may be destroyed when 19306522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // in background. 19316522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa if (currentlyIdle && !isForegroundActivity() && isForegroundActivityForProximity()) { 19326522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa log("Force waking up the screen to let users see \"disconnected\" state"); 19336522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa if (call != null) { 19346522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa mCallCard.updateElapsedTimeWidget(call); 19356522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa } 19366522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // This variable will be kept true until the next InCallScreen#onPause(), which 19376522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // forcibly turns it off regardless of the situation (for avoiding unnecessary 19386522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // confusion around this special case). 19396522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa mApp.inCallUiState.showAlreadyDisconnectedState = true; 19406522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa 19416522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // Finally request wake-up.. 19426522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa mApp.wakeUpScreen(); 19436522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa 19446522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // InCallScreen#onResume() will set DELAYED_CLEANUP_AFTER_DISCONNECT message, 19456522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa // so skip the following section. 19466522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa return; 19476522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa } 19486522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa 1949b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Finally, arrange for delayedCleanupAfterDisconnect() to get 1950b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // called after a short interval (during which we display the 1951b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "call ended" state.) At that point, if the 19524a5a966f0d43e04d336be1b94182346399a931f6Wink Saville // Phone is idle, we'll finish out of this activity. 19536ca271d15ab7c3196854ada94fd6d90ebc644731Daisuke Miyakawa final int callEndedDisplayDelay; 19546ca271d15ab7c3196854ada94fd6d90ebc644731Daisuke Miyakawa switch (cause) { 1955a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa // When the local user hanged up the ongoing call, it is ok to dismiss the screen 1956a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa // soon. In other cases, we show the "hung up" screen longer. 1957a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa // 1958a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa // - For expected reasons we will use CALL_ENDED_LONG_DELAY. 1959a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa // -- when the peer hanged up the call 1960a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa // -- when the local user rejects the incoming call during the other ongoing call 1961a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa // (TODO: there may be other cases which should be in this category) 1962a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa // 1963a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa // - For other unexpected reasons, we will use CALL_ENDED_EXTRA_LONG_DELAY, 1964a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa // assuming the local user wants to confirm the disconnect reason. 1965a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa case LOCAL: 1966a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa callEndedDisplayDelay = CALL_ENDED_SHORT_DELAY; 1967a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa break; 1968a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa case NORMAL: 1969a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa case INCOMING_REJECTED: 1970a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa callEndedDisplayDelay = CALL_ENDED_LONG_DELAY; 1971a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa break; 1972a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa default: 1973a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa callEndedDisplayDelay = CALL_ENDED_EXTRA_LONG_DELAY; 1974a4ba5419c02a0a7bd14a3abe50d3e00bb5ccbb55Daisuke Miyakawa break; 19756ca271d15ab7c3196854ada94fd6d90ebc644731Daisuke Miyakawa } 1976b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mHandler.removeMessages(DELAYED_CLEANUP_AFTER_DISCONNECT); 1977b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mHandler.sendEmptyMessageDelayed(DELAYED_CLEANUP_AFTER_DISCONNECT, 19786ca271d15ab7c3196854ada94fd6d90ebc644731Daisuke Miyakawa callEndedDisplayDelay); 1979b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 19800fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 19810fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Remove 3way timer (only meaningful for CDMA) 198275e3711d82d0c98444f6c438437cad41d862fca6David Brown // TODO: this call needs to happen in the CallController, not here. 198375e3711d82d0c98444f6c438437cad41d862fca6David Brown // (It should probably be triggered by the CallNotifier's onDisconnect method.) 198475e3711d82d0c98444f6c438437cad41d862fca6David Brown // mHandler.removeMessages(THREEWAY_CALLERINFO_DISPLAY_DONE); 1985b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1986b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1987b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1988b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Brings up the "MMI Started" dialog. 1989b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1990eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa /* TODO: sort out MMI code (probably we should remove this method entirely). See also 1991eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa MMI handling code in onResume() 1992b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void onMMIInitiate(AsyncResult r) { 1993796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("onMMIInitiate()... AsyncResult r = " + r); 1994b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1995b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Watch out: don't do this if we're not the foreground activity, 1996b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // mainly since in the Dialog.show() might fail if we don't have a 1997b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // valid window token any more... 1998b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (Note that this exact sequence can happen if you try to start 1999b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // an MMI code while the radio is off or out of service.) 2000b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (!mIsForegroundActivity) { 2001796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("Activity not in foreground! Bailing out..."); 2002b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 2003b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2004b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2005b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Also, if any other dialog is up right now (presumably the 2006b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // generic error dialog displaying the "Starting MMI..." message) 2007b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // take it down before bringing up the real "MMI Started" dialog 2008b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // in its place. 2009b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project dismissAllDialogs(); 2010b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2011b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project MmiCode mmiCode = (MmiCode) r.result; 2012796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log(" - MmiCode: " + mmiCode); 2013b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2014b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Message message = Message.obtain(mHandler, PhoneApp.MMI_CANCEL); 2015b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mMmiStartedDialog = PhoneUtils.displayMMIInitiate(this, mmiCode, 2016b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project message, mMmiStartedDialog); 2017eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa }*/ 2018b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2019b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 2020b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Handles an MMI_CANCEL event, which is triggered by the button 2021b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * (labeled either "OK" or "Cancel") on the "MMI Started" dialog. 2022eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa * @see PhoneUtils#cancelMmiCode(Phone) 2023b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 2024b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void onMMICancel() { 2025796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("onMMICancel()..."); 2026b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2027b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // First of all, cancel the outstanding MMI code (if possible.) 2028b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project PhoneUtils.cancelMmiCode(mPhone); 2029b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2030b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Regardless of whether the current MMI code was cancelable, the 2031b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // PhoneApp will get an MMI_COMPLETE event very soon, which will 2032b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // take us to the MMI Complete dialog (see 2033b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // PhoneUtils.displayMMIComplete().) 2034b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 2035b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // But until that event comes in, we *don't* want to stay here on 2036b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the in-call screen, since we'll be visible in a 2037b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // partially-constructed state as soon as the "MMI Started" dialog 2038b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // gets dismissed. So let's forcibly bail out right now. 20394a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("onMMICancel: finishing InCallScreen..."); 2040eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa dismissAllDialogs(); 20414a5a966f0d43e04d336be1b94182346399a931f6Wink Saville endInCallScreenSession(); 2042b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2043b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2044b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 2045eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa * Handles an MMI_COMPLETE event, which is triggered by telephony, 2046eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa * implying MMI 2047eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa */ 2048eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa private void onMMIComplete(MmiCode mmiCode) { 2049eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // Check the code to see if the request is ready to 2050eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // finish, this includes any MMI state that is not 2051eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // PENDING. 2052eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa 2053eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa // if phone is a CDMA phone display feature code completed message 2054eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa int phoneType = mPhone.getPhoneType(); 2055b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { 2056eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa PhoneUtils.displayMMIComplete(mPhone, mApp, mmiCode, null, null); 2057b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) { 2058eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa if (mmiCode.getState() != MmiCode.State.PENDING) { 2059eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa if (DBG) log("Got MMI_COMPLETE, finishing InCallScreen..."); 2060eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa dismissAllDialogs(); 2061eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa endInCallScreenSession(); 2062eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa } 2063eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa } 2064eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa } 2065eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa 2066eef7d1209a926a3266c93358e58a41c47529d8c4Daisuke Miyakawa /** 2067b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Handles the POST_ON_DIAL_CHARS message from the Phone 2068b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * (see our call to mPhone.setOnPostDialCharacter() above.) 2069b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 2070b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * TODO: NEED TO TEST THIS SEQUENCE now that we no longer handle 2071b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * "dialable" key events here in the InCallScreen: we do directly to the 2072b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Dialer UI instead. Similarly, we may now need to go directly to the 2073b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Dialer to handle POST_ON_DIAL_CHARS too. 2074b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 2075b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void handlePostOnDialChars(AsyncResult r, char ch) { 2076b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection c = (Connection) r.result; 2077b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2078b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (c != null) { 2079b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection.PostDialState state = 2080b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project (Connection.PostDialState) r.userObj; 2081b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2082796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("handlePostOnDialChar: state = " + 2083b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project state + ", ch = " + ch); 2084b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2085b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (state) { 2086b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case STARTED: 208751eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon mDialer.stopLocalToneIfNeeded(); 208851eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (mPauseInProgress) { 208951eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon /** 209051eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon * Note that on some devices, this will never happen, 209151eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon * because we will not ever enter the PAUSE state. 209251eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon */ 209351eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon showPausePromptDialog(c, mPostDialStrAfterPause); 209428dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal } 209551eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon mPauseInProgress = false; 209651eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon mDialer.startLocalToneIfNeeded(ch); 209751eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon 2098b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: is this needed, now that you can't actually 2099b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // type DTMF chars or dial directly from here? 2100b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // If so, we'd need to yank you out of the in-call screen 2101b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // here too (and take you to the 12-key dialer in "in-call" mode.) 2102b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // displayPostDialedChar(ch); 2103b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 2104b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2105b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case WAIT: 210651eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon // wait shows a prompt. 21077397f3b2434a58103a327031bda65c8e9fcecb27David Brown if (DBG) log("handlePostOnDialChars: show WAIT prompt..."); 210851eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon mDialer.stopLocalToneIfNeeded(); 2109b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project String postDialStr = c.getRemainingPostDialString(); 211051eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon showWaitPromptDialog(c, postDialStr); 2111b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 2112b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2113b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case WILD: 21147397f3b2434a58103a327031bda65c8e9fcecb27David Brown if (DBG) log("handlePostOnDialChars: show WILD prompt"); 211551eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon mDialer.stopLocalToneIfNeeded(); 2116b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project showWildPromptDialog(c); 2117b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 2118b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2119b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case COMPLETE: 212051eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon mDialer.stopLocalToneIfNeeded(); 212128dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal break; 212228dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal 212328dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal case PAUSE: 212451eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon // pauses for a brief period of time then continue dialing. 212551eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon mDialer.stopLocalToneIfNeeded(); 212651eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon mPostDialStrAfterPause = c.getRemainingPostDialString(); 212751eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon mPauseInProgress = true; 2128b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 2129b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2130b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project default: 2131b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 2132b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2133b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2134b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2135b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 213628dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal /** 213728dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal * Pop up an alert dialog with OK and Cancel buttons to allow user to 213828dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal * Accept or Reject the WAIT inserted as part of the Dial string. 213928dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal */ 214051eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon private void showWaitPromptDialog(final Connection c, String postDialStr) { 214151eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon if (DBG) log("showWaitPromptDialogChoice: '" + postDialStr + "'..."); 21427397f3b2434a58103a327031bda65c8e9fcecb27David Brown 214328dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal Resources r = getResources(); 214428dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal StringBuilder buf = new StringBuilder(); 214528dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal buf.append(r.getText(R.string.wait_prompt_str)); 214628dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal buf.append(postDialStr); 214728dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal 21487397f3b2434a58103a327031bda65c8e9fcecb27David Brown // if (DBG) log("- mWaitPromptDialog = " + mWaitPromptDialog); 214928dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal if (mWaitPromptDialog != null) { 215028dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal if (DBG) log("- DISMISSING mWaitPromptDialog."); 215128dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal mWaitPromptDialog.dismiss(); // safe even if already dismissed 215228dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal mWaitPromptDialog = null; 215328dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal } 215428dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal 215528dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal mWaitPromptDialog = new AlertDialog.Builder(this) 215628dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal .setMessage(buf.toString()) 215728dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal .setPositiveButton(R.string.pause_prompt_yes, 2158b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa new DialogInterface.OnClickListener() { 2159b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa @Override 2160b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa public void onClick(DialogInterface dialog, int whichButton) { 2161b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa if (DBG) log("handle WAIT_PROMPT_CONFIRMED, proceed..."); 2162b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa c.proceedAfterWaitChar(); 2163b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa } 2164b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa }) 2165b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa .setNegativeButton(R.string.pause_prompt_no, 2166b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa new DialogInterface.OnClickListener() { 2167b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa @Override 2168b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa public void onClick(DialogInterface dialog, int whichButton) { 2169b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa if (DBG) log("handle POST_DIAL_CANCELED!"); 2170b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa c.cancelPostDial(); 2171b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa } 2172b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa }) 217328dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal .create(); 217428dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal mWaitPromptDialog.getWindow().addFlags( 217528dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal WindowManager.LayoutParams.FLAG_BLUR_BEHIND); 217651eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon 217728dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal mWaitPromptDialog.show(); 217828dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal } 217928dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal 218028dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal /** 218128dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal * Pop up an alert dialog which waits for 2 seconds for each P (Pause) Character entered 218228dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal * as part of the Dial String. 218328dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal */ 218451eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon private void showPausePromptDialog(final Connection c, String postDialStrAfterPause) { 218528dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal Resources r = getResources(); 218628dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal StringBuilder buf = new StringBuilder(); 218728dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal buf.append(r.getText(R.string.pause_prompt_str)); 218828dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal buf.append(postDialStrAfterPause); 218928dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal 219028dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal if (mPausePromptDialog != null) { 219128dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal if (DBG) log("- DISMISSING mPausePromptDialog."); 219228dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal mPausePromptDialog.dismiss(); // safe even if already dismissed 219328dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal mPausePromptDialog = null; 219428dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal } 219528dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal 219628dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal mPausePromptDialog = new AlertDialog.Builder(this) 219728dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal .setMessage(buf.toString()) 219828dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal .create(); 219928dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal mPausePromptDialog.show(); 220028dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal // 2 second timer 220128dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal Message msg = Message.obtain(mHandler, EVENT_PAUSE_DIALOG_COMPLETE); 220228dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal mHandler.sendMessageDelayed(msg, PAUSE_PROMPT_DIALOG_TIMEOUT); 220328dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal } 220428dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal 2205b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private View createWildPromptView() { 2206b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project LinearLayout result = new LinearLayout(this); 2207b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project result.setOrientation(LinearLayout.VERTICAL); 2208b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project result.setPadding(5, 5, 5, 5); 2209b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2210b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( 2211a101c0d93c5225ebf9f3e79854c0fa9b27865e6fRomain Guy ViewGroup.LayoutParams.MATCH_PARENT, 2212b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ViewGroup.LayoutParams.WRAP_CONTENT); 2213b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2214b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project TextView promptMsg = new TextView(this); 2215b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project promptMsg.setTextSize(14); 2216b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project promptMsg.setTypeface(Typeface.DEFAULT_BOLD); 2217b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project promptMsg.setText(getResources().getText(R.string.wild_prompt_str)); 2218b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2219b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project result.addView(promptMsg, lp); 2220b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2221b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWildPromptText = new EditText(this); 2222b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWildPromptText.setKeyListener(DialerKeyListener.getInstance()); 2223b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWildPromptText.setMovementMethod(null); 2224b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWildPromptText.setTextSize(14); 2225b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWildPromptText.setMaxLines(1); 2226b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWildPromptText.setHorizontallyScrolling(true); 2227b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWildPromptText.setBackgroundResource(android.R.drawable.editbox_background); 2228b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2229b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams( 2230a101c0d93c5225ebf9f3e79854c0fa9b27865e6fRomain Guy ViewGroup.LayoutParams.MATCH_PARENT, 2231b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ViewGroup.LayoutParams.WRAP_CONTENT); 2232b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project lp2.setMargins(0, 3, 0, 0); 2233b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2234b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project result.addView(mWildPromptText, lp2); 2235b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2236b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return result; 2237b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2238b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2239b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void showWildPromptDialog(final Connection c) { 2240b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project View v = createWildPromptView(); 2241b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2242b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mWildPromptDialog != null) { 2243796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- DISMISSING mWildPromptDialog."); 2244b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWildPromptDialog.dismiss(); // safe even if already dismissed 2245b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWildPromptDialog = null; 2246b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2247b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2248b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWildPromptDialog = new AlertDialog.Builder(this) 2249b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project .setView(v) 2250b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project .setPositiveButton( 2251b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project R.string.send_button, 2252b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project new DialogInterface.OnClickListener() { 2253b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa @Override 2254b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onClick(DialogInterface dialog, int whichButton) { 2255796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("handle WILD_PROMPT_CHAR_ENTERED, proceed..."); 2256b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project String replacement = null; 2257b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mWildPromptText != null) { 2258b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project replacement = mWildPromptText.getText().toString(); 2259b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWildPromptText = null; 2260b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2261b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project c.proceedAfterWildChar(replacement); 226275e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.pokeUserActivity(); 2263b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2264b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project }) 2265b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project .setOnCancelListener( 2266b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project new DialogInterface.OnCancelListener() { 2267b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa @Override 2268b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onCancel(DialogInterface dialog) { 2269796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("handle POST_DIAL_CANCELED!"); 2270b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project c.cancelPostDial(); 227175e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.pokeUserActivity(); 2272b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2273b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project }) 2274b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project .create(); 2275b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWildPromptDialog.getWindow().addFlags( 2276b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project WindowManager.LayoutParams.FLAG_BLUR_BEHIND); 2277b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWildPromptDialog.show(); 2278b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2279b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWildPromptText.requestFocus(); 2280b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2281b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2282b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 2283b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the state of the in-call UI based on the current state of 228475e3711d82d0c98444f6c438437cad41d862fca6David Brown * the Phone. This call has no effect if we're not currently the 228575e3711d82d0c98444f6c438437cad41d862fca6David Brown * foreground activity. 228696af4b62835c1d0d023d285b896226386621e283David Brown * 228796af4b62835c1d0d023d285b896226386621e283David Brown * This method is only allowed to be called from the UI thread (since it 228896af4b62835c1d0d023d285b896226386621e283David Brown * manipulates our View hierarchy). If you need to update the screen from 228996af4b62835c1d0d023d285b896226386621e283David Brown * some other thread, or if you just want to "post a request" for the screen 229096af4b62835c1d0d023d285b896226386621e283David Brown * to be updated (rather than doing it synchronously), call 229196af4b62835c1d0d023d285b896226386621e283David Brown * requestUpdateScreen() instead. 2292b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa * 2293b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa * Right now this method will update UI visibility immediately, with no animation. 2294b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa * TODO: have animate flag here and use it anywhere possible. 2295b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 2296b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void updateScreen() { 22974a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("updateScreen()..."); 2298ee6be3c53945e69acce6c2c852ce1ebf69015c9dDavid Brown final InCallScreenMode inCallScreenMode = mApp.inCallUiState.inCallScreenMode; 2299ee6be3c53945e69acce6c2c852ce1ebf69015c9dDavid Brown if (VDBG) { 2300b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville PhoneConstants.State state = mCM.getState(); 2301ee6be3c53945e69acce6c2c852ce1ebf69015c9dDavid Brown log(" - phone state = " + state); 2302ee6be3c53945e69acce6c2c852ce1ebf69015c9dDavid Brown log(" - inCallScreenMode = " + inCallScreenMode); 2303ee6be3c53945e69acce6c2c852ce1ebf69015c9dDavid Brown } 2304b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2305b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Don't update anything if we're not in the foreground (there's 2306b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // no point updating our UI widgets since we're not visible!) 2307b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Also note this check also ensures we won't update while we're 2308b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // in the middle of pausing, which could cause a visible glitch in 2309b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the "activity ending" transition. 2310b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (!mIsForegroundActivity) { 23114a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("- updateScreen: not the foreground Activity! Bailing out..."); 2312b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 2313b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2314b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 231575e3711d82d0c98444f6c438437cad41d862fca6David Brown if (inCallScreenMode == InCallScreenMode.OTA_NORMAL) { 2316b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa if (DBG) log("- updateScreen: OTA call state NORMAL (NOT updating in-call UI)..."); 23170d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa mCallCard.setVisibility(View.GONE); 231875e3711d82d0c98444f6c438437cad41d862fca6David Brown if (mApp.otaUtils != null) { 231975e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.otaUtils.otaShowProperScreen(); 2320b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa } else { 2321b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa Log.w(LOG_TAG, "OtaUtils object is null, not showing any screen for that."); 2322af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 2323b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa return; // Return without updating in-call UI. 232475e3711d82d0c98444f6c438437cad41d862fca6David Brown } else if (inCallScreenMode == InCallScreenMode.OTA_ENDED) { 2325b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa if (DBG) log("- updateScreen: OTA call ended state (NOT updating in-call UI)..."); 23260d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa mCallCard.setVisibility(View.GONE); 232790d7924ced3749c2207088cbc6f4e8707e330d5dJim Miller // Wake up the screen when we get notification, good or bad. 232875e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.wakeUpScreen(); 232975e3711d82d0c98444f6c438437cad41d862fca6David Brown if (mApp.cdmaOtaScreenState.otaScreenState 2330b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION) { 23314a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("- updateScreen: OTA_STATUS_ACTIVATION"); 233275e3711d82d0c98444f6c438437cad41d862fca6David Brown if (mApp.otaUtils != null) { 233375e3711d82d0c98444f6c438437cad41d862fca6David Brown if (DBG) log("- updateScreen: mApp.otaUtils is not null, " 2334d1b19c70340c258796e7c2ebe6459c65cb16245fDavid Brown + "call otaShowActivationScreen"); 233575e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.otaUtils.otaShowActivateScreen(); 2336af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 2337af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } else { 23384a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("- updateScreen: OTA Call end state for Dialogs"); 233975e3711d82d0c98444f6c438437cad41d862fca6David Brown if (mApp.otaUtils != null) { 23404a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("- updateScreen: Show OTA Success Failure dialog"); 234175e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.otaUtils.otaShowSuccessFailure(); 2342af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 2343af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 2344b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa return; // Return without updating in-call UI. 234575e3711d82d0c98444f6c438437cad41d862fca6David Brown } else if (inCallScreenMode == InCallScreenMode.MANAGE_CONFERENCE) { 23464a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("- updateScreen: manage conference mode (NOT updating in-call UI)..."); 23470d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa mCallCard.setVisibility(View.GONE); 2348b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project updateManageConferencePanelIfNecessary(); 2349b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa return; // Return without updating in-call UI. 235075e3711d82d0c98444f6c438437cad41d862fca6David Brown } else if (inCallScreenMode == InCallScreenMode.CALL_ENDED) { 235196af4b62835c1d0d023d285b896226386621e283David Brown if (DBG) log("- updateScreen: call ended state..."); 235296af4b62835c1d0d023d285b896226386621e283David Brown // Continue with the rest of updateScreen() as usual, since we do 235396af4b62835c1d0d023d285b896226386621e283David Brown // need to update the background (to the special "call ended" color) 235496af4b62835c1d0d023d285b896226386621e283David Brown // and the CallCard (to show the "Call ended" label.) 2355b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2356b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 23574a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("- updateScreen: updating the in-call UI..."); 2358507ee75639e41c17edd410ef787e0617778071aaDavid Brown // Note we update the InCallTouchUi widget before the CallCard, 2359507ee75639e41c17edd410ef787e0617778071aaDavid Brown // since the CallCard adjusts its size based on how much vertical 2360507ee75639e41c17edd410ef787e0617778071aaDavid Brown // space the InCallTouchUi widget needs. 2361507ee75639e41c17edd410ef787e0617778071aaDavid Brown updateInCallTouchUi(); 23628343169cc89621d46dce86449f5ee1ff5d3a4919John Wang mCallCard.updateState(mCM); 2363b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa 2364b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa // If an incoming call is ringing, make sure the dialpad is 2365b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa // closed. (We do this to make sure we're not covering up the 2366b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa // "incoming call" UI.) 236798e53a1f30285cfe855a5955107a24e78ac831eaSantos Cordon if (mCM.getState() == PhoneConstants.State.RINGING) { 2368083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon if (mDialer.isOpened()) { 2369083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon Log.i(LOG_TAG, "During RINGING state we force hiding dialpad."); 2370083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon closeDialpadInternal(false); // don't do the "closing" animation 2371083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon } 2372b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa 2373083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon // At this point, we are guranteed that the dialer is closed. 2374083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon // This means that it is safe to clear out the "history" of DTMF digits 2375083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon // you may have typed into the previous call (so you don't see the 2376083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon // previous call's digits if you answer this call and then bring up the 2377083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon // dialpad.) 2378b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa // 2379b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa // TODO: it would be more precise to do this when you *answer* the 2380b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa // incoming call, rather than as soon as it starts ringing, but 2381b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa // the InCallScreen doesn't keep enough state right now to notice 2382b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa // that specific transition in onPhoneStateChanged(). 2383083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon // TODO: This clears out the dialpad context as well so when a second 2384083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon // call comes in while a voicemail call is happening, the voicemail 2385083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon // dialpad will no longer have the "Voice Mail" context. It's a small 2386083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon // case so not terribly bad, but we need to maintain a better 2387083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon // call-to-callstate mapping before we can fix this. 2388b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa mDialer.clearDigits(); 2389b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa } 2390083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon 2391083365527c51806a5cc4d1966e46f3f32325deeeSantos Cordon 2392b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa // Now that we're sure DTMF dialpad is in an appropriate state, reflect 23930d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa // the dialpad state into CallCard 23940d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa updateCallCardVisibilityPerDialerState(false); 2395b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa 23963426afaf85d33d454fad8d341a1a895fd7e21c10David Brown updateProgressIndication(); 239769409e155fe4bbfd6e1960605d282380c63f5911Yafan Lian 239869409e155fe4bbfd6e1960605d282380c63f5911Yafan Lian // Forcibly take down all dialog if an incoming call is ringing. 2399c97fea097483c6e58c199e857b279ec92e64d8e3John Wang if (mCM.hasActiveRingingCall()) { 240069409e155fe4bbfd6e1960605d282380c63f5911Yafan Lian dismissAllDialogs(); 240169409e155fe4bbfd6e1960605d282380c63f5911Yafan Lian } else { 240269409e155fe4bbfd6e1960605d282380c63f5911Yafan Lian // Wait prompt dialog is not currently up. But it *should* be 240369409e155fe4bbfd6e1960605d282380c63f5911Yafan Lian // up if the FG call has a connection in the WAIT state and 240469409e155fe4bbfd6e1960605d282380c63f5911Yafan Lian // the phone isn't ringing. 24052e23f24acd22741afc91ff8d6568d486ae491552Peng Zhu String postDialStr = null; 2406c97fea097483c6e58c199e857b279ec92e64d8e3John Wang List<Connection> fgConnections = mCM.getFgCallConnections(); 24078343169cc89621d46dce86449f5ee1ff5d3a4919John Wang int phoneType = mCM.getFgPhone().getPhoneType(); 2408b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { 2409c97fea097483c6e58c199e857b279ec92e64d8e3John Wang Connection fgLatestConnection = mCM.getFgCallLatestConnection(); 241075e3711d82d0c98444f6c438437cad41d862fca6David Brown if (mApp.cdmaPhoneCallState.getCurrentCallState() == 24112e23f24acd22741afc91ff8d6568d486ae491552Peng Zhu CdmaPhoneCallState.PhoneCallState.CONF_CALL) { 24122e23f24acd22741afc91ff8d6568d486ae491552Peng Zhu for (Connection cn : fgConnections) { 24132e23f24acd22741afc91ff8d6568d486ae491552Peng Zhu if ((cn != null) && (cn.getPostDialState() == 24142e23f24acd22741afc91ff8d6568d486ae491552Peng Zhu Connection.PostDialState.WAIT)) { 24152e23f24acd22741afc91ff8d6568d486ae491552Peng Zhu cn.cancelPostDial(); 2416a663498ca988952fb60a6e9db66daff28b39dcb8Yafan Lian } 24172e23f24acd22741afc91ff8d6568d486ae491552Peng Zhu } 24182e23f24acd22741afc91ff8d6568d486ae491552Peng Zhu } else if ((fgLatestConnection != null) 24192e23f24acd22741afc91ff8d6568d486ae491552Peng Zhu && (fgLatestConnection.getPostDialState() == Connection.PostDialState.WAIT)) { 24202e23f24acd22741afc91ff8d6568d486ae491552Peng Zhu if(DBG) log("show the Wait dialog for CDMA"); 24212e23f24acd22741afc91ff8d6568d486ae491552Peng Zhu postDialStr = fgLatestConnection.getRemainingPostDialString(); 242251eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon showWaitPromptDialog(fgLatestConnection, postDialStr); 24232e23f24acd22741afc91ff8d6568d486ae491552Peng Zhu } 2424b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM) 2425b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) { 24262e23f24acd22741afc91ff8d6568d486ae491552Peng Zhu for (Connection cn : fgConnections) { 24272e23f24acd22741afc91ff8d6568d486ae491552Peng Zhu if ((cn != null) && (cn.getPostDialState() == Connection.PostDialState.WAIT)) { 24282e23f24acd22741afc91ff8d6568d486ae491552Peng Zhu postDialStr = cn.getRemainingPostDialString(); 242951eaa15edd6953b961a502bd517bcdec59d15d13Martin Hibdon showWaitPromptDialog(cn, postDialStr); 2430a663498ca988952fb60a6e9db66daff28b39dcb8Yafan Lian } 243169409e155fe4bbfd6e1960605d282380c63f5911Yafan Lian } 243279b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } else { 243379b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink throw new IllegalStateException("Unexpected phone type: " + phoneType); 243469409e155fe4bbfd6e1960605d282380c63f5911Yafan Lian } 243569409e155fe4bbfd6e1960605d282380c63f5911Yafan Lian } 2436b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2437b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2438b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 2439b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * (Re)synchronizes the onscreen UI with the current state of the 244075e3711d82d0c98444f6c438437cad41d862fca6David Brown * telephony framework. 2441b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 244275e3711d82d0c98444f6c438437cad41d862fca6David Brown * @return SyncWithPhoneStateStatus.SUCCESS if we successfully updated the UI, or 244375e3711d82d0c98444f6c438437cad41d862fca6David Brown * SyncWithPhoneStateStatus.PHONE_NOT_IN_USE if there was no phone state to sync 2444b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * with (ie. the phone was completely idle). In the latter case, we 2445b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * shouldn't even be in the in-call UI in the first place, and it's 24464a5a966f0d43e04d336be1b94182346399a931f6Wink Saville * the caller's responsibility to bail out of this activity by 24474a5a966f0d43e04d336be1b94182346399a931f6Wink Saville * calling endInCallScreenSession if appropriate. 244896af4b62835c1d0d023d285b896226386621e283David Brown * 244996af4b62835c1d0d023d285b896226386621e283David Brown * This method directly calls updateScreen() in the normal "phone is 245096af4b62835c1d0d023d285b896226386621e283David Brown * in use" case, so there's no need for the caller to do so. 2451b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 245275e3711d82d0c98444f6c438437cad41d862fca6David Brown private SyncWithPhoneStateStatus syncWithPhoneState() { 2453b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean updateSuccessful = false; 2454b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("syncWithPhoneState()..."); 24550f68bb19e2cca0bb7f70e2fcf16e0747a0036885David Brown if (DBG) PhoneUtils.dumpCallState(mPhone); 2456796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) dumpBluetoothState(); 2457b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2458b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Make sure the Phone is "in use". (If not, we shouldn't be on 2459b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // this screen in the first place.) 2460b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 246195bef36fa7efe381db81ec08b6244daf02414a28David Brown // An active or just-ended OTA call counts as "in use". 24621b4455031a45a9b87cf66b3384ce59287500a448Hung-ying Tyan if (TelephonyCapabilities.supportsOtasp(mCM.getFgPhone()) 246375e3711d82d0c98444f6c438437cad41d862fca6David Brown && ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL) 246475e3711d82d0c98444f6c438437cad41d862fca6David Brown || (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED))) { 2465af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville // Even when OTA Call ends, need to show OTA End UI, 2466af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville // so return Success to allow UI update. 246775e3711d82d0c98444f6c438437cad41d862fca6David Brown return SyncWithPhoneStateStatus.SUCCESS; 246879b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } 246979b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink 247095bef36fa7efe381db81ec08b6244daf02414a28David Brown // If an MMI code is running that also counts as "in use". 247195bef36fa7efe381db81ec08b6244daf02414a28David Brown // 247295bef36fa7efe381db81ec08b6244daf02414a28David Brown // TODO: We currently only call getPendingMmiCodes() for GSM 247395bef36fa7efe381db81ec08b6244daf02414a28David Brown // phones. (The code's been that way all along.) But CDMAPhone 247495bef36fa7efe381db81ec08b6244daf02414a28David Brown // does in fact implement getPendingMmiCodes(), so should we 247595bef36fa7efe381db81ec08b6244daf02414a28David Brown // check that here regardless of the phone type? 2476ae3bcafc6ad3a0f106ff71a3bd586fe563497731David Brown boolean hasPendingMmiCodes = 2477b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM) 247895bef36fa7efe381db81ec08b6244daf02414a28David Brown && !mPhone.getPendingMmiCodes().isEmpty(); 2479ae3bcafc6ad3a0f106ff71a3bd586fe563497731David Brown 24803426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // Finally, it's also OK to stay here on the InCallScreen if we 24813426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // need to display a progress indicator while something's 24823426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // happening in the background. 24833426afaf85d33d454fad8d341a1a895fd7e21c10David Brown boolean showProgressIndication = mApp.inCallUiState.isProgressIndicationActive(); 24843426afaf85d33d454fad8d341a1a895fd7e21c10David Brown 24856522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa boolean showScreenEvenAfterDisconnect = mApp.inCallUiState.showAlreadyDisconnectedState; 24866522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa 2487c97fea097483c6e58c199e857b279ec92e64d8e3John Wang if (mCM.hasActiveFgCall() || mCM.hasActiveBgCall() || mCM.hasActiveRingingCall() 24886522e3df7712f6259ed20242ced3a8246f8e6d9aDaisuke Miyakawa || hasPendingMmiCodes || showProgressIndication || showScreenEvenAfterDisconnect) { 2489796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("syncWithPhoneState: it's ok to be here; update the screen..."); 2490b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project updateScreen(); 249175e3711d82d0c98444f6c438437cad41d862fca6David Brown return SyncWithPhoneStateStatus.SUCCESS; 2492b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2493b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 249495bef36fa7efe381db81ec08b6244daf02414a28David Brown Log.i(LOG_TAG, "syncWithPhoneState: phone is idle (shouldn't be here)"); 249575e3711d82d0c98444f6c438437cad41d862fca6David Brown return SyncWithPhoneStateStatus.PHONE_NOT_IN_USE; 2496b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2497b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 24981421491ef591a2529a5c3cf278802522785044aeDavid Brown 2499b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2500b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void handleMissingVoiceMailNumber() { 2501b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("handleMissingVoiceMailNumber"); 2502b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2503b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project final Message msg = Message.obtain(mHandler); 2504b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project msg.what = DONT_ADD_VOICEMAIL_NUMBER; 2505b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2506b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project final Message msg2 = Message.obtain(mHandler); 2507b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project msg2.what = ADD_VOICEMAIL_NUMBER; 2508b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2509b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mMissingVoicemailDialog = new AlertDialog.Builder(this) 2510b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project .setTitle(R.string.no_vm_number) 2511b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project .setMessage(R.string.no_vm_number_msg) 2512b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { 2513b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onClick(DialogInterface dialog, int which) { 2514796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("Missing voicemail AlertDialog: POSITIVE click..."); 2515b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project msg.sendToTarget(); // see dontAddVoiceMailNumber() 251675e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.pokeUserActivity(); 2517b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project }}) 2518b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project .setNegativeButton(R.string.add_vm_number_str, 2519b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project new DialogInterface.OnClickListener() { 2520b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onClick(DialogInterface dialog, int which) { 2521796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("Missing voicemail AlertDialog: NEGATIVE click..."); 2522b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project msg2.sendToTarget(); // see addVoiceMailNumber() 252375e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.pokeUserActivity(); 2524b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project }}) 2525b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project .setOnCancelListener(new OnCancelListener() { 2526b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onCancel(DialogInterface dialog) { 2527796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("Missing voicemail AlertDialog: CANCEL handler..."); 2528b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project msg.sendToTarget(); // see dontAddVoiceMailNumber() 252975e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.pokeUserActivity(); 2530b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project }}) 2531b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project .create(); 2532b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2533b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // When the dialog is up, completely hide the in-call UI 2534b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // underneath (which is in a partially-constructed state). 2535b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mMissingVoicemailDialog.getWindow().addFlags( 2536b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project WindowManager.LayoutParams.FLAG_DIM_BEHIND); 2537b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2538b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mMissingVoicemailDialog.show(); 2539b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2540b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2541b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void addVoiceMailNumberPanel() { 2542b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mMissingVoicemailDialog != null) { 2543b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mMissingVoicemailDialog.dismiss(); 2544b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mMissingVoicemailDialog = null; 2545b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 25464a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("addVoiceMailNumberPanel: finishing InCallScreen..."); 25474a5a966f0d43e04d336be1b94182346399a931f6Wink Saville endInCallScreenSession(); 2548b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2549404edc94de563aef5fd5ba48be9114a970cb93bbWink Saville if (DBG) log("show vm setting"); 2550404edc94de563aef5fd5ba48be9114a970cb93bbWink Saville 2551b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // navigate to the Voicemail setting in the Call Settings activity. 2552b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Intent intent = new Intent(CallFeaturesSetting.ACTION_ADD_VOICEMAIL); 2553b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project intent.setClass(this, CallFeaturesSetting.class); 2554b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project startActivity(intent); 2555b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2556b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2557b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void dontAddVoiceMailNumber() { 2558b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mMissingVoicemailDialog != null) { 2559b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mMissingVoicemailDialog.dismiss(); 2560b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mMissingVoicemailDialog = null; 2561b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 25624a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("dontAddVoiceMailNumber: finishing InCallScreen..."); 25634a5a966f0d43e04d336be1b94182346399a931f6Wink Saville endInCallScreenSession(); 2564b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2565b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2566b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 2567b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Do some delayed cleanup after a Phone call gets disconnected. 2568b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 2569b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * This method gets called a couple of seconds after any DISCONNECT 2570b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * event from the Phone; it's triggered by the 2571b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * DELAYED_CLEANUP_AFTER_DISCONNECT message we send in onDisconnect(). 2572b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 2573b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * If the Phone is totally idle right now, that means we've already 2574b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * shown the "call ended" state for a couple of seconds, and it's now 25754a5a966f0d43e04d336be1b94182346399a931f6Wink Saville * time to endInCallScreenSession this activity. 2576b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 2577b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * If the Phone is *not* idle right now, that probably means that one 25783426afaf85d33d454fad8d341a1a895fd7e21c10David Brown * call ended but the other line is still in use. In that case, do 25793426afaf85d33d454fad8d341a1a895fd7e21c10David Brown * nothing, and instead stay here on the InCallScreen. 2580b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 2581b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void delayedCleanupAfterDisconnect() { 25826f11c0b721507e762af13d60856fcf53ab6e089aDaisuke Miyakawa if (VDBG) log("delayedCleanupAfterDisconnect()... Phone state = " + mCM.getState()); 2583b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2584b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Clean up any connections in the DISCONNECTED state. 2585b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 2586b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // [Background: Even after a connection gets disconnected, its 2587b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Connection object still stays around, in the special 2588b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // DISCONNECTED state. This is necessary because we we need the 2589b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // caller-id information from that Connection to properly draw the 2590b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "Call ended" state of the CallCard. 2591b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // But at this point we truly don't need that connection any 2592b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // more, so tell the Phone that it's now OK to to clean up any 2593b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // connections still in that state.] 25948343169cc89621d46dce86449f5ee1ff5d3a4919John Wang mCM.clearDisconnected(); 2595b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 25963426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // There are two cases where we should *not* exit the InCallScreen: 25973426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // (1) Phone is still in use 25983426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // or 25993426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // (2) There's an active progress indication (i.e. the "Retrying..." 26003426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // progress dialog) that we need to continue to display. 26013426afaf85d33d454fad8d341a1a895fd7e21c10David Brown 26023426afaf85d33d454fad8d341a1a895fd7e21c10David Brown boolean stayHere = phoneIsInUse() || mApp.inCallUiState.isProgressIndicationActive(); 26033426afaf85d33d454fad8d341a1a895fd7e21c10David Brown 26043426afaf85d33d454fad8d341a1a895fd7e21c10David Brown if (stayHere) { 26056f11c0b721507e762af13d60856fcf53ab6e089aDaisuke Miyakawa if (DBG) log("- delayedCleanupAfterDisconnect: staying on the InCallScreen..."); 26063426afaf85d33d454fad8d341a1a895fd7e21c10David Brown } else { 26073426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // Phone is idle! We should exit the in-call UI now. 2608b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- delayedCleanupAfterDisconnect: phone is idle..."); 2609b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2610b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // And (finally!) exit from the in-call screen 2611b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (but not if we're already in the process of pausing...) 2612b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mIsForegroundActivity) { 26134a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("- delayedCleanupAfterDisconnect: finishing InCallScreen..."); 2614b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2615d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // In some cases we finish the call by taking the user to the 2616d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // Call Log. Otherwise, we simply call endInCallScreenSession, 2617d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // which will take us back to wherever we came from. 2618d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // 2619d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // UI note: In eclair and earlier, we went to the Call Log 2620d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // after outgoing calls initiated on the device, but never for 2621d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // incoming calls. Now we do it for incoming calls too, as 2622d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // long as the call was answered by the user. (We always go 2623d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // back where you came from after a rejected or missed incoming 2624d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // call.) 2625d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // 2626d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // And in any case, *never* go to the call log if we're in 2627d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // emergency mode (i.e. if the screen is locked and a lock 26281aa254b1cecfb2eb9b4cad78d2788874b8f11dabDavid Brown // pattern or PIN/password is set), or if we somehow got here 26291aa254b1cecfb2eb9b4cad78d2788874b8f11dabDavid Brown // on a non-voice-capable device. 2630d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown 2631d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown if (VDBG) log("- Post-call behavior:"); 2632d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown if (VDBG) log(" - mLastDisconnectCause = " + mLastDisconnectCause); 2633d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown if (VDBG) log(" - isPhoneStateRestricted() = " + isPhoneStateRestricted()); 2634d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown 2635d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // DisconnectCause values in the most common scenarios: 2636d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // - INCOMING_MISSED: incoming ringing call times out, or the 2637d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // other end hangs up while still ringing 2638d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // - INCOMING_REJECTED: user rejects the call while ringing 2639d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // - LOCAL: user hung up while a call was active (after 2640d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // answering an incoming call, or after making an 2641d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // outgoing call) 2642d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // - NORMAL: the other end hung up (after answering an incoming 2643d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown // call, or after making an outgoing call) 2644d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown 2645d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown if ((mLastDisconnectCause != Connection.DisconnectCause.INCOMING_MISSED) 2646d3bd32cfe009722ac0e9ee79a9ce59d723adf6cdDavid Brown && (mLastDisconnectCause != Connection.DisconnectCause.INCOMING_REJECTED) 26471aa254b1cecfb2eb9b4cad78d2788874b8f11dabDavid Brown && !isPhoneStateRestricted() 2648a1a9601840e50e18ff8ca4be9b888e592287577bDianne Hackborn && PhoneGlobals.sVoiceCapable) { 26496734941af0f8874ca584a363ef3a8febe41b397dDaisuke Miyakawa final Intent intent = mApp.createPhoneEndIntentUsingCallOrigin(); 265007d801323833fd50c89c060910030c81d6af6d10Daisuke Miyakawa ActivityOptions opts = ActivityOptions.makeCustomAnimation(this, 265107d801323833fd50c89c060910030c81d6af6d10Daisuke Miyakawa R.anim.activity_close_enter, R.anim.activity_close_exit); 26526734941af0f8874ca584a363ef3a8febe41b397dDaisuke Miyakawa if (VDBG) { 26536734941af0f8874ca584a363ef3a8febe41b397dDaisuke Miyakawa log("- Show Call Log (or Dialtacts) after disconnect. Current intent: " 26546734941af0f8874ca584a363ef3a8febe41b397dDaisuke Miyakawa + intent); 26556734941af0f8874ca584a363ef3a8febe41b397dDaisuke Miyakawa } 26563ff152c80b97c32a5764c54d2aeb888509cf84adDavid Brown try { 265707d801323833fd50c89c060910030c81d6af6d10Daisuke Miyakawa startActivity(intent, opts.toBundle()); 26583ff152c80b97c32a5764c54d2aeb888509cf84adDavid Brown } catch (ActivityNotFoundException e) { 26591aa254b1cecfb2eb9b4cad78d2788874b8f11dabDavid Brown // Don't crash if there's somehow no "Call log" at 26601aa254b1cecfb2eb9b4cad78d2788874b8f11dabDavid Brown // all on this device. 26611aa254b1cecfb2eb9b4cad78d2788874b8f11dabDavid Brown // (This should never happen, though, since we already 26621aa254b1cecfb2eb9b4cad78d2788874b8f11dabDavid Brown // checked PhoneApp.sVoiceCapable above, and any 26631aa254b1cecfb2eb9b4cad78d2788874b8f11dabDavid Brown // voice-capable device surely *should* have a call 26641aa254b1cecfb2eb9b4cad78d2788874b8f11dabDavid Brown // log activity....) 26653ff152c80b97c32a5764c54d2aeb888509cf84adDavid Brown Log.w(LOG_TAG, "delayedCleanupAfterDisconnect: " 26663ff152c80b97c32a5764c54d2aeb888509cf84adDavid Brown + "transition to call log failed; intent = " + intent); 26673ff152c80b97c32a5764c54d2aeb888509cf84adDavid Brown // ...so just return back where we came from.... 26683ff152c80b97c32a5764c54d2aeb888509cf84adDavid Brown } 26693ff152c80b97c32a5764c54d2aeb888509cf84adDavid Brown // Even if we did go to the call log, note that we still 26703ff152c80b97c32a5764c54d2aeb888509cf84adDavid Brown // call endInCallScreenSession (below) to make sure we don't 26713ff152c80b97c32a5764c54d2aeb888509cf84adDavid Brown // stay in the activity history. 2672b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2673b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2674b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 26756b3d4033e66fde153cec402e12a4bb12fd31898aMakoto Onuki endInCallScreenSession(); 26766734941af0f8874ca584a363ef3a8febe41b397dDaisuke Miyakawa 26776734941af0f8874ca584a363ef3a8febe41b397dDaisuke Miyakawa // Reset the call origin when the session ends and this in-call UI is being finished. 26786734941af0f8874ca584a363ef3a8febe41b397dDaisuke Miyakawa mApp.setLatestActiveCallOrigin(null); 2679b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2680b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2681b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2682b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 26834ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown /** 26844ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown * View.OnClickListener implementation. 26854ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown * 26864ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown * This method handles clicks from UI elements that use the 26874ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown * InCallScreen itself as their OnClickListener. 26884ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown * 26893157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa * Note: Currently this method is used only for a few special buttons: 26903157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa * - the mButtonManageConferenceDone "Back to call" button 26913157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa * - the "dim" effect for the secondary call photo in CallCard as the second "swap" button 26923157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa * - other OTASP-specific buttons managed by OtaUtils.java. 26933157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa * 26943157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa * *Most* in-call controls are handled by the handleOnscreenButtonClick() method, via the 26953157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa * InCallTouchUi widget. 26964ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown */ 2697b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa @Override 2698b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onClick(View view) { 2699b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int id = view.getId(); 2700796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("onClick(View " + view + ", id " + id + ")..."); 2701b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2702b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (id) { 2703b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case R.id.manage_done: // mButtonManageConferenceDone 2704796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("onClick: mButtonManageConferenceDone..."); 2705b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Hide the Manage Conference panel, return to NORMAL mode. 2706b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project setInCallScreenMode(InCallScreenMode.NORMAL); 270796af4b62835c1d0d023d285b896226386621e283David Brown requestUpdateScreen(); 2708b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 2709b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 27103157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa case R.id.dim_effect_for_secondary_photo: 27113157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa if (mInCallControlState.canSwap) { 27123157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa internalSwapCalls(); 27133157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa } 27143157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa break; 27153157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa 2716b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project default: 27174ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // Presumably one of the OTASP-specific buttons managed by 27184ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // OtaUtils.java. 27194ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // (TODO: It would be cleaner for the OtaUtils instance itself to 27204ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // be the OnClickListener for its own buttons.) 27214ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown 27224ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL 27234ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown || mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED) 27244ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown && mApp.otaUtils != null) { 272575e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.otaUtils.onClickHandler(id); 2726af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } else { 27274ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // Uh oh: we *should* only receive clicks here from the 27284ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // buttons managed by OtaUtils.java, but if we're not in one 27294ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // of the special OTASP modes, those buttons shouldn't have 27304ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // been visible in the first place. 2731af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville Log.w(LOG_TAG, 27324ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown "onClick: unexpected click from ID " + id + " (View = " + view + ")"); 2733af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 2734b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 2735b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2736b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2737cd89106dcd1038666f992cea3cc79e067245187fDan Egnor EventLog.writeEvent(EventLogTags.PHONE_UI_BUTTON_CLICK, 2738cd89106dcd1038666f992cea3cc79e067245187fDan Egnor (view instanceof TextView) ? ((TextView) view).getText() : ""); 2739b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 27404ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // Clicking any onscreen UI element counts as explicit "user activity". 274175e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.pokeUserActivity(); 2742b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2743b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2744b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void onHoldClick() { 2745c97fea097483c6e58c199e857b279ec92e64d8e3John Wang final boolean hasActiveCall = mCM.hasActiveFgCall(); 2746c97fea097483c6e58c199e857b279ec92e64d8e3John Wang final boolean hasHoldingCall = mCM.hasActiveBgCall(); 274723d416d92d99bc258a82d3e3d590783766898184David Brown log("onHoldClick: hasActiveCall = " + hasActiveCall 274823d416d92d99bc258a82d3e3d590783766898184David Brown + ", hasHoldingCall = " + hasHoldingCall); 2749b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean newHoldState; 2750b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean holdButtonEnabled; 2751b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (hasActiveCall && !hasHoldingCall) { 2752b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // There's only one line in use, and that line is active. 275375e3711d82d0c98444f6c438437cad41d862fca6David Brown PhoneUtils.switchHoldingAndActive( 275475e3711d82d0c98444f6c438437cad41d862fca6David Brown mCM.getFirstActiveBgCall()); // Really means "hold" in this state 2755b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project newHoldState = true; 2756b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project holdButtonEnabled = true; 2757b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (!hasActiveCall && hasHoldingCall) { 2758b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // There's only one line in use, and that line is on hold. 275975e3711d82d0c98444f6c438437cad41d862fca6David Brown PhoneUtils.switchHoldingAndActive( 276075e3711d82d0c98444f6c438437cad41d862fca6David Brown mCM.getFirstActiveBgCall()); // Really means "unhold" in this state 2761b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project newHoldState = false; 2762b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project holdButtonEnabled = true; 2763b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 2764b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Either zero or 2 lines are in use; "hold/unhold" is meaningless. 2765b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project newHoldState = false; 2766b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project holdButtonEnabled = false; 2767b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 27684ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // No need to forcibly update the onscreen UI; just wait for the 27694ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // onPhoneStateChanged() callback. (This seems to be responsive 27704ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // enough.) 27715aadc2633b13d6676598dc0954be25c108d05fcdDavid Brown 27725aadc2633b13d6676598dc0954be25c108d05fcdDavid Brown // Also, any time we hold or unhold, force the DTMF dialpad to close. 2773b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa closeDialpadInternal(true); // do the "closing" animation 2774b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2775b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 27764e5e483113352e6402aaeba042116fbd9ff6f772David Brown /** 27774e5e483113352e6402aaeba042116fbd9ff6f772David Brown * Toggles in-call audio between speaker and the built-in earpiece (or 27784e5e483113352e6402aaeba042116fbd9ff6f772David Brown * wired headset.) 27794e5e483113352e6402aaeba042116fbd9ff6f772David Brown */ 27804e5e483113352e6402aaeba042116fbd9ff6f772David Brown public void toggleSpeaker() { 27812b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown // TODO: Turning on the speaker seems to enable the mic 27822b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown // whether or not the "mute" feature is active! 27832b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown // Not sure if this is an feature of the telephony API 27842b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown // that I need to handle specially, or just a bug. 27852b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown boolean newSpeakerState = !PhoneUtils.isSpeakerOn(this); 278623d416d92d99bc258a82d3e3d590783766898184David Brown log("toggleSpeaker(): newSpeakerState = " + newSpeakerState); 278723d416d92d99bc258a82d3e3d590783766898184David Brown 27882b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown if (newSpeakerState && isBluetoothAvailable() && isBluetoothAudioConnected()) { 27892b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown disconnectBluetoothAudio(); 27902b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown } 2791425b8e3c9846d5e0e76466604b35cad8856d79deEric Laurent PhoneUtils.turnOnSpeaker(this, newSpeakerState, true); 27924e5e483113352e6402aaeba042116fbd9ff6f772David Brown 27934e5e483113352e6402aaeba042116fbd9ff6f772David Brown // And update the InCallTouchUi widget (since the "audio mode" 27944e5e483113352e6402aaeba042116fbd9ff6f772David Brown // button might need to change its appearance based on the new 27954e5e483113352e6402aaeba042116fbd9ff6f772David Brown // audio state.) 27964e5e483113352e6402aaeba042116fbd9ff6f772David Brown updateInCallTouchUi(); 27972b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown } 27982b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown 2799a50e10e2efadac960987eaadc0938c6f92d3ee90John Wang /* 2800a50e10e2efadac960987eaadc0938c6f92d3ee90John Wang * onMuteClick is called only when there is a foreground call 2801a50e10e2efadac960987eaadc0938c6f92d3ee90John Wang */ 28022b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown private void onMuteClick() { 2803a50e10e2efadac960987eaadc0938c6f92d3ee90John Wang boolean newMuteState = !PhoneUtils.getMute(); 280423d416d92d99bc258a82d3e3d590783766898184David Brown log("onMuteClick(): newMuteState = " + newMuteState); 2805a50e10e2efadac960987eaadc0938c6f92d3ee90John Wang PhoneUtils.setMute(newMuteState); 28062b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown } 28072b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown 28084e5e483113352e6402aaeba042116fbd9ff6f772David Brown /** 28094e5e483113352e6402aaeba042116fbd9ff6f772David Brown * Toggles whether or not to route in-call audio to the bluetooth 28104e5e483113352e6402aaeba042116fbd9ff6f772David Brown * headset, or do nothing (but log a warning) if no bluetooth device 28114e5e483113352e6402aaeba042116fbd9ff6f772David Brown * is actually connected. 28124e5e483113352e6402aaeba042116fbd9ff6f772David Brown * 28134e5e483113352e6402aaeba042116fbd9ff6f772David Brown * TODO: this method is currently unused, but the "audio mode" UI 28144e5e483113352e6402aaeba042116fbd9ff6f772David Brown * design is still in flux so let's keep it around for now. 28154e5e483113352e6402aaeba042116fbd9ff6f772David Brown * (But if we ultimately end up *not* providing any way for the UI to 28164e5e483113352e6402aaeba042116fbd9ff6f772David Brown * simply "toggle bluetooth", we can get rid of this method.) 28174e5e483113352e6402aaeba042116fbd9ff6f772David Brown */ 28184e5e483113352e6402aaeba042116fbd9ff6f772David Brown public void toggleBluetooth() { 28194e5e483113352e6402aaeba042116fbd9ff6f772David Brown if (VDBG) log("toggleBluetooth()..."); 2820b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2821b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (isBluetoothAvailable()) { 2822b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Toggle the bluetooth audio connection state: 2823b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (isBluetoothAudioConnected()) { 2824b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project disconnectBluetoothAudio(); 2825b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 2826b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Manually turn the speaker phone off, instead of allowing the 28274ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // Bluetooth audio routing to handle it, since there's other 28284ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // important state-updating that needs to happen in the 28294ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // PhoneUtils.turnOnSpeaker() method. 28304ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // (Similarly, whenever the user turns *on* the speaker, we 28314ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // manually disconnect the active bluetooth headset; 28324e5e483113352e6402aaeba042116fbd9ff6f772David Brown // see toggleSpeaker() and/or switchInCallAudio().) 28332b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown if (PhoneUtils.isSpeakerOn(this)) { 2834425b8e3c9846d5e0e76466604b35cad8856d79deEric Laurent PhoneUtils.turnOnSpeaker(this, false, true); 2835b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2836b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2837b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project connectBluetoothAudio(); 2838b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2839b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 28404e5e483113352e6402aaeba042116fbd9ff6f772David Brown // Bluetooth isn't available; the onscreen UI shouldn't have 28414e5e483113352e6402aaeba042116fbd9ff6f772David Brown // allowed this request in the first place! 28424e5e483113352e6402aaeba042116fbd9ff6f772David Brown Log.w(LOG_TAG, "toggleBluetooth(): bluetooth is unavailable"); 2843b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 28444e5e483113352e6402aaeba042116fbd9ff6f772David Brown 28454e5e483113352e6402aaeba042116fbd9ff6f772David Brown // And update the InCallTouchUi widget (since the "audio mode" 28464e5e483113352e6402aaeba042116fbd9ff6f772David Brown // button might need to change its appearance based on the new 28474e5e483113352e6402aaeba042116fbd9ff6f772David Brown // audio state.) 28484e5e483113352e6402aaeba042116fbd9ff6f772David Brown updateInCallTouchUi(); 2849b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2850b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2851a32b63bd0040abf65b5c41d4a0e577a88dd66615David Brown /** 2852b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown * Switches the current routing of in-call audio between speaker, 285318410cf5cd54564fdcbf693ee6a4f4b5a8d479e4David Brown * bluetooth, and the built-in earpiece (or wired headset.) 2854b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown * 2855b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown * This method is used on devices that provide a single 3-way switch 2856b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown * for audio routing. For devices that provide separate toggles for 28574e5e483113352e6402aaeba042116fbd9ff6f772David Brown * Speaker and Bluetooth, see toggleBluetooth() and toggleSpeaker(). 2858b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown * 2859b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown * TODO: UI design is still in flux. If we end up totally 2860b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown * eliminating the concept of Speaker and Bluetooth toggle buttons, 28614e5e483113352e6402aaeba042116fbd9ff6f772David Brown * we can get rid of toggleBluetooth() and toggleSpeaker(). 2862b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown */ 2863b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown public void switchInCallAudio(InCallAudioMode newMode) { 286423d416d92d99bc258a82d3e3d590783766898184David Brown log("switchInCallAudio: new mode = " + newMode); 2865b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown switch (newMode) { 2866b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown case SPEAKER: 2867b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown if (!PhoneUtils.isSpeakerOn(this)) { 2868b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown // Switch away from Bluetooth, if it was active. 2869b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown if (isBluetoothAvailable() && isBluetoothAudioConnected()) { 2870b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown disconnectBluetoothAudio(); 2871b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown } 2872b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown PhoneUtils.turnOnSpeaker(this, true, true); 2873b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown } 2874b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown break; 2875b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown 2876b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown case BLUETOOTH: 2877b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown // If already connected to BT, there's nothing to do here. 2878b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown if (isBluetoothAvailable() && !isBluetoothAudioConnected()) { 2879b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown // Manually turn the speaker phone off, instead of allowing the 28804ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // Bluetooth audio routing to handle it, since there's other 28814ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // important state-updating that needs to happen in the 28824ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // PhoneUtils.turnOnSpeaker() method. 28834ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // (Similarly, whenever the user turns *on* the speaker, we 28844ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // manually disconnect the active bluetooth headset; 28854e5e483113352e6402aaeba042116fbd9ff6f772David Brown // see toggleSpeaker() and/or switchInCallAudio().) 2886b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown if (PhoneUtils.isSpeakerOn(this)) { 2887b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown PhoneUtils.turnOnSpeaker(this, false, true); 2888b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown } 2889b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown connectBluetoothAudio(); 2890b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown } 2891b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown break; 2892b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown 2893b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown case EARPIECE: 289418410cf5cd54564fdcbf693ee6a4f4b5a8d479e4David Brown // Switch to either the handset earpiece, or the wired headset (if connected.) 289518410cf5cd54564fdcbf693ee6a4f4b5a8d479e4David Brown // (Do this by simply making sure both speaker and bluetooth are off.) 2896b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown if (isBluetoothAvailable() && isBluetoothAudioConnected()) { 2897b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown disconnectBluetoothAudio(); 2898b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown } 2899b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown if (PhoneUtils.isSpeakerOn(this)) { 2900b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown PhoneUtils.turnOnSpeaker(this, false, true); 2901b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown } 2902b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown break; 2903b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown 2904b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown default: 2905b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown Log.wtf(LOG_TAG, "switchInCallAudio: unexpected mode " + newMode); 2906b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown break; 2907b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown } 29084e5e483113352e6402aaeba042116fbd9ff6f772David Brown 29094e5e483113352e6402aaeba042116fbd9ff6f772David Brown // And finally, update the InCallTouchUi widget (since the "audio 29104e5e483113352e6402aaeba042116fbd9ff6f772David Brown // mode" button might need to change its appearance based on the 29114e5e483113352e6402aaeba042116fbd9ff6f772David Brown // new audio state.) 29124e5e483113352e6402aaeba042116fbd9ff6f772David Brown updateInCallTouchUi(); 2913b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown } 2914b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown 2915b8cea05ad8f831af7fe1822e39997c8dc7e33ea6David Brown /** 2916b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa * Handle a click on the "Open/Close dialpad" button. 2917b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa * 2918b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa * @see DTMFTwelveKeyDialer#openDialer(boolean) 2919b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa * @see DTMFTwelveKeyDialer#closeDialer(boolean) 2920a32b63bd0040abf65b5c41d4a0e577a88dd66615David Brown */ 2921b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa private void onOpenCloseDialpad() { 2922b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa if (VDBG) log("onOpenCloseDialpad()..."); 29232b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown if (mDialer.isOpened()) { 2924b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa closeDialpadInternal(true); // do the "closing" animation 29252b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown } else { 2926b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa openDialpadInternal(true); // do the "opening" animation 29272b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown } 29285c594605452f1207311bfdbdd51c82907835a1e0Daisuke Miyakawa mApp.updateProximitySensorMode(mCM.getState()); 29292b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown } 29302b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown 2931b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa /** Internal wrapper around {@link DTMFTwelveKeyDialer#openDialer(boolean)} */ 2932b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa private void openDialpadInternal(boolean animate) { 2933a32b63bd0040abf65b5c41d4a0e577a88dd66615David Brown mDialer.openDialer(animate); 2934a32b63bd0040abf65b5c41d4a0e577a88dd66615David Brown // And update the InCallUiState (so that we'll restore the dialpad 2935a32b63bd0040abf65b5c41d4a0e577a88dd66615David Brown // to the correct state if we get paused/resumed). 2936a32b63bd0040abf65b5c41d4a0e577a88dd66615David Brown mApp.inCallUiState.showDialpad = true; 2937a32b63bd0040abf65b5c41d4a0e577a88dd66615David Brown } 2938a32b63bd0040abf65b5c41d4a0e577a88dd66615David Brown 2939a32b63bd0040abf65b5c41d4a0e577a88dd66615David Brown // Internal wrapper around DTMFTwelveKeyDialer.closeDialer() 2940b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa private void closeDialpadInternal(boolean animate) { 2941a32b63bd0040abf65b5c41d4a0e577a88dd66615David Brown mDialer.closeDialer(animate); 2942a32b63bd0040abf65b5c41d4a0e577a88dd66615David Brown // And update the InCallUiState (so that we'll restore the dialpad 2943a32b63bd0040abf65b5c41d4a0e577a88dd66615David Brown // to the correct state if we get paused/resumed). 2944a32b63bd0040abf65b5c41d4a0e577a88dd66615David Brown mApp.inCallUiState.showDialpad = false; 2945a32b63bd0040abf65b5c41d4a0e577a88dd66615David Brown } 2946a32b63bd0040abf65b5c41d4a0e577a88dd66615David Brown 29472b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown /** 29482b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown * Handles button clicks from the InCallTouchUi widget. 29492b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown */ 29502b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown /* package */ void handleOnscreenButtonClick(int id) { 29514a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("handleOnscreenButtonClick(id " + id + ")..."); 29522b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown 29532b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown switch (id) { 2954a1bfb5406fa20be8351e272a089c582946e86fc4David Brown // Actions while an incoming call is ringing: 29559e25b785cc7edae682144536f58080edb3a374e4David Brown case R.id.incomingCallAnswer: 29562b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown internalAnswerCall(); 29572b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown break; 29589e25b785cc7edae682144536f58080edb3a374e4David Brown case R.id.incomingCallReject: 2959717392cacea72751cbffb57b0424354b19da0868David Brown hangupRingingCall(); 29602b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown break; 29619e25b785cc7edae682144536f58080edb3a374e4David Brown case R.id.incomingCallRespondViaSms: 29629e25b785cc7edae682144536f58080edb3a374e4David Brown internalRespondViaSms(); 29639e25b785cc7edae682144536f58080edb3a374e4David Brown break; 29642b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown 29652b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown // The other regular (single-tap) buttons used while in-call: 29662b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown case R.id.holdButton: 29672b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown onHoldClick(); 29682b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown break; 2969c0005b83ea6ff24b5136fc93d807553922f00458David Brown case R.id.swapButton: 2970c0005b83ea6ff24b5136fc93d807553922f00458David Brown internalSwapCalls(); 2971c0005b83ea6ff24b5136fc93d807553922f00458David Brown break; 2972284c588c8d9a1089ba7f22725c8f52a83f267435David Brown case R.id.endButton: 29732b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown internalHangup(); 29742b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown break; 29752b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown case R.id.dialpadButton: 2976b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa onOpenCloseDialpad(); 29772b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown break; 29782b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown case R.id.muteButton: 29792b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown onMuteClick(); 29802b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown break; 2981284c588c8d9a1089ba7f22725c8f52a83f267435David Brown case R.id.addButton: 29828343169cc89621d46dce86449f5ee1ff5d3a4919John Wang PhoneUtils.startNewCall(mCM); // Fires off an ACTION_DIAL intent 298347e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown break; 2984284c588c8d9a1089ba7f22725c8f52a83f267435David Brown case R.id.mergeButton: 298539a84144262f12df44861d746788b9de92259e4fAbhishek Pillai case R.id.cdmaMergeButton: 2986b045b9344f339170d134cf814357361d96c349cfHung-ying Tyan PhoneUtils.mergeCalls(mCM); 298747e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown break; 2988507ee75639e41c17edd410ef787e0617778071aaDavid Brown case R.id.manageConferenceButton: 298947e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown // Show the Manage Conference panel. 299047e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown setInCallScreenMode(InCallScreenMode.MANAGE_CONFERENCE); 299196af4b62835c1d0d023d285b896226386621e283David Brown requestUpdateScreen(); 299247e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown break; 29932b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown 29942b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown default: 29952b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown Log.w(LOG_TAG, "handleOnscreenButtonClick: unexpected ID " + id); 29962b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown break; 29972b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown } 299847e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown 29994ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // Clicking any onscreen UI element counts as explicit "user activity". 30004ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown mApp.pokeUserActivity(); 30014ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown 30024ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // Just in case the user clicked a "stateful" UI element (like one 300347e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown // of the toggle buttons), we force the in-call buttons to update, 300447e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown // to make sure the user sees the *new* current state. 300547e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown // 30064ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // Note that some in-call buttons will *not* immediately change the 30074ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // state of the UI, namely those that send a request to the telephony 30084ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // layer (like "Hold" or "End call".) For those buttons, the 30094ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // updateInCallTouchUi() call here won't have any visible effect. 30104ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // Instead, the UI will be updated eventually when the next 30114ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // onPhoneStateChanged() event comes in and triggers an updateScreen() 30124ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // call. 301347e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown // 301447e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown // TODO: updateInCallTouchUi() is overkill here; it would be 301547e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown // more efficient to update *only* the affected button(s). 30164ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // (But this isn't a big deal since updateInCallTouchUi() is pretty 30174ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // cheap anyway...) 301847e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown updateInCallTouchUi(); 30192b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown } 30202b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown 3021b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 302275e3711d82d0c98444f6c438437cad41d862fca6David Brown * Display a status or error indication to the user according to the 302375e3711d82d0c98444f6c438437cad41d862fca6David Brown * specified InCallUiState.CallStatusCode value. 3024b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 302575e3711d82d0c98444f6c438437cad41d862fca6David Brown private void showStatusIndication(CallStatusCode status) { 30261421491ef591a2529a5c3cf278802522785044aeDavid Brown switch (status) { 302775e3711d82d0c98444f6c438437cad41d862fca6David Brown case SUCCESS: 302875e3711d82d0c98444f6c438437cad41d862fca6David Brown // The InCallScreen does not need to display any kind of error indication, 302975e3711d82d0c98444f6c438437cad41d862fca6David Brown // so we shouldn't have gotten here in the first place. 303075e3711d82d0c98444f6c438437cad41d862fca6David Brown Log.wtf(LOG_TAG, "showStatusIndication: nothing to display"); 3031b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 3032b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3033b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case POWER_OFF: 303475e3711d82d0c98444f6c438437cad41d862fca6David Brown // Radio is explictly powered off, presumably because the 303575e3711d82d0c98444f6c438437cad41d862fca6David Brown // device is in airplane mode. 303675e3711d82d0c98444f6c438437cad41d862fca6David Brown // 303775e3711d82d0c98444f6c438437cad41d862fca6David Brown // TODO: For now this UI is ultra-simple: we simply display 303875e3711d82d0c98444f6c438437cad41d862fca6David Brown // a message telling the user to turn off airplane mode. 303975e3711d82d0c98444f6c438437cad41d862fca6David Brown // But it might be nicer for the dialog to offer the option 304075e3711d82d0c98444f6c438437cad41d862fca6David Brown // to turn the radio on right there (and automatically retry 304175e3711d82d0c98444f6c438437cad41d862fca6David Brown // the call once network registration is complete.) 304275e3711d82d0c98444f6c438437cad41d862fca6David Brown showGenericErrorDialog(R.string.incall_error_power_off, 304375e3711d82d0c98444f6c438437cad41d862fca6David Brown true /* isStartupError */); 3044b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 3045b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3046b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case EMERGENCY_ONLY: 3047b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Only emergency numbers are allowed, but we tried to dial 3048b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // a non-emergency number. 30491421491ef591a2529a5c3cf278802522785044aeDavid Brown // (This state is currently unused; see comments above.) 305075e3711d82d0c98444f6c438437cad41d862fca6David Brown showGenericErrorDialog(R.string.incall_error_emergency_only, 305175e3711d82d0c98444f6c438437cad41d862fca6David Brown true /* isStartupError */); 3052b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 3053b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 30541421491ef591a2529a5c3cf278802522785044aeDavid Brown case OUT_OF_SERVICE: 30551421491ef591a2529a5c3cf278802522785044aeDavid Brown // No network connection. 305675e3711d82d0c98444f6c438437cad41d862fca6David Brown showGenericErrorDialog(R.string.incall_error_out_of_service, 305775e3711d82d0c98444f6c438437cad41d862fca6David Brown true /* isStartupError */); 3058b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 3059b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3060b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case NO_PHONE_NUMBER_SUPPLIED: 3061b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // The supplied Intent didn't contain a valid phone number. 306275e3711d82d0c98444f6c438437cad41d862fca6David Brown // (This is rare and should only ever happen with broken 306375e3711d82d0c98444f6c438437cad41d862fca6David Brown // 3rd-party apps.) For now just show a generic error. 306475e3711d82d0c98444f6c438437cad41d862fca6David Brown showGenericErrorDialog(R.string.incall_error_no_phone_number_supplied, 306575e3711d82d0c98444f6c438437cad41d862fca6David Brown true /* isStartupError */); 3066b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 3067b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3068b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case DIALED_MMI: 3069b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Our initial phone number was actually an MMI sequence. 3070b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // There's no real "error" here, but we do bring up the 3071b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // a Toast (as requested of the New UI paradigm). 3072b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 3073b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // In-call MMIs do not trigger the normal MMI Initiate 3074b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Notifications, so we should notify the user here. 3075b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Otherwise, the code in PhoneUtils.java should handle 3076b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // user notifications in the form of Toasts or Dialogs. 3077b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville if (mCM.getState() == PhoneConstants.State.OFFHOOK) { 307875e3711d82d0c98444f6c438437cad41d862fca6David Brown Toast.makeText(mApp, R.string.incall_status_dialed_mmi, Toast.LENGTH_SHORT) 307975e3711d82d0c98444f6c438437cad41d862fca6David Brown .show(); 3080b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3081b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 3082b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3083b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case CALL_FAILED: 3084b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // We couldn't successfully place the call; there was some 3085b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // failure in the telephony layer. 3086b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: Need UI spec for this failure case; for now just 3087b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // show a generic error. 308875e3711d82d0c98444f6c438437cad41d862fca6David Brown showGenericErrorDialog(R.string.incall_error_call_failed, 308975e3711d82d0c98444f6c438437cad41d862fca6David Brown true /* isStartupError */); 3090b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 3091b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 309275e3711d82d0c98444f6c438437cad41d862fca6David Brown case VOICEMAIL_NUMBER_MISSING: 309375e3711d82d0c98444f6c438437cad41d862fca6David Brown // We tried to call a voicemail: URI but the device has no 309475e3711d82d0c98444f6c438437cad41d862fca6David Brown // voicemail number configured. 309575e3711d82d0c98444f6c438437cad41d862fca6David Brown handleMissingVoiceMailNumber(); 3096b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 309775e3711d82d0c98444f6c438437cad41d862fca6David Brown 309875e3711d82d0c98444f6c438437cad41d862fca6David Brown case CDMA_CALL_LOST: 309975e3711d82d0c98444f6c438437cad41d862fca6David Brown // This status indicates that InCallScreen should display the 310075e3711d82d0c98444f6c438437cad41d862fca6David Brown // CDMA-specific "call lost" dialog. (If an outgoing call fails, 310175e3711d82d0c98444f6c438437cad41d862fca6David Brown // and the CDMA "auto-retry" feature is enabled, *and* the retried 310275e3711d82d0c98444f6c438437cad41d862fca6David Brown // call fails too, we display this specific dialog.) 310375e3711d82d0c98444f6c438437cad41d862fca6David Brown // 310475e3711d82d0c98444f6c438437cad41d862fca6David Brown // TODO: currently unused; see InCallUiState.needToShowCallLostDialog 310575e3711d82d0c98444f6c438437cad41d862fca6David Brown break; 310675e3711d82d0c98444f6c438437cad41d862fca6David Brown 310775e3711d82d0c98444f6c438437cad41d862fca6David Brown case EXITED_ECM: 310875e3711d82d0c98444f6c438437cad41d862fca6David Brown // This status indicates that InCallScreen needs to display a 310975e3711d82d0c98444f6c438437cad41d862fca6David Brown // warning that we're exiting ECM (emergency callback mode). 311075e3711d82d0c98444f6c438437cad41d862fca6David Brown showExitingECMDialog(); 311175e3711d82d0c98444f6c438437cad41d862fca6David Brown break; 311275e3711d82d0c98444f6c438437cad41d862fca6David Brown 311375e3711d82d0c98444f6c438437cad41d862fca6David Brown default: 311475e3711d82d0c98444f6c438437cad41d862fca6David Brown throw new IllegalStateException( 311575e3711d82d0c98444f6c438437cad41d862fca6David Brown "showStatusIndication: unexpected status code: " + status); 3116b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 311775e3711d82d0c98444f6c438437cad41d862fca6David Brown 311875e3711d82d0c98444f6c438437cad41d862fca6David Brown // TODO: still need to make sure that pressing OK or BACK from 311975e3711d82d0c98444f6c438437cad41d862fca6David Brown // *any* of the dialogs we launch here ends up calling 312075e3711d82d0c98444f6c438437cad41d862fca6David Brown // inCallUiState.clearPendingCallStatusCode() 312175e3711d82d0c98444f6c438437cad41d862fca6David Brown // *and* 312275e3711d82d0c98444f6c438437cad41d862fca6David Brown // make sure the Dialog handles both OK *and* cancel by calling 312375e3711d82d0c98444f6c438437cad41d862fca6David Brown // endInCallScreenSession. (See showGenericErrorDialog() for an 312475e3711d82d0c98444f6c438437cad41d862fca6David Brown // example.) 312575e3711d82d0c98444f6c438437cad41d862fca6David Brown // 312675e3711d82d0c98444f6c438437cad41d862fca6David Brown // (showGenericErrorDialog() currently does this correctly, 312775e3711d82d0c98444f6c438437cad41d862fca6David Brown // but handleMissingVoiceMailNumber() probably needs to be fixed too.) 312875e3711d82d0c98444f6c438437cad41d862fca6David Brown // 312975e3711d82d0c98444f6c438437cad41d862fca6David Brown // Also need to make sure that bailing out of any of these dialogs by 313075e3711d82d0c98444f6c438437cad41d862fca6David Brown // pressing Home clears out the pending status code too. (If you do 313175e3711d82d0c98444f6c438437cad41d862fca6David Brown // that, neither the dialog's clickListener *or* cancelListener seems 313275e3711d82d0c98444f6c438437cad41d862fca6David Brown // to run...) 3133b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3134b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3135b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 3136b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Utility function to bring up a generic "error" dialog, and then bail 3137b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * out of the in-call UI when the user hits OK (or the BACK button.) 3138b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3139b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void showGenericErrorDialog(int resid, boolean isStartupError) { 3140b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project CharSequence msg = getResources().getText(resid); 3141b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("showGenericErrorDialog('" + msg + "')..."); 3142b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3143b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // create the clicklistener and cancel listener as needed. 3144b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project DialogInterface.OnClickListener clickListener; 3145b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project OnCancelListener cancelListener; 3146b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (isStartupError) { 3147b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project clickListener = new DialogInterface.OnClickListener() { 3148b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onClick(DialogInterface dialog, int which) { 3149b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project bailOutAfterErrorDialog(); 3150b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project }}; 3151b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project cancelListener = new OnCancelListener() { 3152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onCancel(DialogInterface dialog) { 3153b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project bailOutAfterErrorDialog(); 3154b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project }}; 3155b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 3156b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project clickListener = new DialogInterface.OnClickListener() { 3157b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onClick(DialogInterface dialog, int which) { 3158b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project delayedCleanupAfterDisconnect(); 3159b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project }}; 3160b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project cancelListener = new OnCancelListener() { 3161b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onCancel(DialogInterface dialog) { 3162b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project delayedCleanupAfterDisconnect(); 3163b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project }}; 3164b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3165b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3166b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: Consider adding a setTitle() call here (with some generic 3167b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "failure" title?) 3168b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mGenericErrorDialog = new AlertDialog.Builder(this) 3169b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project .setMessage(msg) 3170b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project .setPositiveButton(R.string.ok, clickListener) 3171b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project .setOnCancelListener(cancelListener) 3172b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project .create(); 3173b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3174b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // When the dialog is up, completely hide the in-call UI 3175b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // underneath (which is in a partially-constructed state). 3176b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mGenericErrorDialog.getWindow().addFlags( 3177b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project WindowManager.LayoutParams.FLAG_DIM_BEHIND); 3178b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3179b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mGenericErrorDialog.show(); 3180b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3181b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 31821066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown private void showCallLostDialog() { 31831066df0a541fb7b6a31fe2bea8a5b2e4e3e29f1aDavid Brown if (DBG) log("showCallLostDialog()..."); 31843800ac871d6548790ac6119bb68b9be0640af261David Krause 3185c27f15ea03626351bb9499406685f3a315398803Paul Berman // Don't need to show the dialog if InCallScreen isn't in the forgeround 3186c27f15ea03626351bb9499406685f3a315398803Paul Berman if (!mIsForegroundActivity) { 3187c27f15ea03626351bb9499406685f3a315398803Paul Berman if (DBG) log("showCallLostDialog: not the foreground Activity! Bailing out..."); 3188c27f15ea03626351bb9499406685f3a315398803Paul Berman return; 3189c27f15ea03626351bb9499406685f3a315398803Paul Berman } 3190c27f15ea03626351bb9499406685f3a315398803Paul Berman 3191329dc035267d5f65f96021e26601df3f7cc57659Peng Zhu // Don't need to show the dialog again, if there is one already. 3192329dc035267d5f65f96021e26601df3f7cc57659Peng Zhu if (mCallLostDialog != null) { 3193329dc035267d5f65f96021e26601df3f7cc57659Peng Zhu if (DBG) log("showCallLostDialog: There is a mCallLostDialog already."); 3194329dc035267d5f65f96021e26601df3f7cc57659Peng Zhu return; 3195329dc035267d5f65f96021e26601df3f7cc57659Peng Zhu } 3196329dc035267d5f65f96021e26601df3f7cc57659Peng Zhu 31973800ac871d6548790ac6119bb68b9be0640af261David Krause mCallLostDialog = new AlertDialog.Builder(this) 31983800ac871d6548790ac6119bb68b9be0640af261David Krause .setMessage(R.string.call_lost) 319950480073bf2394d5b065084f46b2223ab90fb7dcDaisuke Miyakawa .setIconAttribute(android.R.attr.alertDialogIcon) 32003800ac871d6548790ac6119bb68b9be0640af261David Krause .create(); 32013800ac871d6548790ac6119bb68b9be0640af261David Krause mCallLostDialog.show(); 32023800ac871d6548790ac6119bb68b9be0640af261David Krause } 32033800ac871d6548790ac6119bb68b9be0640af261David Krause 3204a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown /** 3205a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * Displays the "Exiting ECM" warning dialog. 3206a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * 3207a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * Background: If the phone is currently in ECM (Emergency callback 3208a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * mode) and we dial a non-emergency number, that automatically 3209a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * *cancels* ECM. (That behavior comes from CdmaCallTracker.dial().) 3210a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * When that happens, we need to warn the user that they're no longer 3211a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * in ECM (bug 4207607.) 3212a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * 3213a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * So bring up a dialog explaining what's happening. There's nothing 3214a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * for the user to do, by the way; we're simply providing an 3215a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * indication that they're exiting ECM. We *could* use a Toast for 3216a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * this, but toasts are pretty easy to miss, so instead use a dialog 3217a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * with a single "OK" button. 3218a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * 3219a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * TODO: it's ugly that the code here has to make assumptions about 3220a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * the behavior of the telephony layer (namely that dialing a 3221a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * non-emergency number while in ECM causes us to exit ECM.) 3222a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * 3223a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * Instead, this warning dialog should really be triggered by our 3224a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * handler for the 3225a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED intent in 3226a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * PhoneApp.java. But that won't work until that intent also 3227a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * includes a *reason* why we're exiting ECM, since we need to 3228a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * display this dialog when exiting ECM because of an outgoing call, 3229a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * but NOT if we're exiting ECM because the user manually turned it 3230a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * off via the EmergencyCallbackModeExitDialog. 3231a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * 3232a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * Or, it might be simpler to just have outgoing non-emergency calls 3233a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * *not* cancel ECM. That way the UI wouldn't have to do anything 3234a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown * special here. 3235a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown */ 3236a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown private void showExitingECMDialog() { 3237a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown Log.i(LOG_TAG, "showExitingECMDialog()..."); 3238a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown 3239a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown if (mExitingECMDialog != null) { 3240a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown if (DBG) log("- DISMISSING mExitingECMDialog."); 3241a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown mExitingECMDialog.dismiss(); // safe even if already dismissed 3242a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown mExitingECMDialog = null; 3243a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown } 3244a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown 324575e3711d82d0c98444f6c438437cad41d862fca6David Brown // When the user dismisses the "Exiting ECM" dialog, we clear out 324675e3711d82d0c98444f6c438437cad41d862fca6David Brown // the pending call status code field (since we're done with this 324775e3711d82d0c98444f6c438437cad41d862fca6David Brown // dialog), but do *not* bail out of the InCallScreen. 324875e3711d82d0c98444f6c438437cad41d862fca6David Brown 324975e3711d82d0c98444f6c438437cad41d862fca6David Brown final InCallUiState inCallUiState = mApp.inCallUiState; 325075e3711d82d0c98444f6c438437cad41d862fca6David Brown DialogInterface.OnClickListener clickListener = new DialogInterface.OnClickListener() { 325175e3711d82d0c98444f6c438437cad41d862fca6David Brown public void onClick(DialogInterface dialog, int which) { 325275e3711d82d0c98444f6c438437cad41d862fca6David Brown inCallUiState.clearPendingCallStatusCode(); 325375e3711d82d0c98444f6c438437cad41d862fca6David Brown }}; 325475e3711d82d0c98444f6c438437cad41d862fca6David Brown OnCancelListener cancelListener = new OnCancelListener() { 325575e3711d82d0c98444f6c438437cad41d862fca6David Brown public void onCancel(DialogInterface dialog) { 325675e3711d82d0c98444f6c438437cad41d862fca6David Brown inCallUiState.clearPendingCallStatusCode(); 325775e3711d82d0c98444f6c438437cad41d862fca6David Brown }}; 325875e3711d82d0c98444f6c438437cad41d862fca6David Brown 3259a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown // Ultra-simple AlertDialog with only an OK button: 3260a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown mExitingECMDialog = new AlertDialog.Builder(this) 3261a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown .setMessage(R.string.progress_dialog_exiting_ecm) 326275e3711d82d0c98444f6c438437cad41d862fca6David Brown .setPositiveButton(R.string.ok, clickListener) 326375e3711d82d0c98444f6c438437cad41d862fca6David Brown .setOnCancelListener(cancelListener) 3264a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown .create(); 3265a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown mExitingECMDialog.getWindow().addFlags( 3266a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown WindowManager.LayoutParams.FLAG_BLUR_BEHIND); 3267a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown mExitingECMDialog.show(); 3268a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown } 3269a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown 3270b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void bailOutAfterErrorDialog() { 3271b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mGenericErrorDialog != null) { 32724a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("bailOutAfterErrorDialog: DISMISSING mGenericErrorDialog."); 3273b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mGenericErrorDialog.dismiss(); 3274b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mGenericErrorDialog = null; 3275b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 32764a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("bailOutAfterErrorDialog(): end InCallScreen session..."); 327795407b4abc7b7fcb518b6b86c2231711192b4f40David Brown 327875e3711d82d0c98444f6c438437cad41d862fca6David Brown // Now that the user has dismissed the error dialog (presumably by 327975e3711d82d0c98444f6c438437cad41d862fca6David Brown // either hitting the OK button or pressing Back, we can now reset 328075e3711d82d0c98444f6c438437cad41d862fca6David Brown // the pending call status code field. 328175e3711d82d0c98444f6c438437cad41d862fca6David Brown // 328275e3711d82d0c98444f6c438437cad41d862fca6David Brown // (Note that the pending call status is NOT cleared simply 328375e3711d82d0c98444f6c438437cad41d862fca6David Brown // by the InCallScreen being paused or finished, since the resulting 328475e3711d82d0c98444f6c438437cad41d862fca6David Brown // dialog is supposed to persist across orientation changes or if the 328575e3711d82d0c98444f6c438437cad41d862fca6David Brown // screen turns off.) 328675e3711d82d0c98444f6c438437cad41d862fca6David Brown // 328775e3711d82d0c98444f6c438437cad41d862fca6David Brown // See the "Error / diagnostic indications" section of 328875e3711d82d0c98444f6c438437cad41d862fca6David Brown // InCallUiState.java for more detailed info about the 328975e3711d82d0c98444f6c438437cad41d862fca6David Brown // pending call status code field. 329075e3711d82d0c98444f6c438437cad41d862fca6David Brown final InCallUiState inCallUiState = mApp.inCallUiState; 329175e3711d82d0c98444f6c438437cad41d862fca6David Brown inCallUiState.clearPendingCallStatusCode(); 329275e3711d82d0c98444f6c438437cad41d862fca6David Brown 329395407b4abc7b7fcb518b6b86c2231711192b4f40David Brown // Force the InCallScreen to truly finish(), rather than just 329495407b4abc7b7fcb518b6b86c2231711192b4f40David Brown // moving it to the back of the activity stack (which is what 329595407b4abc7b7fcb518b6b86c2231711192b4f40David Brown // our finish() method usually does.) 329695407b4abc7b7fcb518b6b86c2231711192b4f40David Brown // This is necessary to avoid an obscure scenario where the 329795407b4abc7b7fcb518b6b86c2231711192b4f40David Brown // InCallScreen can get stuck in an inconsistent state, somehow 329895407b4abc7b7fcb518b6b86c2231711192b4f40David Brown // causing a *subsequent* outgoing call to fail (bug 4172599). 329995407b4abc7b7fcb518b6b86c2231711192b4f40David Brown endInCallScreenSession(true /* force a real finish() call */); 3300b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3301b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3302b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 3303b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Dismisses (and nulls out) all persistent Dialogs managed 3304b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * by the InCallScreen. Useful if (a) we're about to bring up 3305b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * a dialog and want to pre-empt any currently visible dialogs, 3306b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * or (b) as a cleanup step when the Activity is going away. 3307b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3308b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void dismissAllDialogs() { 33094a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("dismissAllDialogs()..."); 3310b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3311b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Note it's safe to dismiss() a dialog that's already dismissed. 3312b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (Even if the AlertDialog object(s) below are still around, it's 3313b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // possible that the actual dialog(s) may have already been 3314b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // dismissed by the user.) 3315b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3316b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mMissingVoicemailDialog != null) { 3317796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- DISMISSING mMissingVoicemailDialog."); 3318b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mMissingVoicemailDialog.dismiss(); 3319b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mMissingVoicemailDialog = null; 3320b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3321b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mMmiStartedDialog != null) { 3322796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- DISMISSING mMmiStartedDialog."); 3323b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mMmiStartedDialog.dismiss(); 3324b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mMmiStartedDialog = null; 3325b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3326b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mGenericErrorDialog != null) { 3327796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- DISMISSING mGenericErrorDialog."); 3328b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mGenericErrorDialog.dismiss(); 3329b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mGenericErrorDialog = null; 3330b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3331b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mSuppServiceFailureDialog != null) { 3332796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- DISMISSING mSuppServiceFailureDialog."); 3333b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mSuppServiceFailureDialog.dismiss(); 3334b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mSuppServiceFailureDialog = null; 3335b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3336b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mWaitPromptDialog != null) { 3337796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- DISMISSING mWaitPromptDialog."); 3338b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWaitPromptDialog.dismiss(); 3339b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWaitPromptDialog = null; 3340b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3341b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mWildPromptDialog != null) { 3342796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- DISMISSING mWildPromptDialog."); 3343b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWildPromptDialog.dismiss(); 3344b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mWildPromptDialog = null; 3345b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 33463800ac871d6548790ac6119bb68b9be0640af261David Krause if (mCallLostDialog != null) { 33473800ac871d6548790ac6119bb68b9be0640af261David Krause if (VDBG) log("- DISMISSING mCallLostDialog."); 33483800ac871d6548790ac6119bb68b9be0640af261David Krause mCallLostDialog.dismiss(); 33493800ac871d6548790ac6119bb68b9be0640af261David Krause mCallLostDialog = null; 33503800ac871d6548790ac6119bb68b9be0640af261David Krause } 335175e3711d82d0c98444f6c438437cad41d862fca6David Brown if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL 335275e3711d82d0c98444f6c438437cad41d862fca6David Brown || mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED) 335375e3711d82d0c98444f6c438437cad41d862fca6David Brown && mApp.otaUtils != null) { 335475e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.otaUtils.dismissAllOtaDialogs(); 3355af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 335628dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal if (mPausePromptDialog != null) { 335728dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal if (DBG) log("- DISMISSING mPausePromptDialog."); 335828dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal mPausePromptDialog.dismiss(); 335928dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal mPausePromptDialog = null; 336028dce65483c7d6dfb473db013637e7ffb3f32e34Reli Tal } 3361a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown if (mExitingECMDialog != null) { 3362a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown if (DBG) log("- DISMISSING mExitingECMDialog."); 3363a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown mExitingECMDialog.dismiss(); 3364a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown mExitingECMDialog = null; 3365a2ed4429b4749131fe2e34a84713a2dffc281a91David Brown } 3366b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3367b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 33683426afaf85d33d454fad8d341a1a895fd7e21c10David Brown /** 33693426afaf85d33d454fad8d341a1a895fd7e21c10David Brown * Updates the state of the onscreen "progress indication" used in 33703426afaf85d33d454fad8d341a1a895fd7e21c10David Brown * some (relatively rare) scenarios where we need to wait for 33713426afaf85d33d454fad8d341a1a895fd7e21c10David Brown * something to happen before enabling the in-call UI. 33723426afaf85d33d454fad8d341a1a895fd7e21c10David Brown * 33733426afaf85d33d454fad8d341a1a895fd7e21c10David Brown * If necessary, this method will cause a ProgressDialog (i.e. a 33743426afaf85d33d454fad8d341a1a895fd7e21c10David Brown * spinning wait cursor) to be drawn *on top of* whatever the current 33753426afaf85d33d454fad8d341a1a895fd7e21c10David Brown * state of the in-call UI is. 33763426afaf85d33d454fad8d341a1a895fd7e21c10David Brown * 33773426afaf85d33d454fad8d341a1a895fd7e21c10David Brown * @see InCallUiState.ProgressIndicationType 33783426afaf85d33d454fad8d341a1a895fd7e21c10David Brown */ 33793426afaf85d33d454fad8d341a1a895fd7e21c10David Brown private void updateProgressIndication() { 33803426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // If an incoming call is ringing, that takes priority over any 33813426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // possible value of inCallUiState.progressIndication. 33823426afaf85d33d454fad8d341a1a895fd7e21c10David Brown if (mCM.hasActiveRingingCall()) { 33833426afaf85d33d454fad8d341a1a895fd7e21c10David Brown dismissProgressIndication(); 33843426afaf85d33d454fad8d341a1a895fd7e21c10David Brown return; 33853426afaf85d33d454fad8d341a1a895fd7e21c10David Brown } 33863426afaf85d33d454fad8d341a1a895fd7e21c10David Brown 33873426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // Otherwise, put up a progress indication if indicated by the 33883426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // inCallUiState.progressIndication field. 33893426afaf85d33d454fad8d341a1a895fd7e21c10David Brown final InCallUiState inCallUiState = mApp.inCallUiState; 33903426afaf85d33d454fad8d341a1a895fd7e21c10David Brown switch (inCallUiState.getProgressIndication()) { 33913426afaf85d33d454fad8d341a1a895fd7e21c10David Brown case NONE: 33923426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // No progress indication necessary, so make sure it's dismissed. 33933426afaf85d33d454fad8d341a1a895fd7e21c10David Brown dismissProgressIndication(); 33943426afaf85d33d454fad8d341a1a895fd7e21c10David Brown break; 33953426afaf85d33d454fad8d341a1a895fd7e21c10David Brown 33963426afaf85d33d454fad8d341a1a895fd7e21c10David Brown case TURNING_ON_RADIO: 33973426afaf85d33d454fad8d341a1a895fd7e21c10David Brown showProgressIndication( 33983426afaf85d33d454fad8d341a1a895fd7e21c10David Brown R.string.emergency_enable_radio_dialog_title, 33993426afaf85d33d454fad8d341a1a895fd7e21c10David Brown R.string.emergency_enable_radio_dialog_message); 34003426afaf85d33d454fad8d341a1a895fd7e21c10David Brown break; 34013426afaf85d33d454fad8d341a1a895fd7e21c10David Brown 34023426afaf85d33d454fad8d341a1a895fd7e21c10David Brown case RETRYING: 34033426afaf85d33d454fad8d341a1a895fd7e21c10David Brown showProgressIndication( 34043426afaf85d33d454fad8d341a1a895fd7e21c10David Brown R.string.emergency_enable_radio_dialog_title, 34053426afaf85d33d454fad8d341a1a895fd7e21c10David Brown R.string.emergency_enable_radio_dialog_retry); 34063426afaf85d33d454fad8d341a1a895fd7e21c10David Brown break; 34073426afaf85d33d454fad8d341a1a895fd7e21c10David Brown 34083426afaf85d33d454fad8d341a1a895fd7e21c10David Brown default: 34093426afaf85d33d454fad8d341a1a895fd7e21c10David Brown Log.wtf(LOG_TAG, "updateProgressIndication: unexpected value: " 34103426afaf85d33d454fad8d341a1a895fd7e21c10David Brown + inCallUiState.getProgressIndication()); 34113426afaf85d33d454fad8d341a1a895fd7e21c10David Brown dismissProgressIndication(); 34123426afaf85d33d454fad8d341a1a895fd7e21c10David Brown break; 34133426afaf85d33d454fad8d341a1a895fd7e21c10David Brown } 34143426afaf85d33d454fad8d341a1a895fd7e21c10David Brown } 34153426afaf85d33d454fad8d341a1a895fd7e21c10David Brown 34163426afaf85d33d454fad8d341a1a895fd7e21c10David Brown /** 34173426afaf85d33d454fad8d341a1a895fd7e21c10David Brown * Show an onscreen "progress indication" with the specified title and message. 34183426afaf85d33d454fad8d341a1a895fd7e21c10David Brown */ 34193426afaf85d33d454fad8d341a1a895fd7e21c10David Brown private void showProgressIndication(int titleResId, int messageResId) { 34203426afaf85d33d454fad8d341a1a895fd7e21c10David Brown if (DBG) log("showProgressIndication(message " + messageResId + ")..."); 34213426afaf85d33d454fad8d341a1a895fd7e21c10David Brown 34223426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // TODO: make this be a no-op if the progress indication is 34233426afaf85d33d454fad8d341a1a895fd7e21c10David Brown // already visible with the exact same title and message. 34243426afaf85d33d454fad8d341a1a895fd7e21c10David Brown 34253426afaf85d33d454fad8d341a1a895fd7e21c10David Brown dismissProgressIndication(); // Clean up any prior progress indication 34263426afaf85d33d454fad8d341a1a895fd7e21c10David Brown mProgressDialog = new ProgressDialog(this); 34273426afaf85d33d454fad8d341a1a895fd7e21c10David Brown mProgressDialog.setTitle(getText(titleResId)); 34283426afaf85d33d454fad8d341a1a895fd7e21c10David Brown mProgressDialog.setMessage(getText(messageResId)); 34293426afaf85d33d454fad8d341a1a895fd7e21c10David Brown mProgressDialog.setIndeterminate(true); 34303426afaf85d33d454fad8d341a1a895fd7e21c10David Brown mProgressDialog.setCancelable(false); 34313426afaf85d33d454fad8d341a1a895fd7e21c10David Brown mProgressDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG); 34323426afaf85d33d454fad8d341a1a895fd7e21c10David Brown mProgressDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND); 34333426afaf85d33d454fad8d341a1a895fd7e21c10David Brown mProgressDialog.show(); 34343426afaf85d33d454fad8d341a1a895fd7e21c10David Brown } 34353426afaf85d33d454fad8d341a1a895fd7e21c10David Brown 34363426afaf85d33d454fad8d341a1a895fd7e21c10David Brown /** 34373426afaf85d33d454fad8d341a1a895fd7e21c10David Brown * Dismiss the onscreen "progress indication" (if present). 34383426afaf85d33d454fad8d341a1a895fd7e21c10David Brown */ 34393426afaf85d33d454fad8d341a1a895fd7e21c10David Brown private void dismissProgressIndication() { 34403426afaf85d33d454fad8d341a1a895fd7e21c10David Brown if (DBG) log("dismissProgressIndication()..."); 34413426afaf85d33d454fad8d341a1a895fd7e21c10David Brown if (mProgressDialog != null) { 34423426afaf85d33d454fad8d341a1a895fd7e21c10David Brown mProgressDialog.dismiss(); // safe even if already dismissed 34433426afaf85d33d454fad8d341a1a895fd7e21c10David Brown mProgressDialog = null; 34443426afaf85d33d454fad8d341a1a895fd7e21c10David Brown } 34453426afaf85d33d454fad8d341a1a895fd7e21c10David Brown } 34463426afaf85d33d454fad8d341a1a895fd7e21c10David Brown 3447b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3448b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 3449b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Helper functions for answering incoming calls. 3450b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 3451b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3452b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 34534d910f9df60b820d3461995c1d85d0581041b531David Brown * Answer a ringing call. This method does nothing if there's no 34544d910f9df60b820d3461995c1d85d0581041b531David Brown * ringing or waiting call. 3455b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 34569e25b785cc7edae682144536f58080edb3a374e4David Brown private void internalAnswerCall() { 34572a5f795c4602bf519235a875b6a4003965642dddDaisuke Miyakawa if (DBG) log("internalAnswerCall()..."); 3458b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if (DBG) PhoneUtils.dumpCallState(mPhone); 34594d910f9df60b820d3461995c1d85d0581041b531David Brown 3460c97fea097483c6e58c199e857b279ec92e64d8e3John Wang final boolean hasRingingCall = mCM.hasActiveRingingCall(); 34614d910f9df60b820d3461995c1d85d0581041b531David Brown 34624d910f9df60b820d3461995c1d85d0581041b531David Brown if (hasRingingCall) { 34638343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Phone phone = mCM.getRingingPhone(); 34648343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Call ringing = mCM.getFirstActiveRingingCall(); 34658343169cc89621d46dce86449f5ee1ff5d3a4919John Wang int phoneType = phone.getPhoneType(); 3466b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { 34671e8a3579f8e49fd1f1a078d6be6864a6a8bac306David Brown if (DBG) log("internalAnswerCall: answering (CDMA)..."); 34688eb9d0a1337e930d373692d6730ef5b67a706c94John Wang if (mCM.hasActiveFgCall() 3469b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville && mCM.getFgPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_SIP) { 34708eb9d0a1337e930d373692d6730ef5b67a706c94John Wang // The incoming call is CDMA call and the ongoing 34718eb9d0a1337e930d373692d6730ef5b67a706c94John Wang // call is a SIP call. The CDMA network does not 34728eb9d0a1337e930d373692d6730ef5b67a706c94John Wang // support holding an active call, so there's no 34738eb9d0a1337e930d373692d6730ef5b67a706c94John Wang // way to swap between a CDMA call and a SIP call. 34748eb9d0a1337e930d373692d6730ef5b67a706c94John Wang // So for now, we just don't allow a CDMA call and 34758eb9d0a1337e930d373692d6730ef5b67a706c94John Wang // a SIP call to be active at the same time.We'll 34768eb9d0a1337e930d373692d6730ef5b67a706c94John Wang // "answer incoming, end ongoing" in this case. 34778eb9d0a1337e930d373692d6730ef5b67a706c94John Wang if (DBG) log("internalAnswerCall: answer " 34788eb9d0a1337e930d373692d6730ef5b67a706c94John Wang + "CDMA incoming and end SIP ongoing"); 34798eb9d0a1337e930d373692d6730ef5b67a706c94John Wang PhoneUtils.answerAndEndActive(mCM, ringing); 34808eb9d0a1337e930d373692d6730ef5b67a706c94John Wang } else { 34818eb9d0a1337e930d373692d6730ef5b67a706c94John Wang PhoneUtils.answerCall(ringing); 34828eb9d0a1337e930d373692d6730ef5b67a706c94John Wang } 3483b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville } else if (phoneType == PhoneConstants.PHONE_TYPE_SIP) { 34848eb9d0a1337e930d373692d6730ef5b67a706c94John Wang if (DBG) log("internalAnswerCall: answering (SIP)..."); 34858eb9d0a1337e930d373692d6730ef5b67a706c94John Wang if (mCM.hasActiveFgCall() 3486b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville && mCM.getFgPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 34878eb9d0a1337e930d373692d6730ef5b67a706c94John Wang // Similar to the PHONE_TYPE_CDMA handling. 34888eb9d0a1337e930d373692d6730ef5b67a706c94John Wang // The incoming call is SIP call and the ongoing 34898eb9d0a1337e930d373692d6730ef5b67a706c94John Wang // call is a CDMA call. The CDMA network does not 34908eb9d0a1337e930d373692d6730ef5b67a706c94John Wang // support holding an active call, so there's no 34918eb9d0a1337e930d373692d6730ef5b67a706c94John Wang // way to swap between a CDMA call and a SIP call. 34928eb9d0a1337e930d373692d6730ef5b67a706c94John Wang // So for now, we just don't allow a CDMA call and 34938eb9d0a1337e930d373692d6730ef5b67a706c94John Wang // a SIP call to be active at the same time.We'll 34948eb9d0a1337e930d373692d6730ef5b67a706c94John Wang // "answer incoming, end ongoing" in this case. 34958eb9d0a1337e930d373692d6730ef5b67a706c94John Wang if (DBG) log("internalAnswerCall: answer " 34968eb9d0a1337e930d373692d6730ef5b67a706c94John Wang + "SIP incoming and end CDMA ongoing"); 34978eb9d0a1337e930d373692d6730ef5b67a706c94John Wang PhoneUtils.answerAndEndActive(mCM, ringing); 34988eb9d0a1337e930d373692d6730ef5b67a706c94John Wang } else { 34998eb9d0a1337e930d373692d6730ef5b67a706c94John Wang PhoneUtils.answerCall(ringing); 35008eb9d0a1337e930d373692d6730ef5b67a706c94John Wang } 3501b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) { 35022a5f795c4602bf519235a875b6a4003965642dddDaisuke Miyakawa if (DBG) log("internalAnswerCall: answering (GSM)..."); 35034d910f9df60b820d3461995c1d85d0581041b531David Brown // GSM: this is usually just a wrapper around 35044d910f9df60b820d3461995c1d85d0581041b531David Brown // PhoneUtils.answerCall(), *but* we also need to do 35054d910f9df60b820d3461995c1d85d0581041b531David Brown // something special for the "both lines in use" case. 35064d910f9df60b820d3461995c1d85d0581041b531David Brown 3507c97fea097483c6e58c199e857b279ec92e64d8e3John Wang final boolean hasActiveCall = mCM.hasActiveFgCall(); 3508c97fea097483c6e58c199e857b279ec92e64d8e3John Wang final boolean hasHoldingCall = mCM.hasActiveBgCall(); 35094d910f9df60b820d3461995c1d85d0581041b531David Brown 35104d910f9df60b820d3461995c1d85d0581041b531David Brown if (hasActiveCall && hasHoldingCall) { 35114d910f9df60b820d3461995c1d85d0581041b531David Brown if (DBG) log("internalAnswerCall: answering (both lines in use!)..."); 35124d910f9df60b820d3461995c1d85d0581041b531David Brown // The relatively rare case where both lines are 35134d910f9df60b820d3461995c1d85d0581041b531David Brown // already in use. We "answer incoming, end ongoing" 35144d910f9df60b820d3461995c1d85d0581041b531David Brown // in this case, according to the current UI spec. 35158343169cc89621d46dce86449f5ee1ff5d3a4919John Wang PhoneUtils.answerAndEndActive(mCM, ringing); 35164d910f9df60b820d3461995c1d85d0581041b531David Brown 35174d910f9df60b820d3461995c1d85d0581041b531David Brown // Alternatively, we could use 35188343169cc89621d46dce86449f5ee1ff5d3a4919John Wang // PhoneUtils.answerAndEndHolding(mPhone); 35194d910f9df60b820d3461995c1d85d0581041b531David Brown // here to end the on-hold call instead. 35204d910f9df60b820d3461995c1d85d0581041b531David Brown } else { 35214d910f9df60b820d3461995c1d85d0581041b531David Brown if (DBG) log("internalAnswerCall: answering..."); 35228343169cc89621d46dce86449f5ee1ff5d3a4919John Wang PhoneUtils.answerCall(ringing); // Automatically holds the current active call, 35234d910f9df60b820d3461995c1d85d0581041b531David Brown // if there is one 35244d910f9df60b820d3461995c1d85d0581041b531David Brown } 352579b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } else { 352679b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink throw new IllegalStateException("Unexpected phone type: " + phoneType); 35274d910f9df60b820d3461995c1d85d0581041b531David Brown } 35286734941af0f8874ca584a363ef3a8febe41b397dDaisuke Miyakawa 35296734941af0f8874ca584a363ef3a8febe41b397dDaisuke Miyakawa // Call origin is valid only with outgoing calls. Disable it on incoming calls. 35306734941af0f8874ca584a363ef3a8febe41b397dDaisuke Miyakawa mApp.setLatestActiveCallOrigin(null); 3531c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman } 3532b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3533b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3534b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 3535b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Hang up the ringing call (aka "Don't answer"). 3536b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3537717392cacea72751cbffb57b0424354b19da0868David Brown /* package */ void hangupRingingCall() { 3538717392cacea72751cbffb57b0424354b19da0868David Brown if (DBG) log("hangupRingingCall()..."); 35398343169cc89621d46dce86449f5ee1ff5d3a4919John Wang if (VDBG) PhoneUtils.dumpCallManager(); 35408343169cc89621d46dce86449f5ee1ff5d3a4919John Wang // In the rare case when multiple calls are ringing, the UI policy 35419e25b785cc7edae682144536f58080edb3a374e4David Brown // it to always act on the first ringing call. 35428343169cc89621d46dce86449f5ee1ff5d3a4919John Wang PhoneUtils.hangupRingingCall(mCM.getFirstActiveRingingCall()); 3543b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3544b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3545b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 35469e25b785cc7edae682144536f58080edb3a374e4David Brown * Silence the ringer (if an incoming call is ringing.) 35479e25b785cc7edae682144536f58080edb3a374e4David Brown */ 35489e25b785cc7edae682144536f58080edb3a374e4David Brown private void internalSilenceRinger() { 35499e25b785cc7edae682144536f58080edb3a374e4David Brown if (DBG) log("internalSilenceRinger()..."); 35509e25b785cc7edae682144536f58080edb3a374e4David Brown final CallNotifier notifier = mApp.notifier; 35519e25b785cc7edae682144536f58080edb3a374e4David Brown if (notifier.isRinging()) { 35529e25b785cc7edae682144536f58080edb3a374e4David Brown // ringer is actually playing, so silence it. 35539e25b785cc7edae682144536f58080edb3a374e4David Brown notifier.silenceRinger(); 35549e25b785cc7edae682144536f58080edb3a374e4David Brown } 35559e25b785cc7edae682144536f58080edb3a374e4David Brown } 35569e25b785cc7edae682144536f58080edb3a374e4David Brown 35579e25b785cc7edae682144536f58080edb3a374e4David Brown /** 35589e25b785cc7edae682144536f58080edb3a374e4David Brown * Respond via SMS to the ringing call. 3559524486403a387c324dee5aff7fb78ca784d15255David Brown * @see RespondViaSmsManager 35609e25b785cc7edae682144536f58080edb3a374e4David Brown */ 35619e25b785cc7edae682144536f58080edb3a374e4David Brown private void internalRespondViaSms() { 356223d416d92d99bc258a82d3e3d590783766898184David Brown log("internalRespondViaSms()..."); 35639e25b785cc7edae682144536f58080edb3a374e4David Brown if (VDBG) PhoneUtils.dumpCallManager(); 35649e25b785cc7edae682144536f58080edb3a374e4David Brown 35659e25b785cc7edae682144536f58080edb3a374e4David Brown // In the rare case when multiple calls are ringing, the UI policy 35669e25b785cc7edae682144536f58080edb3a374e4David Brown // it to always act on the first ringing call. 35679e25b785cc7edae682144536f58080edb3a374e4David Brown Call ringingCall = mCM.getFirstActiveRingingCall(); 35689e25b785cc7edae682144536f58080edb3a374e4David Brown 3569524486403a387c324dee5aff7fb78ca784d15255David Brown mRespondViaSmsManager.showRespondViaSmsPopup(ringingCall); 35709e25b785cc7edae682144536f58080edb3a374e4David Brown 3571fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown // Silence the ringer, since it would be distracting while you're trying 3572fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown // to pick a response. (Note that we'll restart the ringer if you bail 3573507ee75639e41c17edd410ef787e0617778071aaDavid Brown // out of the popup, though; see RespondViaSmsCancelListener.) 35749e25b785cc7edae682144536f58080edb3a374e4David Brown internalSilenceRinger(); 35759e25b785cc7edae682144536f58080edb3a374e4David Brown } 35769e25b785cc7edae682144536f58080edb3a374e4David Brown 35779e25b785cc7edae682144536f58080edb3a374e4David Brown /** 35784d910f9df60b820d3461995c1d85d0581041b531David Brown * Hang up the current active call. 35794d910f9df60b820d3461995c1d85d0581041b531David Brown */ 35809e25b785cc7edae682144536f58080edb3a374e4David Brown private void internalHangup() { 3581b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville PhoneConstants.State state = mCM.getState(); 35823bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown log("internalHangup()... phone state = " + state); 35833bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown 35843bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // Regardless of the phone state, issue a hangup request. 35853bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // (If the phone is already idle, this call will presumably have no 35863bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // effect (but also see the note below.)) 35878343169cc89621d46dce86449f5ee1ff5d3a4919John Wang PhoneUtils.hangup(mCM); 35883bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown 35893bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // If the user just hung up the only active call, we'll eventually exit 35903bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // the in-call UI after the following sequence: 35913bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // - When the hangup() succeeds, we'll get a DISCONNECT event from 35923bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // the telephony layer (see onDisconnect()). 35933bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // - We immediately switch to the "Call ended" state (see the "delayed 35943bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // bailout" code path in onDisconnect()) and also post a delayed 35953bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // DELAYED_CLEANUP_AFTER_DISCONNECT message. 35963bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // - When the DELAYED_CLEANUP_AFTER_DISCONNECT message comes in (see 35973bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // delayedCleanupAfterDisconnect()) we do some final cleanup, and exit 35983bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // this activity unless the phone is still in use (i.e. if there's 35993bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // another call, or something else going on like an active MMI 36003bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // sequence.) 36013bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown 3602b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville if (state == PhoneConstants.State.IDLE) { 36033bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // The user asked us to hang up, but the phone was (already) idle! 36043bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown Log.w(LOG_TAG, "internalHangup(): phone is already IDLE!"); 36053bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown 36063bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // This is rare, but can happen in a few cases: 36073bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // (a) If the user quickly double-taps the "End" button. In this case 36083bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // we'll see that 2nd press event during the brief "Call ended" 36093bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // state (where the phone is IDLE), or possibly even before the 36103bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // radio has been able to respond to the initial hangup request. 36113bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // (b) More rarely, this can happen if the user presses "End" at the 36123bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // exact moment that the call ends on its own (like because of the 36133bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // other person hanging up.) 36143bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // (c) Finally, this could also happen if we somehow get stuck here on 36153bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // the InCallScreen with the phone truly idle, perhaps due to a 36163bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // bug where we somehow *didn't* exit when the phone became idle 36173bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // in the first place. 36183bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown 36193bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // TODO: as a "safety valve" for case (c), consider immediately 36203bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // bailing out of the in-call UI right here. (The user can always 36213bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // bail out by pressing Home, of course, but they'll probably try 36223bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // pressing End first.) 36233bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // 36243bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // Log.i(LOG_TAG, "internalHangup(): phone is already IDLE! Bailing out..."); 36253bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown // endInCallScreenSession(); 36263bb74765a9dcfd981637234505ab5a40f3be4f9eDavid Brown } 36274d910f9df60b820d3461995c1d85d0581041b531David Brown } 36284d910f9df60b820d3461995c1d85d0581041b531David Brown 36294d910f9df60b820d3461995c1d85d0581041b531David Brown /** 3630b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * InCallScreen-specific wrapper around PhoneUtils.switchHoldingAndActive(). 3631b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3632b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void internalSwapCalls() { 36334a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("internalSwapCalls()..."); 3634b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3635b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Any time we swap calls, force the DTMF dialpad to close. 3636b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (We want the regular in-call UI to be visible right now, so the 3637b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // user can clearly see which call is now in the foreground.) 3638b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa closeDialpadInternal(true); // do the "closing" animation 3639b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3640b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Also, clear out the "history" of DTMF digits you typed, to make 3641b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // sure you don't see digits from call #1 while call #2 is active. 3642b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (Yes, this does mean that swapping calls twice will cause you 3643b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // to lose any previous digits from the current call; see the TODO 3644b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // comment on DTMFTwelvKeyDialer.clearDigits() for more info.) 3645b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mDialer.clearDigits(); 3646b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3647b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Swap the fg and bg calls. 36488343169cc89621d46dce86449f5ee1ff5d3a4919John Wang // In the future we may provides some way for user to choose among 36498343169cc89621d46dce86449f5ee1ff5d3a4919John Wang // multiple background calls, for now, always act on the first background calll. 36508343169cc89621d46dce86449f5ee1ff5d3a4919John Wang PhoneUtils.switchHoldingAndActive(mCM.getFirstActiveBgCall()); 3651c9d9ed30aa547b79b81adc13a4d148a003b6ee62w 365259d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie // If we have a valid BluetoothPhoneService then since CDMA network or 3653c9d9ed30aa547b79b81adc13a4d148a003b6ee62w // Telephony FW does not send us information on which caller got swapped 365459d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie // we need to update the second call active state in BluetoothPhoneService internally 3655b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville if (mCM.getBgPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 365659d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie IBluetoothHeadsetPhone btPhone = mApp.getBluetoothPhoneService(); 365759d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie if (btPhone != null) { 365859d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie try { 365959d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie btPhone.cdmaSwapSecondCallState(); 366059d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie } catch (RemoteException e) { 366159d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie Log.e(LOG_TAG, Log.getStackTraceString(new Throwable())); 366259d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie } 366359d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie } 3664c9d9ed30aa547b79b81adc13a4d148a003b6ee62w } 3665c9d9ed30aa547b79b81adc13a4d148a003b6ee62w 3666b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3667b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3668b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 3669b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Sets the current high-level "mode" of the in-call UI. 3670b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 3671b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * NOTE: if newMode is CALL_ENDED, the caller is responsible for 3672b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * posting a delayed DELAYED_CLEANUP_AFTER_DISCONNECT message, to make 3673b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * sure the "call ended" state goes away after a couple of seconds. 367496af4b62835c1d0d023d285b896226386621e283David Brown * 367596af4b62835c1d0d023d285b896226386621e283David Brown * Note this method does NOT refresh of the onscreen UI; the caller is 367696af4b62835c1d0d023d285b896226386621e283David Brown * responsible for calling updateScreen() or requestUpdateScreen() if 367796af4b62835c1d0d023d285b896226386621e283David Brown * necessary. 3678b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3679b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void setInCallScreenMode(InCallScreenMode newMode) { 36805c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville if (DBG) log("setInCallScreenMode: " + newMode); 368175e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.inCallUiState.inCallScreenMode = newMode; 3682b154630235935e1aab2a41eff9ed794d40084a02David Brown 368375e3711d82d0c98444f6c438437cad41d862fca6David Brown switch (newMode) { 3684b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case MANAGE_CONFERENCE: 3685c97fea097483c6e58c199e857b279ec92e64d8e3John Wang if (!PhoneUtils.isConferenceCall(mCM.getActiveFgCall())) { 3686b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Log.w(LOG_TAG, "MANAGE_CONFERENCE: no active conference call!"); 3687b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Hide the Manage Conference panel, return to NORMAL mode. 3688b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project setInCallScreenMode(InCallScreenMode.NORMAL); 3689b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 3690b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3691c97fea097483c6e58c199e857b279ec92e64d8e3John Wang List<Connection> connections = mCM.getFgCallConnections(); 3692b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // There almost certainly will be > 1 connection, 3693b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // since isConferenceCall() just returned true. 3694b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if ((connections == null) || (connections.size() <= 1)) { 3695b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Log.w(LOG_TAG, 3696b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project "MANAGE_CONFERENCE: Bogus TRUE from isConferenceCall(); connections = " 3697b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project + connections); 3698b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Hide the Manage Conference panel, return to NORMAL mode. 3699b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project setInCallScreenMode(InCallScreenMode.NORMAL); 3700b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 3701b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3702b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 37037b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown // TODO: Don't do this here. The call to 37047b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown // initManageConferencePanel() should instead happen 37057b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown // automagically in ManageConferenceUtils the very first 37067b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown // time you call updateManageConferencePanel() or 37077b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown // setPanelVisible(true). 37087b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown mManageConferenceUtils.initManageConferencePanel(); // if necessary 37097b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown 37107b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown mManageConferenceUtils.updateManageConferencePanel(connections); 3711b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3712b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // The "Manage conference" UI takes up the full main frame, 37130d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa // replacing the CallCard PopupWindow. 37147b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown mManageConferenceUtils.setPanelVisible(true); 3715b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 37167b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown // Start the chronometer. 37177b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown // TODO: Similarly, we shouldn't expose startConferenceTime() 37187b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown // and stopConferenceTime(); the ManageConferenceUtils 37197b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown // class ought to manage the conferenceTime widget itself 37207b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown // based on setPanelVisible() calls. 3721c97fea097483c6e58c199e857b279ec92e64d8e3John Wang 3722c97fea097483c6e58c199e857b279ec92e64d8e3John Wang // Note: there is active Fg call since we are in conference call 372375e3711d82d0c98444f6c438437cad41d862fca6David Brown long callDuration = 372475e3711d82d0c98444f6c438437cad41d862fca6David Brown mCM.getActiveFgCall().getEarliestConnection().getDurationMillis(); 37257b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown mManageConferenceUtils.startConferenceTime( 37267b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown SystemClock.elapsedRealtime() - callDuration); 3727b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3728dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // No need to close the dialer here, since the Manage 3729dfa83d531cdb88513f09e913424b7a16628b37d3David Brown // Conference UI will just cover it up anyway. 3730b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3731b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 3732b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3733b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case CALL_ENDED: 3734b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case NORMAL: 37357b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown mManageConferenceUtils.setPanelVisible(false); 37367b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown mManageConferenceUtils.stopConferenceTime(); 3737b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 3738af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville 3739af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville case OTA_NORMAL: 374075e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.otaUtils.setCdmaOtaInCallScreenUiState( 3741f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville OtaUtils.CdmaOtaInCallScreenUiState.State.NORMAL); 3742f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville break; 3743f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville 3744af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville case OTA_ENDED: 374575e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.otaUtils.setCdmaOtaInCallScreenUiState( 3746f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville OtaUtils.CdmaOtaInCallScreenUiState.State.ENDED); 3747af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville break; 3748f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville 3749f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville case UNDEFINED: 37505c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // Set our Activities intent to ACTION_UNDEFINED so 37515c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // that if we get resumed after we've completed a call 37525c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // the next call will not cause checkIsOtaCall to 37535c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // return true. 37545c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // 3755211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // TODO(OTASP): update these comments 3756211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // 37575c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // With the framework as of October 2009 the sequence below 37585c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // causes the framework to call onResume, onPause, onNewIntent, 37595c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // onResume. If we don't call setIntent below then when the 3760211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // first onResume calls checkIsOtaCall via checkOtaspStateOnResume it will 37615c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // return true and the Activity will be confused. 37625c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // 37635c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // 1) Power up Phone A 37645c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // 2) Place *22899 call and activate Phone A 37655c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // 3) Press the power key on Phone A to turn off the display 37665c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // 4) Call Phone A from Phone B answering Phone A 37675c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // 5) The screen will be blank (Should be normal InCallScreen) 37685c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // 6) Hang up the Phone B 37695c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // 7) Phone A displays the activation screen. 37705c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // 37715c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // Step 3 is the critical step to cause the onResume, onPause 37725c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // onNewIntent, onResume sequence. If step 3 is skipped the 37735c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // sequence will be onNewIntent, onResume and all will be well. 37745c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville setIntent(new Intent(ACTION_UNDEFINED)); 37755c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville 37765c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // Cleanup Ota Screen if necessary and set the panel 37775c0517ae3c17505ffd466be79ab0026b7fe6c959Wink Saville // to VISIBLE. 3778b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville if (mCM.getState() != PhoneConstants.State.OFFHOOK) { 377975e3711d82d0c98444f6c438437cad41d862fca6David Brown if (mApp.otaUtils != null) { 378075e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.otaUtils.cleanOtaScreen(true); 37814a5a966f0d43e04d336be1b94182346399a931f6Wink Saville } 37824a5a966f0d43e04d336be1b94182346399a931f6Wink Saville } else { 37834a5a966f0d43e04d336be1b94182346399a931f6Wink Saville log("WARNING: Setting mode to UNDEFINED but phone is OFFHOOK," 37844a5a966f0d43e04d336be1b94182346399a931f6Wink Saville + " skip cleanOtaScreen."); 3785ebe745f3277139eced2bce8425b4e2694355e1eaWink Saville } 3786f6eb7893215a875863e1e0200e4aa3174137f76cWink Saville break; 3787b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3788b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3789b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3790b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 3791b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * @return true if the "Manage conference" UI is currently visible. 3792b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3793b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /* package */ boolean isManageConferenceMode() { 379475e3711d82d0c98444f6c438437cad41d862fca6David Brown return (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.MANAGE_CONFERENCE); 3795b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3796b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3797b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 3798b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Checks if the "Manage conference" UI needs to be updated. 3799b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * If the state of the current conference call has changed 3800b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * since our previous call to updateManageConferencePanel()), 38017b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown * do a fresh update. Also, if the current call is no longer a 38027b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown * conference call at all, bail out of the "Manage conference" UI and 38037b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown * return to InCallScreenMode.NORMAL mode. 3804b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3805b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void updateManageConferencePanelIfNecessary() { 3806c97fea097483c6e58c199e857b279ec92e64d8e3John Wang if (VDBG) log("updateManageConferencePanelIfNecessary: " + mCM.getActiveFgCall() + "..."); 3807b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3808c97fea097483c6e58c199e857b279ec92e64d8e3John Wang List<Connection> connections = mCM.getFgCallConnections(); 3809b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (connections == null) { 3810796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("==> no connections on foreground call!"); 3811b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Hide the Manage Conference panel, return to NORMAL mode. 3812b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project setInCallScreenMode(InCallScreenMode.NORMAL); 381375e3711d82d0c98444f6c438437cad41d862fca6David Brown SyncWithPhoneStateStatus status = syncWithPhoneState(); 381475e3711d82d0c98444f6c438437cad41d862fca6David Brown if (status != SyncWithPhoneStateStatus.SUCCESS) { 3815b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Log.w(LOG_TAG, "- syncWithPhoneState failed! status = " + status); 3816b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // We shouldn't even be in the in-call UI in the first 3817b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // place, so bail out: 38184a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("updateManageConferencePanelIfNecessary: endInCallScreenSession... 1"); 38194a5a966f0d43e04d336be1b94182346399a931f6Wink Saville endInCallScreenSession(); 3820b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 3821b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3822b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 3823b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3824b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3825b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int numConnections = connections.size(); 3826b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (numConnections <= 1) { 3827796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("==> foreground call no longer a conference!"); 3828b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Hide the Manage Conference panel, return to NORMAL mode. 3829b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project setInCallScreenMode(InCallScreenMode.NORMAL); 383075e3711d82d0c98444f6c438437cad41d862fca6David Brown SyncWithPhoneStateStatus status = syncWithPhoneState(); 383175e3711d82d0c98444f6c438437cad41d862fca6David Brown if (status != SyncWithPhoneStateStatus.SUCCESS) { 3832b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Log.w(LOG_TAG, "- syncWithPhoneState failed! status = " + status); 3833b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // We shouldn't even be in the in-call UI in the first 3834b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // place, so bail out: 38354a5a966f0d43e04d336be1b94182346399a931f6Wink Saville if (DBG) log("updateManageConferencePanelIfNecessary: endInCallScreenSession... 2"); 38364a5a966f0d43e04d336be1b94182346399a931f6Wink Saville endInCallScreenSession(); 3837b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 3838b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3839b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 3840b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3841b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 38427b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown // TODO: the test to see if numConnections has changed can go in 38437b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown // updateManageConferencePanel(), rather than here. 38447b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown if (numConnections != mManageConferenceUtils.getNumCallersInConference()) { 38457b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown if (VDBG) log("==> Conference size has changed; need to rebuild UI!"); 38467b50e05c9e6a2e75b5f34b8de1866702351d1ffbDavid Brown mManageConferenceUtils.updateManageConferencePanel(connections); 3847b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3848b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3849b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3850b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 38510d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa * Updates {@link #mCallCard}'s visibility state per DTMF dialpad visibility. They 3852b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa * cannot be shown simultaneously and thus we should reflect DTMF dialpad visibility into 3853b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa * another. 3854b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa * 3855b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa * Note: During OTA calls or users' managing conference calls, we should *not* call this method 3856b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa * but manually manage both visibility. 3857b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa * 3858b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa * @see #updateScreen() 3859b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 38600d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa private void updateCallCardVisibilityPerDialerState(boolean animate) { 38610d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa // We need to hide the CallCard while the dialpad is visible. 38624ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown if (isDialerOpened()) { 3863b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa if (VDBG) { 38640d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa log("- updateCallCardVisibilityPerDialerState(animate=" 38650d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa + animate + "): dialpad open, hide mCallCard..."); 3866b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa } 3867b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa if (animate) { 38680f3a4bfe3a9a3aed224a9c89b82c986cd12c3fe8Daisuke Miyakawa AnimationUtils.Fade.hide(mCallCard, View.GONE); 3869b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa } else { 38700d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa mCallCard.setVisibility(View.GONE); 3871b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa } 38724ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown } else { 3873b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa // Dialpad is dismissed; bring back the CallCard if it's supposed to be visible. 38744ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.NORMAL) 38754ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown || (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.CALL_ENDED)) { 3876b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa if (VDBG) { 38770d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa log("- updateCallCardVisibilityPerDialerState(animate=" 38780d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa + animate + "): dialpad dismissed, show mCallCard..."); 3879b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa } 3880b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa if (animate) { 38810f3a4bfe3a9a3aed224a9c89b82c986cd12c3fe8Daisuke Miyakawa AnimationUtils.Fade.show(mCallCard); 3882b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa } else { 38830d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa mCallCard.setVisibility(View.VISIBLE); 3884b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa } 38855aadc2633b13d6676598dc0954be25c108d05fcdDavid Brown } 38868df5c508da2c836b841ee24120fa7c5cc92df387David Brown } 3887b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3888b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3889b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 3890b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa * @see DTMFTwelveKeyDialer#isOpened() 3891b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3892b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /* package */ boolean isDialerOpened() { 3893b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return (mDialer != null && mDialer.isOpened()); 3894b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3895b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3896b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 3897b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Called any time the DTMF dialpad is opened. 3898b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa * @see DTMFTwelveKeyDialer#openDialer(boolean) 3899b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3900b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa /* package */ void onDialerOpen(boolean animate) { 39010f68bb19e2cca0bb7f70e2fcf16e0747a0036885David Brown if (DBG) log("onDialerOpen()..."); 3902b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 39034ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // Update the in-call touch UI. 39042b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown updateInCallTouchUi(); 39052b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown 39060d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa // Update CallCard UI, which depends on the dialpad. 39070d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa updateCallCardVisibilityPerDialerState(animate); 39085aadc2633b13d6676598dc0954be25c108d05fcdDavid Brown 39094472ce7a7e8568b4bb66098c4e4a2e71099167acDavid Brown // This counts as explicit "user activity". 391075e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.pokeUserActivity(); 39115aadc2633b13d6676598dc0954be25c108d05fcdDavid Brown 3912af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville //If on OTA Call, hide OTA Screen 39135aadc2633b13d6676598dc0954be25c108d05fcdDavid Brown // TODO: This may not be necessary, now that the dialpad is 39145aadc2633b13d6676598dc0954be25c108d05fcdDavid Brown // always visible in OTA mode. 391575e3711d82d0c98444f6c438437cad41d862fca6David Brown if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL 391675e3711d82d0c98444f6c438437cad41d862fca6David Brown || mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED) 391775e3711d82d0c98444f6c438437cad41d862fca6David Brown && mApp.otaUtils != null) { 391875e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.otaUtils.hideOtaScreen(); 3919af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 3920b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3921b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3922b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 3923b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Called any time the DTMF dialpad is closed. 3924b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa * @see DTMFTwelveKeyDialer#closeDialer(boolean) 3925b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3926b4fa896f7737117d5a6ee8a533a4c8f88f0c4953Daisuke Miyakawa /* package */ void onDialerClose(boolean animate) { 39270f68bb19e2cca0bb7f70e2fcf16e0747a0036885David Brown if (DBG) log("onDialerClose()..."); 3928b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 39291aa6bc13039b66997380c4c9664b70d5cea1af73David Brown // OTA-specific cleanup upon closing the dialpad. 393075e3711d82d0c98444f6c438437cad41d862fca6David Brown if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL) 393175e3711d82d0c98444f6c438437cad41d862fca6David Brown || (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED) 393275e3711d82d0c98444f6c438437cad41d862fca6David Brown || ((mApp.cdmaOtaScreenState != null) 393375e3711d82d0c98444f6c438437cad41d862fca6David Brown && (mApp.cdmaOtaScreenState.otaScreenState == 39341aa6bc13039b66997380c4c9664b70d5cea1af73David Brown CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION))) { 393575e3711d82d0c98444f6c438437cad41d862fca6David Brown if (mApp.otaUtils != null) { 393675e3711d82d0c98444f6c438437cad41d862fca6David Brown mApp.otaUtils.otaShowProperScreen(); 3937af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 3938af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 39391aa6bc13039b66997380c4c9664b70d5cea1af73David Brown 39404ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // Update the in-call touch UI. 39412b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown updateInCallTouchUi(); 39422b7613e21b0bea57cfa4e5ba5860a8ff1cfefbc1David Brown 39430d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa // Update CallCard UI, which depends on the dialpad. 39440d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa updateCallCardVisibilityPerDialerState(animate); 39450f68bb19e2cca0bb7f70e2fcf16e0747a0036885David Brown 39464472ce7a7e8568b4bb66098c4e4a2e71099167acDavid Brown // This counts as explicit "user activity". 39474ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown mApp.pokeUserActivity(); 3948b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3949b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3950b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 3951b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Determines when we can dial DTMF tones. 3952b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3953eab6549d1725b487f07114d08a73dfe2c1f8daa9Daisuke Miyakawa /* package */ boolean okToDialDTMFTones() { 3954c97fea097483c6e58c199e857b279ec92e64d8e3John Wang final boolean hasRingingCall = mCM.hasActiveRingingCall(); 3955c97fea097483c6e58c199e857b279ec92e64d8e3John Wang final Call.State fgCallState = mCM.getActiveFgCallState(); 3956b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3957b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // We're allowed to send DTMF tones when there's an ACTIVE 3958b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // foreground call, and not when an incoming call is ringing 3959b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (since DTMF tones are useless in that state), or if the 3960b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Manage Conference UI is visible (since the tab interferes 3961b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // with the "Back to call" button.) 3962b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3963b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // We can also dial while in ALERTING state because there are 3964b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // some connections that never update to an ACTIVE state (no 3965b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // indication from the network). 3966b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean canDial = 3967b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project (fgCallState == Call.State.ACTIVE || fgCallState == Call.State.ALERTING) 3968b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project && !hasRingingCall 396975e3711d82d0c98444f6c438437cad41d862fca6David Brown && (mApp.inCallUiState.inCallScreenMode != InCallScreenMode.MANAGE_CONFERENCE); 3970b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3971796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log ("[okToDialDTMFTones] foreground state: " + fgCallState + 3972b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ", ringing state: " + hasRingingCall + 397375e3711d82d0c98444f6c438437cad41d862fca6David Brown ", call screen mode: " + mApp.inCallUiState.inCallScreenMode + 3974b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ", result: " + canDial); 3975b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3976b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return canDial; 3977b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3978b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3979b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 3980b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * @return true if the in-call DTMF dialpad should be available to the 3981b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * user, given the current state of the phone and the in-call UI. 39824ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown * (This is used to control the enabledness of the "Show 39834ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown * dialpad" onscreen button; see InCallControlState.dialpadEnabled.) 3984b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3985b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /* package */ boolean okToShowDialpad() { 3986eab6549d1725b487f07114d08a73dfe2c1f8daa9Daisuke Miyakawa // Very similar to okToDialDTMFTones(), but allow DIALING here. 3987eab6549d1725b487f07114d08a73dfe2c1f8daa9Daisuke Miyakawa final Call.State fgCallState = mCM.getActiveFgCallState(); 3988eab6549d1725b487f07114d08a73dfe2c1f8daa9Daisuke Miyakawa return okToDialDTMFTones() || (fgCallState == Call.State.DIALING); 3989b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3990b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3991419426e206b3d8e76ebd4e3a19d8e5cddbdff658David Brown /** 39924d910f9df60b820d3461995c1d85d0581041b531David Brown * Initializes the in-call touch UI on devices that need it. 3993419426e206b3d8e76ebd4e3a19d8e5cddbdff658David Brown */ 39944d910f9df60b820d3461995c1d85d0581041b531David Brown private void initInCallTouchUi() { 39954d910f9df60b820d3461995c1d85d0581041b531David Brown if (DBG) log("initInCallTouchUi()..."); 39964d910f9df60b820d3461995c1d85d0581041b531David Brown // TODO: we currently use the InCallTouchUi widget in at least 39974d910f9df60b820d3461995c1d85d0581041b531David Brown // some states on ALL platforms. But if some devices ultimately 39984d910f9df60b820d3461995c1d85d0581041b531David Brown // end up not using *any* onscreen touch UI, we should make sure 39994d910f9df60b820d3461995c1d85d0581041b531David Brown // to not even inflate the InCallTouchUi widget on those devices. 40004d910f9df60b820d3461995c1d85d0581041b531David Brown mInCallTouchUi = (InCallTouchUi) findViewById(R.id.inCallTouchUi); 40014d910f9df60b820d3461995c1d85d0581041b531David Brown mInCallTouchUi.setInCallScreenInstance(this); 4002524486403a387c324dee5aff7fb78ca784d15255David Brown 4003524486403a387c324dee5aff7fb78ca784d15255David Brown // RespondViaSmsManager implements the "Respond via SMS" 4004524486403a387c324dee5aff7fb78ca784d15255David Brown // feature that's triggered from the incoming call widget. 4005524486403a387c324dee5aff7fb78ca784d15255David Brown mRespondViaSmsManager = new RespondViaSmsManager(); 4006524486403a387c324dee5aff7fb78ca784d15255David Brown mRespondViaSmsManager.setInCallScreenInstance(this); 4007419426e206b3d8e76ebd4e3a19d8e5cddbdff658David Brown } 4008419426e206b3d8e76ebd4e3a19d8e5cddbdff658David Brown 4009419426e206b3d8e76ebd4e3a19d8e5cddbdff658David Brown /** 40104d910f9df60b820d3461995c1d85d0581041b531David Brown * Updates the state of the in-call touch UI. 4011419426e206b3d8e76ebd4e3a19d8e5cddbdff658David Brown */ 40124d910f9df60b820d3461995c1d85d0581041b531David Brown private void updateInCallTouchUi() { 40134d910f9df60b820d3461995c1d85d0581041b531David Brown if (mInCallTouchUi != null) { 40148343169cc89621d46dce86449f5ee1ff5d3a4919John Wang mInCallTouchUi.updateState(mCM); 4015419426e206b3d8e76ebd4e3a19d8e5cddbdff658David Brown } 4016419426e206b3d8e76ebd4e3a19d8e5cddbdff658David Brown } 4017419426e206b3d8e76ebd4e3a19d8e5cddbdff658David Brown 4018b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 4019507ee75639e41c17edd410ef787e0617778071aaDavid Brown * @return the InCallTouchUi widget 4020507ee75639e41c17edd410ef787e0617778071aaDavid Brown */ 4021507ee75639e41c17edd410ef787e0617778071aaDavid Brown /* package */ InCallTouchUi getInCallTouchUi() { 4022507ee75639e41c17edd410ef787e0617778071aaDavid Brown return mInCallTouchUi; 4023507ee75639e41c17edd410ef787e0617778071aaDavid Brown } 4024507ee75639e41c17edd410ef787e0617778071aaDavid Brown 4025507ee75639e41c17edd410ef787e0617778071aaDavid Brown /** 402675e3711d82d0c98444f6c438437cad41d862fca6David Brown * Posts a handler message telling the InCallScreen to refresh the 402775e3711d82d0c98444f6c438437cad41d862fca6David Brown * onscreen in-call UI. 4028325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown * 402975e3711d82d0c98444f6c438437cad41d862fca6David Brown * This is just a wrapper around updateScreen(), for use by the 4030325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown * rest of the phone app or from a thread other than the UI thread. 403175e3711d82d0c98444f6c438437cad41d862fca6David Brown * 403275e3711d82d0c98444f6c438437cad41d862fca6David Brown * updateScreen() is a no-op if the InCallScreen is not the foreground 403375e3711d82d0c98444f6c438437cad41d862fca6David Brown * activity, so it's safe to call this whether or not the InCallScreen 403475e3711d82d0c98444f6c438437cad41d862fca6David Brown * is currently visible. 4035b8df8173e1a0ea8ba89cea984176216201c4d5e7Paul Berman */ 403675e3711d82d0c98444f6c438437cad41d862fca6David Brown /* package */ void requestUpdateScreen() { 403775e3711d82d0c98444f6c438437cad41d862fca6David Brown if (DBG) log("requestUpdateScreen()..."); 403875e3711d82d0c98444f6c438437cad41d862fca6David Brown mHandler.removeMessages(REQUEST_UPDATE_SCREEN); 403975e3711d82d0c98444f6c438437cad41d862fca6David Brown mHandler.sendEmptyMessage(REQUEST_UPDATE_SCREEN); 4040b8df8173e1a0ea8ba89cea984176216201c4d5e7Paul Berman } 4041b8df8173e1a0ea8ba89cea984176216201c4d5e7Paul Berman 4042b8df8173e1a0ea8ba89cea984176216201c4d5e7Paul Berman /** 4043b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * @return true if we're in restricted / emergency dialing only mode. 4044b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 4045b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public boolean isPhoneStateRestricted() { 4046b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: This needs to work IN TANDEM with the KeyGuardViewMediator Code. 4047b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Right now, it looks like the mInputRestricted flag is INTERNAL to the 4048b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // KeyGuardViewMediator and SPECIFICALLY set to be FALSE while the emergency 4049b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // phone call is being made, to allow for input into the InCallScreen. 4050b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Having the InCallScreen judge the state of the device from this flag 4051b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // becomes meaningless since it is always false for us. The mediator should 4052b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // have an additional API to let this app know that it should be restricted. 40538343169cc89621d46dce86449f5ee1ff5d3a4919John Wang int serviceState = mCM.getServiceState(); 40548343169cc89621d46dce86449f5ee1ff5d3a4919John Wang return ((serviceState == ServiceState.STATE_EMERGENCY_ONLY) || 40558343169cc89621d46dce86449f5ee1ff5d3a4919John Wang (serviceState == ServiceState.STATE_OUT_OF_SERVICE) || 405675e3711d82d0c98444f6c438437cad41d862fca6David Brown (mApp.getKeyguardManager().inKeyguardRestrictedInputMode())); 4057b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 4058b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 4059b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 4060b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 4061b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Bluetooth helper methods. 4062b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 4063cec56587c1d3c90014848d7adfe817bef9c325eaNick Pelly // - BluetoothAdapter is the Bluetooth system service. If 4064cec56587c1d3c90014848d7adfe817bef9c325eaNick Pelly // getDefaultAdapter() returns null 4065b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // then the device is not BT capable. Use BluetoothDevice.isEnabled() 4066b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // to see if BT is enabled on the device. 4067b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 4068b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // - BluetoothHeadset is the API for the control connection to a 4069b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Bluetooth Headset. This lets you completely connect/disconnect a 4070b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // headset (which we don't do from the Phone UI!) but also lets you 4071b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // get the address of the currently active headset and see whether 4072b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // it's currently connected. 4073b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 4074b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 4075b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * @return true if the Bluetooth on/off switch in the UI should be 4076b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * available to the user (i.e. if the device is BT-capable 4077b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * and a headset is connected.) 4078b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 4079b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /* package */ boolean isBluetoothAvailable() { 4080796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("isBluetoothAvailable()..."); 4081b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 4082b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // There's no need to ask the Bluetooth system service if BT is enabled: 4083b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 4084cec56587c1d3c90014848d7adfe817bef9c325eaNick Pelly // BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 4085db065e9834bcad9b0cb16c272b4b272dee8bdf62Nick Pelly // if ((adapter == null) || !adapter.isEnabled()) { 4086b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if (DBG) log(" ==> FALSE (BT not enabled)"); 4087b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // return false; 4088b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // } 4089db065e9834bcad9b0cb16c272b4b272dee8bdf62Nick Pelly // if (DBG) log(" - BT enabled! device name " + adapter.getName() 4090db065e9834bcad9b0cb16c272b4b272dee8bdf62Nick Pelly // + ", address " + adapter.getAddress()); 4091b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 4092b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // ...since we already have a BluetoothHeadset instance. We can just 4093b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // call isConnected() on that, and assume it'll be false if BT isn't 4094b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // enabled at all. 4095b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 4096b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Check if there's a connected headset, using the BluetoothHeadset API. 4097b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean isConnected = false; 4098b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mBluetoothHeadset != null) { 40997893303ffaf4c2e1dee13fb7cf06525502c03ba1Jaikumar Ganesh List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices(); 41001d417d7ede71bbcf72a7edebf528efbfcf9b82bbJaikumar Ganesh 41017893303ffaf4c2e1dee13fb7cf06525502c03ba1Jaikumar Ganesh if (deviceList.size() > 0) { 41027893303ffaf4c2e1dee13fb7cf06525502c03ba1Jaikumar Ganesh BluetoothDevice device = deviceList.get(0); 41031d417d7ede71bbcf72a7edebf528efbfcf9b82bbJaikumar Ganesh isConnected = true; 41041d417d7ede71bbcf72a7edebf528efbfcf9b82bbJaikumar Ganesh 41051d417d7ede71bbcf72a7edebf528efbfcf9b82bbJaikumar Ganesh if (VDBG) log(" - headset state = " + 41067893303ffaf4c2e1dee13fb7cf06525502c03ba1Jaikumar Ganesh mBluetoothHeadset.getConnectionState(device)); 41077893303ffaf4c2e1dee13fb7cf06525502c03ba1Jaikumar Ganesh if (VDBG) log(" - headset address: " + device); 4108796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log(" - isConnected: " + isConnected); 4109b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 4110b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 4111b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 4112796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log(" ==> " + isConnected); 4113b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return isConnected; 4114b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 4115b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 4116b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 411759d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie * @return true if a BT Headset is available, and its audio is currently connected. 4118b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 4119b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /* package */ boolean isBluetoothAudioConnected() { 412002d680e702821997b17f09b68946255e42d57bbbJaikumar Ganesh if (mBluetoothHeadset == null) { 412102d680e702821997b17f09b68946255e42d57bbbJaikumar Ganesh if (VDBG) log("isBluetoothAudioConnected: ==> FALSE (null mBluetoothHeadset)"); 4122b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return false; 4123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 412459d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices(); 412559d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie 412659d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie if (deviceList.isEmpty()) { 412759d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie return false; 412859d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie } 412959d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie BluetoothDevice device = deviceList.get(0); 413059d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie boolean isAudioOn = mBluetoothHeadset.isAudioConnected(device); 4131796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("isBluetoothAudioConnected: ==> isAudioOn = " + isAudioOn); 4132b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return isAudioOn; 4133b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 4134b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 4135b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 41364ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown * Helper method used to control the onscreen "Bluetooth" indication; 41374ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown * see InCallControlState.bluetoothIndicatorOn. 4138b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 4139b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * @return true if a BT device is available and its audio is currently connected, 414059d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie * <b>or</b> if we issued a BluetoothHeadset.connectAudio() 4141b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * call within the last 5 seconds (which presumably means 4142b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * that the BT audio connection is currently being set 4143b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * up, and will be connected soon.) 4144b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 4145b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /* package */ boolean isBluetoothAudioConnectedOrPending() { 4146b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (isBluetoothAudioConnected()) { 4147796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("isBluetoothAudioConnectedOrPending: ==> TRUE (really connected)"); 4148b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 4149b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 4150b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 415159d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie // If we issued a connectAudio() call "recently enough", even 4152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if BT isn't actually connected yet, let's still pretend BT is 41534ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // on. This makes the onscreen indication more responsive. 4154b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mBluetoothConnectionPending) { 4155b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project long timeSinceRequest = 4156b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project SystemClock.elapsedRealtime() - mBluetoothConnectionRequestTime; 4157b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (timeSinceRequest < 5000 /* 5 seconds */) { 4158796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("isBluetoothAudioConnectedOrPending: ==> TRUE (requested " 4159b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project + timeSinceRequest + " msec ago)"); 4160b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 4161b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 4162796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("isBluetoothAudioConnectedOrPending: ==> FALSE (request too old: " 4163b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project + timeSinceRequest + " msec ago)"); 4164b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mBluetoothConnectionPending = false; 4165b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return false; 4166b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 4167b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 4168b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 4169796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("isBluetoothAudioConnectedOrPending: ==> FALSE"); 4170b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return false; 4171b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 4172b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 41738bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project /** 41748bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project * Posts a message to our handler saying to update the onscreen UI 41758bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project * based on a bluetooth headset state change. 41768bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project */ 4177325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown /* package */ void requestUpdateBluetoothIndication() { 4178325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown if (VDBG) log("requestUpdateBluetoothIndication()..."); 41798bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // No need to look at the current state here; any UI elements that 41808bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // care about the bluetooth state (i.e. the CallCard) get 41818bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // the necessary state directly from PhoneApp.showBluetoothIndication(). 4182325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown mHandler.removeMessages(REQUEST_UPDATE_BLUETOOTH_INDICATION); 4183325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown mHandler.sendEmptyMessage(REQUEST_UPDATE_BLUETOOTH_INDICATION); 41848bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project } 41858bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project 41868bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project private void dumpBluetoothState() { 41878bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project log("============== dumpBluetoothState() ============="); 41888bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project log("= isBluetoothAvailable: " + isBluetoothAvailable()); 41898bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project log("= isBluetoothAudioConnected: " + isBluetoothAudioConnected()); 41908bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project log("= isBluetoothAudioConnectedOrPending: " + isBluetoothAudioConnectedOrPending()); 41918bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project log("= PhoneApp.showBluetoothIndication: " 419275e3711d82d0c98444f6c438437cad41d862fca6David Brown + mApp.showBluetoothIndication()); 41938bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project log("="); 419459d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie if (mBluetoothAdapter != null) { 41958bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project if (mBluetoothHeadset != null) { 41967893303ffaf4c2e1dee13fb7cf06525502c03ba1Jaikumar Ganesh List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices(); 41971d417d7ede71bbcf72a7edebf528efbfcf9b82bbJaikumar Ganesh 41987893303ffaf4c2e1dee13fb7cf06525502c03ba1Jaikumar Ganesh if (deviceList.size() > 0) { 41997893303ffaf4c2e1dee13fb7cf06525502c03ba1Jaikumar Ganesh BluetoothDevice device = deviceList.get(0); 42007893303ffaf4c2e1dee13fb7cf06525502c03ba1Jaikumar Ganesh log("= BluetoothHeadset.getCurrentDevice: " + device); 42011d417d7ede71bbcf72a7edebf528efbfcf9b82bbJaikumar Ganesh log("= BluetoothHeadset.State: " 42027893303ffaf4c2e1dee13fb7cf06525502c03ba1Jaikumar Ganesh + mBluetoothHeadset.getConnectionState(device)); 420359d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie log("= BluetoothHeadset audio connected: " + 420459d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie mBluetoothHeadset.isAudioConnected(device)); 42058bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project } 42068bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project } else { 42078bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project log("= mBluetoothHeadset is null"); 42088bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project } 42098bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project } else { 421059d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie log("= mBluetoothAdapter is null; device is not BT capable"); 42118bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project } 42128bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project } 42138bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project 4214b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /* package */ void connectBluetoothAudio() { 4215796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("connectBluetoothAudio()..."); 421602d680e702821997b17f09b68946255e42d57bbbJaikumar Ganesh if (mBluetoothHeadset != null) { 421759d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie // TODO(BT) check return 421859d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie mBluetoothHeadset.connectAudio(); 4219b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 4220b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 4221b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Watch out: The bluetooth connection doesn't happen instantly; 422259d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie // the connectAudio() call returns instantly but does its real 42234ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // work in another thread. The mBluetoothConnectionPending flag 42244ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // is just a little trickery to ensure that the onscreen UI updates 42254ba332e62c4d54b2623ccdc59fafd46ecba08cf0David Brown // instantly. (See isBluetoothAudioConnectedOrPending() above.) 4226b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mBluetoothConnectionPending = true; 4227b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mBluetoothConnectionRequestTime = SystemClock.elapsedRealtime(); 4228b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 4229b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 4230b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /* package */ void disconnectBluetoothAudio() { 4231796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("disconnectBluetoothAudio()..."); 423202d680e702821997b17f09b68946255e42d57bbbJaikumar Ganesh if (mBluetoothHeadset != null) { 423359d39bc3d1f3930550dc572172e144831ac91c31Matthew Xie mBluetoothHeadset.disconnectAudio(); 4234b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 4235b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mBluetoothConnectionPending = false; 4236b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 4237b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 4238325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown /** 4239325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown * Posts a handler message telling the InCallScreen to close 4240325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown * the OTA failure notice after the specified delay. 4241325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown * @see OtaUtils.otaShowProgramFailureNotice 4242325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown */ 4243325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown /* package */ void requestCloseOtaFailureNotice(long timeout) { 4244325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown if (DBG) log("requestCloseOtaFailureNotice() with timeout: " + timeout); 4245325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown mHandler.sendEmptyMessageDelayed(REQUEST_CLOSE_OTA_FAILURE_NOTICE, timeout); 4246325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown 4247325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown // TODO: we probably ought to call removeMessages() for this 4248325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown // message code in either onPause or onResume, just to be 100% 4249325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown // sure that the message we just posted has no way to affect a 4250325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown // *different* call if the user quickly backs out and restarts. 4251325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown // (This is also true for requestCloseSpcErrorNotice() below, and 4252325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown // probably anywhere else we use mHandler.sendEmptyMessageDelayed().) 4253325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown } 4254325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown 4255325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown /** 4256325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown * Posts a handler message telling the InCallScreen to close 4257325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown * the SPC error notice after the specified delay. 4258325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown * @see OtaUtils.otaShowSpcErrorNotice 4259325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown */ 4260325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown /* package */ void requestCloseSpcErrorNotice(long timeout) { 4261325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown if (DBG) log("requestCloseSpcErrorNotice() with timeout: " + timeout); 4262325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown mHandler.sendEmptyMessageDelayed(REQUEST_CLOSE_SPC_ERROR_NOTICE, timeout); 4263af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 4264af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville 4265af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville public boolean isOtaCallInActiveState() { 426675e3711d82d0c98444f6c438437cad41d862fca6David Brown if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL) 426775e3711d82d0c98444f6c438437cad41d862fca6David Brown || ((mApp.cdmaOtaScreenState != null) 426875e3711d82d0c98444f6c438437cad41d862fca6David Brown && (mApp.cdmaOtaScreenState.otaScreenState == 42691aa6bc13039b66997380c4c9664b70d5cea1af73David Brown CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION))) { 4270af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville return true; 4271af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } else { 4272af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville return false; 4273af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 4274af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 4275af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville 4276af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville /** 4277af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * Handle OTA Call End scenario when display becomes dark during OTA Call 4278af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * and InCallScreen is in pause mode. CallNotifier will listen for call 4279af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * end indication and call this api to handle OTA Call end scenario 4280af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville */ 4281af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville public void handleOtaCallEnd() { 4282af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville if (DBG) log("handleOtaCallEnd entering"); 428375e3711d82d0c98444f6c438437cad41d862fca6David Brown if (((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL) 428475e3711d82d0c98444f6c438437cad41d862fca6David Brown || ((mApp.cdmaOtaScreenState != null) 428575e3711d82d0c98444f6c438437cad41d862fca6David Brown && (mApp.cdmaOtaScreenState.otaScreenState != 42866bdc4d568f008ca476c744d52056dde3e8db27f8Abhishek Pillai CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED))) 428775e3711d82d0c98444f6c438437cad41d862fca6David Brown && ((mApp.cdmaOtaProvisionData != null) 428875e3711d82d0c98444f6c438437cad41d862fca6David Brown && (!mApp.cdmaOtaProvisionData.inOtaSpcState))) { 4289af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville if (DBG) log("handleOtaCallEnd - Set OTA Call End stater"); 4290af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville setInCallScreenMode(InCallScreenMode.OTA_ENDED); 4291af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville updateScreen(); 4292af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 4293af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 4294af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville 4295af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville public boolean isOtaCallInEndState() { 429675e3711d82d0c98444f6c438437cad41d862fca6David Brown return (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED); 4297af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 4298af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville 4299af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville 4300211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown /** 4301211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown * Upon resuming the in-call UI, check to see if an OTASP call is in 4302211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown * progress, and if so enable the special OTASP-specific UI. 4303211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown * 4304211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown * TODO: have a simple single flag in InCallUiState for this rather than 4305211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown * needing to know about all those mApp.cdma*State objects. 4306211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown * 4307211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown * @return true if any OTASP-related UI is active 4308211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown */ 4309211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown private boolean checkOtaspStateOnResume() { 4310211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // If there's no OtaUtils instance, that means we haven't even tried 4311211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // to start an OTASP call (yet), so there's definitely nothing to do here. 4312211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown if (mApp.otaUtils == null) { 4313211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown if (DBG) log("checkOtaspStateOnResume: no OtaUtils instance; nothing to do."); 4314af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville return false; 4315af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 4316af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville 4317211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown if ((mApp.cdmaOtaScreenState == null) || (mApp.cdmaOtaProvisionData == null)) { 4318211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // Uh oh -- something wrong with our internal OTASP state. 4319211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // (Since this is an OTASP-capable device, these objects 4320211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // *should* have already been created by PhoneApp.onCreate().) 4321211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown throw new IllegalStateException("checkOtaspStateOnResume: " 4322211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown + "app.cdmaOta* objects(s) not initialized"); 432374cfc64ffd6c8b96e8bc39c602af720ac7c3f0f9David Brown } 432474cfc64ffd6c8b96e8bc39c602af720ac7c3f0f9David Brown 4325211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // The PhoneApp.cdmaOtaInCallScreenUiState instance is the 4326211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // authoritative source saying whether or not the in-call UI should 4327211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // show its OTASP-related UI. 4328af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville 4329211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown OtaUtils.CdmaOtaInCallScreenUiState.State cdmaOtaInCallScreenState = 4330211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown mApp.otaUtils.getCdmaOtaInCallScreenUiState(); 4331211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // These states are: 4332211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // - UNDEFINED: no OTASP-related UI is visible 4333211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // - NORMAL: OTASP call in progress, so show in-progress OTASP UI 4334211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // - ENDED: OTASP call just ended, so show success/failure indication 4335211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown 4336211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown boolean otaspUiActive = 4337211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown (cdmaOtaInCallScreenState == OtaUtils.CdmaOtaInCallScreenUiState.State.NORMAL) 4338211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown || (cdmaOtaInCallScreenState == OtaUtils.CdmaOtaInCallScreenUiState.State.ENDED); 4339211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown 4340211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown if (otaspUiActive) { 4341211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // Make sure the OtaUtils instance knows about the InCallScreen's 4342211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // OTASP-related UI widgets. 434375e3711d82d0c98444f6c438437cad41d862fca6David Brown // 4344211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // (This call has no effect if the UI widgets have already been set up. 4345211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // It only really matters the very first time that the InCallScreen instance 4346211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // is onResume()d after starting an OTASP call.) 43470d5fc92288847d393d3237503da362c8beb77194Daisuke Miyakawa mApp.otaUtils.updateUiWidgets(this, mInCallTouchUi, mCallCard); 4348211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown 4349211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // Also update the InCallScreenMode based on the cdmaOtaInCallScreenState. 4350211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown 4351211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown if (cdmaOtaInCallScreenState == OtaUtils.CdmaOtaInCallScreenUiState.State.NORMAL) { 4352211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown if (DBG) log("checkOtaspStateOnResume - in OTA Normal mode"); 4353211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown setInCallScreenMode(InCallScreenMode.OTA_NORMAL); 4354211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown } else if (cdmaOtaInCallScreenState == 4355211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown OtaUtils.CdmaOtaInCallScreenUiState.State.ENDED) { 4356211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown if (DBG) log("checkOtaspStateOnResume - in OTA END mode"); 4357211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown setInCallScreenMode(InCallScreenMode.OTA_ENDED); 4358af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 4359af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville 4360211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // TODO(OTASP): we might also need to go into OTA_ENDED mode 4361211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // in one extra case: 4362211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // 4363211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // else if (mApp.cdmaOtaScreenState.otaScreenState == 4364211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG) { 4365211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // if (DBG) log("checkOtaspStateOnResume - set OTA END Mode"); 4366211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // setInCallScreenMode(InCallScreenMode.OTA_ENDED); 4367211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // } 43689d3a3d147a543ec23113fa59732f9f73ba28386fWink Saville 4369211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown } else { 4370211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // OTASP is not active; reset to regular in-call UI. 437179b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink 4372211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown if (DBG) log("checkOtaspStateOnResume - Set OTA NORMAL Mode"); 4373211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown setInCallScreenMode(InCallScreenMode.OTA_NORMAL); 437479b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink 4375211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown if (mApp.otaUtils != null) { 4376211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown mApp.otaUtils.cleanOtaScreen(false); 437779b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } 437879b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } 4379211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown 4380211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // TODO(OTASP): 4381211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // The original check from checkIsOtaCall() when handling ACTION_MAIN was this: 4382211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // 4383211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // [ . . . ] 4384211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // else if (action.equals(intent.ACTION_MAIN)) { 4385211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // if (DBG) log("checkIsOtaCall action ACTION_MAIN"); 4386211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // boolean isRingingCall = mCM.hasActiveRingingCall(); 4387211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // if (isRingingCall) { 4388211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // if (DBG) log("checkIsOtaCall isRingingCall: " + isRingingCall); 4389211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // return false; 4390211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // } else if ((mApp.cdmaOtaInCallScreenUiState.state 4391211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // == CdmaOtaInCallScreenUiState.State.NORMAL) 4392211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // || (mApp.cdmaOtaInCallScreenUiState.state 4393211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // == CdmaOtaInCallScreenUiState.State.ENDED)) { 4394211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // if (DBG) log("action ACTION_MAIN, OTA call already in progress"); 4395211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // isOtaCall = true; 4396211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // } else { 4397211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // if (mApp.cdmaOtaScreenState.otaScreenState != 4398211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED) { 4399211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // if (DBG) log("checkIsOtaCall action ACTION_MAIN, " 4400211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // + "OTA call in progress with UNDEFINED"); 4401211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // isOtaCall = true; 4402211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // } 4403211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // } 4404211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // } 4405211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // 4406211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // Also, in internalResolveIntent() we used to do this: 4407211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // 4408211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL) 4409211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // || (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED)) { 4410211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // // If in OTA Call, update the OTA UI 4411211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // updateScreen(); 4412211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // return; 4413211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // } 4414211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // 4415211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown // We still need more cleanup to simplify the mApp.cdma*State objects. 4416211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown 4417211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown return otaspUiActive; 4418af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 4419af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville 442047e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown /** 442147e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown * Updates and returns the InCallControlState instance. 442247e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown */ 442347e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown public InCallControlState getUpdatedInCallControlState() { 442402d1c632adde606031c1fe6ea0e3be1e288fd6c6David Brown if (VDBG) log("getUpdatedInCallControlState()..."); 442547e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown mInCallControlState.update(); 442647e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown return mInCallControlState; 442747e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown } 442847e534e7b9f75d8ec85ba15f1fd681770ec4592eDavid Brown 442973caead845b30580010a7502e4b7551d21dfa265Matthew Sun public void resetInCallScreenMode() { 4430211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown if (DBG) log("resetInCallScreenMode: setting mode to UNDEFINED..."); 443173caead845b30580010a7502e4b7551d21dfa265Matthew Sun setInCallScreenMode(InCallScreenMode.UNDEFINED); 443273caead845b30580010a7502e4b7551d21dfa265Matthew Sun } 4433b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 44342cbf80dfbbc28ae24e093fb089973b3e59d4508aNicolas Catania /** 44359688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown * Updates the onscreen hint displayed while the user is dragging one 44369688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown * of the handles of the RotarySelector widget used for incoming 44379688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown * calls. 44389688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown * 44399688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown * @param hintTextResId resource ID of the hint text to display, 44409688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown * or 0 if no hint should be visible. 44419688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown * @param hintColorResId resource ID for the color of the hint text 44429688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown */ 4443ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller /* package */ void updateIncomingCallWidgetHint(int hintTextResId, int hintColorResId) { 4444ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller if (VDBG) log("updateIncomingCallWidgetHint(" + hintTextResId + ")..."); 44459688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown if (mCallCard != null) { 4446ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller mCallCard.setIncomingCallWidgetHint(hintTextResId, hintColorResId); 44478343169cc89621d46dce86449f5ee1ff5d3a4919John Wang mCallCard.updateState(mCM); 44489688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // TODO: if hintTextResId == 0, consider NOT clearing the onscreen 44499688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // hint right away, but instead post a delayed handler message to 44509688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // keep it onscreen for an extra second or two. (This might make 44519688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // the hint more helpful if the user quickly taps one of the 44529688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // handles without dragging at all...) 44539688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // (Or, maybe this should happen completely within the RotarySelector 44549688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // widget, since the widget itself probably wants to keep the colored 44559688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // arrow visible for some extra time also...) 44569688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown } 44579688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown } 44589688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown 44593157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa 44603157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa /** 44613157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa * Used when we need to update buttons outside InCallTouchUi's updateInCallControls() along 44623157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa * with that method being called. CallCard may call this too because it doesn't have 44633157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa * enough information to update buttons inside itself (more specifically, the class cannot 44643157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa * obtain mInCallControllState without some side effect. See also 44653157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa * {@link #getUpdatedInCallControlState()}. We probably don't want a method like 44663157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa * getRawCallControlState() which returns raw intance with no side effect just for this 44673157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa * corner case scenario) 44683157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa * 44693157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa * TODO: need better design for buttons outside InCallTouchUi. 44703157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa */ 44713157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa /* package */ void updateButtonStateOutsideInCallTouchUi() { 44723157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa if (mCallCard != null) { 44733157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa mCallCard.setSecondaryCallClickable(mInCallControlState.canSwap); 44743157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa } 44753157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa } 44763157623699f642bcac5efc5382b49320efbd819bDaisuke Miyakawa 4477dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown @Override 4478dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 4479dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown super.dispatchPopulateAccessibilityEvent(event); 4480dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown mCallCard.dispatchPopulateAccessibilityEvent(event); 4481dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown return true; 4482dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown } 4483dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown 4484ad465d2663816e822b07232b56b0fdf2863ee248David Brown /** 4485ad465d2663816e822b07232b56b0fdf2863ee248David Brown * Manually handle configuration changes. 4486ad465d2663816e822b07232b56b0fdf2863ee248David Brown * 44878aca6a3c591a5dea28c69d4ddae722a13bfbe3cfGeobio Boo * Originally android:configChanges was set to "orientation|keyboardHidden|uiMode" 44888aca6a3c591a5dea28c69d4ddae722a13bfbe3cfGeobio Boo * in order "to make sure the system doesn't destroy and re-create us due to the 44898aca6a3c591a5dea28c69d4ddae722a13bfbe3cfGeobio Boo * above config changes". However it is currently set to "keyboardHidden" since 44908aca6a3c591a5dea28c69d4ddae722a13bfbe3cfGeobio Boo * the system needs to handle rotation when inserted into a compatible cardock. 44918aca6a3c591a5dea28c69d4ddae722a13bfbe3cfGeobio Boo * Even without explicitly handling orientation and uiMode, the app still runs 44928aca6a3c591a5dea28c69d4ddae722a13bfbe3cfGeobio Boo * and does not drop the call when rotated. 4493ad465d2663816e822b07232b56b0fdf2863ee248David Brown * 4494ad465d2663816e822b07232b56b0fdf2863ee248David Brown */ 4495ad465d2663816e822b07232b56b0fdf2863ee248David Brown public void onConfigurationChanged(Configuration newConfig) { 4496ad465d2663816e822b07232b56b0fdf2863ee248David Brown if (DBG) log("onConfigurationChanged: newConfig = " + newConfig); 4497ad465d2663816e822b07232b56b0fdf2863ee248David Brown 4498ad465d2663816e822b07232b56b0fdf2863ee248David Brown // Note: At the time this function is called, our Resources object 4499ad465d2663816e822b07232b56b0fdf2863ee248David Brown // will have already been updated to return resource values matching 4500ad465d2663816e822b07232b56b0fdf2863ee248David Brown // the new configuration. 4501ad465d2663816e822b07232b56b0fdf2863ee248David Brown 4502ad465d2663816e822b07232b56b0fdf2863ee248David Brown // Watch out: we *can* still get destroyed and recreated if a 4503ad465d2663816e822b07232b56b0fdf2863ee248David Brown // configuration change occurs that is *not* listed in the 4504ad465d2663816e822b07232b56b0fdf2863ee248David Brown // android:configChanges attribute. TODO: Any others we need to list? 4505ad465d2663816e822b07232b56b0fdf2863ee248David Brown 4506ad465d2663816e822b07232b56b0fdf2863ee248David Brown super.onConfigurationChanged(newConfig); 4507ad465d2663816e822b07232b56b0fdf2863ee248David Brown 4508ad465d2663816e822b07232b56b0fdf2863ee248David Brown // Nothing else to do here, since (currently) the InCallScreen looks 4509ad465d2663816e822b07232b56b0fdf2863ee248David Brown // exactly the same regardless of configuration. 4510ad465d2663816e822b07232b56b0fdf2863ee248David Brown // (Specifically, we'll never be in landscape mode because we set 4511ad465d2663816e822b07232b56b0fdf2863ee248David Brown // android:screenOrientation="portrait" in our manifest, and we don't 4512ad465d2663816e822b07232b56b0fdf2863ee248David Brown // change our UI at all based on newConfig.keyboardHidden or 4513ad465d2663816e822b07232b56b0fdf2863ee248David Brown // newConfig.uiMode.) 4514ad465d2663816e822b07232b56b0fdf2863ee248David Brown 4515ad465d2663816e822b07232b56b0fdf2863ee248David Brown // TODO: we do eventually want to handle at least some config changes, such as: 4516ad465d2663816e822b07232b56b0fdf2863ee248David Brown boolean isKeyboardOpen = (newConfig.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO); 4517ad465d2663816e822b07232b56b0fdf2863ee248David Brown if (DBG) log(" - isKeyboardOpen = " + isKeyboardOpen); 4518ad465d2663816e822b07232b56b0fdf2863ee248David Brown boolean isLandscape = (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE); 4519ad465d2663816e822b07232b56b0fdf2863ee248David Brown if (DBG) log(" - isLandscape = " + isLandscape); 4520ad465d2663816e822b07232b56b0fdf2863ee248David Brown if (DBG) log(" - uiMode = " + newConfig.uiMode); 4521ad465d2663816e822b07232b56b0fdf2863ee248David Brown // See bug 2089513. 4522ad465d2663816e822b07232b56b0fdf2863ee248David Brown } 4523ad465d2663816e822b07232b56b0fdf2863ee248David Brown 4524493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown /** 4525493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown * Handles an incoming RING event from the telephony layer. 4526493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown */ 4527493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown private void onIncomingRing() { 4528fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown if (DBG) log("onIncomingRing()..."); 4529493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown // IFF we're visible, forward this event to the InCallTouchUi 4530493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown // instance (which uses this event to drive the animation of the 4531493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown // incoming-call UI.) 4532493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown if (mIsForegroundActivity && (mInCallTouchUi != null)) { 4533493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown mInCallTouchUi.onIncomingRing(); 4534493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown } 4535493f919534543c4470baa89a59cb4fbdc0d9ff45David Brown } 4536ad465d2663816e822b07232b56b0fdf2863ee248David Brown 4537fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown /** 4538fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown * Handles a "new ringing connection" event from the telephony layer. 4539f4ef613d8e6f203248d459cd77a3a7074c8f817cDaisuke Miyakawa * 4540f4ef613d8e6f203248d459cd77a3a7074c8f817cDaisuke Miyakawa * This event comes in right at the start of the incoming-call sequence, 4541f4ef613d8e6f203248d459cd77a3a7074c8f817cDaisuke Miyakawa * exactly once per incoming call. 4542f4ef613d8e6f203248d459cd77a3a7074c8f817cDaisuke Miyakawa * 4543f4ef613d8e6f203248d459cd77a3a7074c8f817cDaisuke Miyakawa * Watch out: this won't be called if InCallScreen isn't ready yet, 4544f4ef613d8e6f203248d459cd77a3a7074c8f817cDaisuke Miyakawa * which typically happens for the first incoming phone call (even before 4545f4ef613d8e6f203248d459cd77a3a7074c8f817cDaisuke Miyakawa * the possible first outgoing call). 4546fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown */ 4547fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown private void onNewRingingConnection() { 4548fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown if (DBG) log("onNewRingingConnection()..."); 4549fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown 4550f4ef613d8e6f203248d459cd77a3a7074c8f817cDaisuke Miyakawa // We use this event to reset any incoming-call-related UI elements 4551f4ef613d8e6f203248d459cd77a3a7074c8f817cDaisuke Miyakawa // that might have been left in an inconsistent state after a prior 4552f4ef613d8e6f203248d459cd77a3a7074c8f817cDaisuke Miyakawa // incoming call. 4553fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown // (Note we do this whether or not we're the foreground activity, 4554fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown // since this event comes in *before* we actually get launched to 4555fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown // display the incoming-call UI.) 4556fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown 4557524486403a387c324dee5aff7fb78ca784d15255David Brown // If there's a "Respond via SMS" popup still around since the 4558524486403a387c324dee5aff7fb78ca784d15255David Brown // last time we were the foreground activity, make sure it's not 4559524486403a387c324dee5aff7fb78ca784d15255David Brown // still active(!) since that would interfere with *this* incoming 4560524486403a387c324dee5aff7fb78ca784d15255David Brown // call. 4561524486403a387c324dee5aff7fb78ca784d15255David Brown // (Note that we also do this same check in onResume(). But we 4562524486403a387c324dee5aff7fb78ca784d15255David Brown // need it here too, to make sure the popup gets reset in the case 4563524486403a387c324dee5aff7fb78ca784d15255David Brown // where a call-waiting call comes in while the InCallScreen is 4564524486403a387c324dee5aff7fb78ca784d15255David Brown // already in the foreground.) 4565f4ef613d8e6f203248d459cd77a3a7074c8f817cDaisuke Miyakawa mRespondViaSmsManager.dismissPopup(); // safe even if already dismissed 4566fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown } 4567fdc5d2875421a5c0119c24af8d6bca616ebb6be8David Brown 456837bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa /** 456937bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa * Enables or disables the status bar "window shade" based on the current situation. 457037bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa */ 457137bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa private void updateExpandedViewState() { 457237bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa if (mIsForegroundActivity) { 457337bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa if (mApp.proximitySensorModeEnabled()) { 457437bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa // We should not enable notification's expanded view on RINGING state. 457537bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa mApp.notificationMgr.statusBarHelper.enableExpandedView( 4576b0f85b4a78abead921c363f9c8e247d5bdd20c74Wink Saville mCM.getState() != PhoneConstants.State.RINGING); 457737bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa } else { 457837bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa // If proximity sensor is unavailable on the device, disable it to avoid false 457937bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa // touches toward notifications. 458037bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa mApp.notificationMgr.statusBarHelper.enableExpandedView(false); 458137bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa } 458237bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa } else { 458337bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa mApp.notificationMgr.statusBarHelper.enableExpandedView(true); 458437bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa } 458537bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa } 458637bd7d871494f0ac85bb4e96f886fe1fd0922f31Daisuke Miyakawa 4587b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void log(String msg) { 4588b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Log.d(LOG_TAG, msg); 4589b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 4590b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa 4591b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa /** 4592b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa * Requests to remove provider info frame after having 4593b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa * {@link #PROVIDER_INFO_TIMEOUT}) msec delay. 4594b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa */ 4595b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa /* package */ void requestRemoveProviderInfoWithDelay() { 4596b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa // Remove any zombie messages and then send a message to 4597b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa // self to remove the provider info after some time. 4598b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa mHandler.removeMessages(EVENT_HIDE_PROVIDER_INFO); 4599b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa Message msg = Message.obtain(mHandler, EVENT_HIDE_PROVIDER_INFO); 4600b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa mHandler.sendMessageDelayed(msg, PROVIDER_INFO_TIMEOUT); 4601b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa if (DBG) { 4602b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa log("Requested to remove provider info after " + PROVIDER_INFO_TIMEOUT + " msec."); 4603b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa } 4604b8e01d75f21087d55ba70e70f2b8ff1422b2406bDaisuke Miyakawa } 46056046c0d05994e434b7706fa1e3aec03d5f066d75Yorke Lee 46066046c0d05994e434b7706fa1e3aec03d5f066d75Yorke Lee /** 46076046c0d05994e434b7706fa1e3aec03d5f066d75Yorke Lee * Indicates whether or not the QuickResponseDialog is currently showing in the call screen 46086046c0d05994e434b7706fa1e3aec03d5f066d75Yorke Lee */ 46096046c0d05994e434b7706fa1e3aec03d5f066d75Yorke Lee public boolean isQuickResponseDialogShowing() { 46106046c0d05994e434b7706fa1e3aec03d5f066d75Yorke Lee return mRespondViaSmsManager != null && mRespondViaSmsManager.isShowingPopup(); 46116046c0d05994e434b7706fa1e3aec03d5f066d75Yorke Lee } 4612b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project} 4613