PhoneInterfaceManager.java revision 97ebb427fc22f1f14eab7c79745dfcbf2eb2ff7a
17d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon/* 27d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Copyright (C) 2006 The Android Open Source Project 37d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 47d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Licensed under the Apache License, Version 2.0 (the "License"); 57d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * you may not use this file except in compliance with the License. 67d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * You may obtain a copy of the License at 77d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 87d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * http://www.apache.org/licenses/LICENSE-2.0 97d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Unless required by applicable law or agreed to in writing, software 117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * distributed under the License is distributed on an "AS IS" BASIS, 127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * See the License for the specific language governing permissions and 147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * limitations under the License. 157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonpackage com.android.phone; 187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.app.ActivityManager; 207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.app.AppOpsManager; 21bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepalimport android.content.ComponentName; 227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.content.Context; 237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.content.Intent; 2497ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tanimport android.content.SharedPreferences; 2560f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawalimport android.content.pm.PackageInfo; 2660f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawalimport android.content.pm.PackageManager; 2760f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawalimport android.content.pm.Signature; 2836469e74b7c79ed84148754190c38196eb9a2c49Wink Savilleimport android.net.ConnectivityManager; 297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.net.Uri; 307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.AsyncResult; 317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Binder; 327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Bundle; 337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Handler; 3436ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport android.os.IBinder; 357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Looper; 367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Message; 377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Process; 3836ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport android.os.RemoteException; 397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.ServiceManager; 407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.UserHandle; 4197ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tanimport android.preference.PreferenceManager; 42f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awadimport android.provider.Settings; 437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.telephony.CellInfo; 44da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawalimport android.telephony.IccOpenLogicalChannelResponse; 45e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport android.telephony.NeighboringCellInfo; 467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.telephony.ServiceState; 4736469e74b7c79ed84148754190c38196eb9a2c49Wink Savilleimport android.telephony.SubscriptionManager; 48f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awadimport android.telephony.TelephonyManager; 497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.text.TextUtils; 507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.util.Log; 51e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport android.util.Pair; 527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 53566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.CallManager; 54566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.CommandException; 5536ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport com.android.internal.telephony.Connection; 567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.DefaultPhoneNotifier; 577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.ITelephony; 58e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport com.android.internal.telephony.IccCard; 597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.Phone; 6036469e74b7c79ed84148754190c38196eb9a2c49Wink Savilleimport com.android.internal.telephony.PhoneFactory; 6136469e74b7c79ed84148754190c38196eb9a2c49Wink Savilleimport com.android.internal.telephony.CallManager; 6236469e74b7c79ed84148754190c38196eb9a2c49Wink Savilleimport com.android.internal.telephony.CommandException; 637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.PhoneConstants; 6436469e74b7c79ed84148754190c38196eb9a2c49Wink Savilleimport com.android.internal.telephony.dataconnection.DctController; 657226c84acb402f96e527650347391fa025294350Derek Tanimport com.android.internal.telephony.uicc.AdnRecord; 66566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.uicc.IccIoResult; 67566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.uicc.IccUtils; 68eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawalimport com.android.internal.telephony.uicc.UiccCard; 6960f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawalimport com.android.internal.telephony.uicc.UiccCarrierPrivilegeRules; 70566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.uicc.UiccController; 71e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport com.android.internal.util.HexDump; 727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7336469e74b7c79ed84148754190c38196eb9a2c49Wink Savilleimport static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY; 7436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport java.util.ArrayList; 7636ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport java.util.HashMap; 7789e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tanimport java.util.HashSet; 7836ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport java.util.Iterator; 79e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport java.util.List; 8036ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport java.util.Map; 8189e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tanimport java.util.Set; 827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon/** 847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Implementation of the ITelephony interface. 857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 86117fee7467c140dccdc66972f60031dae2d55b35Santos Cordonpublic class PhoneInterfaceManager extends ITelephony.Stub { 877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final String LOG_TAG = "PhoneInterfaceManager"; 887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2); 897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final boolean DBG_LOC = false; 907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Message codes used with mMainThreadHandler 927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_HANDLE_PIN_MMI = 1; 937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_HANDLE_NEIGHBORING_CELL = 2; 947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int EVENT_NEIGHBORING_CELL_DONE = 3; 957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_ANSWER_RINGING_CALL = 4; 967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_END_CALL = 5; // not used yet 977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_SILENCE_RINGER = 6; 98da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7; 99da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8; 100566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int CMD_OPEN_CHANNEL = 9; 101566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int EVENT_OPEN_CHANNEL_DONE = 10; 102566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int CMD_CLOSE_CHANNEL = 11; 103566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int EVENT_CLOSE_CHANNEL_DONE = 12; 104e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_READ_ITEM = 13; 105e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_READ_ITEM_DONE = 14; 106e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_WRITE_ITEM = 15; 107e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_WRITE_ITEM_DONE = 16; 108e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_WRITE_CDMA_PRL = 17; 109e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18; 110e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_RESET_CONFIG = 19; 111e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_RESET_CONFIG_DONE = 20; 1127c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21; 1137c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22; 1147c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23; 1157c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24; 11635b5945231af96ad0d7ebf4cfcaafeb677d8c75cSailesh Nepal private static final int CMD_SEND_ENVELOPE = 25; 11735b5945231af96ad0d7ebf4cfcaafeb677d8c75cSailesh Nepal private static final int EVENT_SEND_ENVELOPE_DONE = 26; 1186b088eef6c47d96b9b2a0097e3b8ee8b4332f068Derek Tan private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27; 1196b088eef6c47d96b9b2a0097e3b8ee8b4332f068Derek Tan private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28; 1206b088eef6c47d96b9b2a0097e3b8ee8b4332f068Derek Tan private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29; 1216b088eef6c47d96b9b2a0097e3b8ee8b4332f068Derek Tan private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30; 1226b088eef6c47d96b9b2a0097e3b8ee8b4332f068Derek Tan private static final int CMD_EXCHANGE_SIM_IO = 31; 1236b088eef6c47d96b9b2a0097e3b8ee8b4332f068Derek Tan private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32; 1247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The singleton instance. */ 1267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static PhoneInterfaceManager sInstance; 1277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneGlobals mApp; 1297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Phone mPhone; 1307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CallManager mCM; 1317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AppOpsManager mAppOps; 1327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon MainThreadHandler mMainThreadHandler; 1337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13497ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan SharedPreferences carrierPrivilegeConfigs; 13597ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_"; 13697ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_"; 13797ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan private static final String PREF_CARRIERS_SIMPLIFIED_NETWORK_SETTINGS_PREFIX = 13897ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan "carrier_simplified_network_settings_"; 13989e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan 14089e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan /** 141566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal * A request object to use for transmitting data to an ICC. 142566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal */ 143566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final class IccAPDUArgument { 144566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public int channel, cla, command, p1, p2, p3; 145566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public String data; 146566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 147566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public IccAPDUArgument(int channel, int cla, int command, 148566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal int p1, int p2, int p3, String data) { 149566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.channel = channel; 150566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.cla = cla; 151566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.command = command; 152566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.p1 = p1; 153566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.p2 = p2; 154566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.p3 = p3; 155566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.data = data; 156566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 157566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 158566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 159566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal /** 1607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the 1617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * request after sending. The main thread will notify the request when it is complete. 1627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 1637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final class MainThreadRequest { 1647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The argument to use for the request */ 1657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public Object argument; 1667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The result of the request that is run on the main thread */ 1677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public Object result; 1687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public MainThreadRequest(Object argument) { 1707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon this.argument = argument; 1717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 174cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal private static final class IncomingThirdPartyCallArgs { 175cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public final ComponentName component; 176cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public final String callId; 177cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public final String callerDisplayName; 178cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal 179cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public IncomingThirdPartyCallArgs(ComponentName component, String callId, 180cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal String callerDisplayName) { 181cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal this.component = component; 182cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal this.callId = callId; 183cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal this.callerDisplayName = callerDisplayName; 184cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal } 185cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal } 186cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal 1877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * A handler that processes messages on the main thread in the phone process. Since many 1897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * of the Phone calls are not thread safe this is needed to shuttle the requests from the 1907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * inbound binder threads to the main thread in the phone process. The Binder thread 1917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting 1927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * on, which will be notified when the operation completes and will contain the result of the 1937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * request. 1947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 1957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * <p>If a MainThreadRequest object is provided in the msg.obj field, 1967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * note that request.result must be set to something non-null for the calling thread to 1977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * unblock. 1987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 1997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private final class MainThreadHandler extends Handler { 2007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 2017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void handleMessage(Message msg) { 2027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon MainThreadRequest request; 2037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message onCompleted; 2047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AsyncResult ar; 205eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal UiccCard uiccCard = UiccController.getInstance().getUiccCard(); 206da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccAPDUArgument iccArgument; 2077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon switch (msg.what) { 2097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_HANDLE_PIN_MMI: 2107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) msg.obj; 211e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = mPhone.handlePinMmi((String) request.argument); 2127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wake up the requesting thread 2137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 2147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.notifyAll(); 2157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_HANDLE_NEIGHBORING_CELL: 2197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) msg.obj; 2207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onCompleted = obtainMessage(EVENT_NEIGHBORING_CELL_DONE, 2217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request); 2227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.getNeighboringCids(onCompleted); 2237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case EVENT_NEIGHBORING_CELL_DONE: 2267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ar = (AsyncResult) msg.obj; 2277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) ar.userObj; 2287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (ar.exception == null && ar.result != null) { 2297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.result = ar.result; 2307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 2317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // create an empty list to notify the waiting thread 232e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = new ArrayList<NeighboringCellInfo>(0); 2337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wake up the requesting thread 2357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 2367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.notifyAll(); 2377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_ANSWER_RINGING_CALL: 2417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon answerRingingCallInternal(); 2427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_SILENCE_RINGER: 2457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon silenceRingerInternal(); 2467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_END_CALL: 2497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) msg.obj; 250e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby boolean hungUp; 2517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int phoneType = mPhone.getPhoneType(); 2527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { 2537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // CDMA: If the user presses the Power button we treat it as 2547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ending the complete call session 2557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon hungUp = PhoneUtils.hangupRingingAndActive(mPhone); 2567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) { 2577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // GSM: End the call as per the Phone state 2587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon hungUp = PhoneUtils.hangup(mCM); 2597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 2607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon throw new IllegalStateException("Unexpected phone type: " + phoneType); 2617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("CMD_END_CALL: " + (hungUp ? "hung up!" : "no call to hang up")); 2637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.result = hungUp; 2647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wake up the requesting thread 2657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 2667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.notifyAll(); 2677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 270da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL: 271566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) msg.obj; 272da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument = (IccAPDUArgument) request.argument; 273eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (uiccCard == null) { 274eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("iccTransmitApduLogicalChannel: No UICC"); 275eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 276eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal synchronized (request) { 277eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.notifyAll(); 278eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 279eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } else { 280da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE, 281da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request); 282eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal uiccCard.iccTransmitApduLogicalChannel( 283da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument.channel, iccArgument.cla, iccArgument.command, 284da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data, 285566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal onCompleted); 286eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 287566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 288566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 289da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE: 290566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal ar = (AsyncResult) msg.obj; 291566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) ar.userObj; 292566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.exception == null && ar.result != null) { 293566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.result = ar.result; 294566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 295566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 296566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.result == null) { 297566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccTransmitApduLogicalChannel: Empty response"); 298e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else if (ar.exception instanceof CommandException) { 299566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccTransmitApduLogicalChannel: CommandException: " + 300e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby ar.exception); 301566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 302566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccTransmitApduLogicalChannel: Unknown exception"); 303566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 304566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 305566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal synchronized (request) { 306566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.notifyAll(); 307566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 308566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 309566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 310da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal case CMD_TRANSMIT_APDU_BASIC_CHANNEL: 311da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request = (MainThreadRequest) msg.obj; 312da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument = (IccAPDUArgument) request.argument; 313da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (uiccCard == null) { 314da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal loge("iccTransmitApduBasicChannel: No UICC"); 315da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 316da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal synchronized (request) { 317da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.notifyAll(); 318da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 319da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else { 320da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE, 321da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request); 322da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal uiccCard.iccTransmitApduBasicChannel( 323da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2, 324da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument.p3, iccArgument.data, onCompleted); 325da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 326da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal break; 327da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 328da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE: 329da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal ar = (AsyncResult) msg.obj; 330da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request = (MainThreadRequest) ar.userObj; 331da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (ar.exception == null && ar.result != null) { 332da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.result = ar.result; 333da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else { 334da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 335da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (ar.result == null) { 336da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal loge("iccTransmitApduBasicChannel: Empty response"); 337da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else if (ar.exception instanceof CommandException) { 338da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal loge("iccTransmitApduBasicChannel: CommandException: " + 339da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal ar.exception); 340da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else { 341da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal loge("iccTransmitApduBasicChannel: Unknown exception"); 342da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 343da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 344da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal synchronized (request) { 345da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.notifyAll(); 346da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 347da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal break; 348da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 349da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal case CMD_EXCHANGE_SIM_IO: 350da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request = (MainThreadRequest) msg.obj; 351da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument = (IccAPDUArgument) request.argument; 352da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (uiccCard == null) { 353da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal loge("iccExchangeSimIO: No UICC"); 354da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 355da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal synchronized (request) { 356da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.notifyAll(); 357da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 358da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else { 359da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE, 360da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request); 361da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */ 362da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3, 363da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument.data, onCompleted); 364da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 365da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal break; 366da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 367da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal case EVENT_EXCHANGE_SIM_IO_DONE: 368da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal ar = (AsyncResult) msg.obj; 369da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request = (MainThreadRequest) ar.userObj; 370da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (ar.exception == null && ar.result != null) { 371da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.result = ar.result; 372da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else { 373da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.result = new IccIoResult(0x6f, 0, (byte[])null); 374da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 375da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal synchronized (request) { 376da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.notifyAll(); 377da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 378da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal break; 379da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 3804d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan case CMD_SEND_ENVELOPE: 3814d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan request = (MainThreadRequest) msg.obj; 382eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (uiccCard == null) { 383eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("sendEnvelopeWithStatus: No UICC"); 384eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 385eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal synchronized (request) { 386eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.notifyAll(); 387eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 388eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } else { 389eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request); 390eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted); 391eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 3924d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan break; 3934d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan 3944d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan case EVENT_SEND_ENVELOPE_DONE: 3954d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan ar = (AsyncResult) msg.obj; 3964d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan request = (MainThreadRequest) ar.userObj; 3979f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal if (ar.exception == null && ar.result != null) { 3989f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal request.result = ar.result; 3994d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan } else { 4009f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 4019f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal if (ar.result == null) { 4029f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal loge("sendEnvelopeWithStatus: Empty response"); 4039f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal } else if (ar.exception instanceof CommandException) { 4049f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal loge("sendEnvelopeWithStatus: CommandException: " + 4059f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal ar.exception); 4069f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal } else { 4079f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal loge("sendEnvelopeWithStatus: exception:" + ar.exception); 4089f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal } 4094d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan } 4104d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan synchronized (request) { 4114d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan request.notifyAll(); 4124d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan } 4134d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan break; 4144d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan 415566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case CMD_OPEN_CHANNEL: 416566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) msg.obj; 417eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (uiccCard == null) { 418eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("iccOpenLogicalChannel: No UICC"); 419eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 420eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal synchronized (request) { 421eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.notifyAll(); 422eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 423eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } else { 424eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request); 425eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal uiccCard.iccOpenLogicalChannel((String)request.argument, onCompleted); 426eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 427566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 428566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 429566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case EVENT_OPEN_CHANNEL_DONE: 430566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal ar = (AsyncResult) msg.obj; 431566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) ar.userObj; 432da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccOpenLogicalChannelResponse openChannelResp; 433566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.exception == null && ar.result != null) { 434da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal int[] result = (int[]) ar.result; 435da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal int channelId = result[0]; 436da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal byte[] selectResponse = null; 437da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (result.length > 1) { 438da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal selectResponse = new byte[result.length - 1]; 439da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal for (int i = 1; i < result.length; ++i) { 440da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal selectResponse[i - 1] = (byte) result[i]; 441da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 442da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 443da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal openChannelResp = new IccOpenLogicalChannelResponse(channelId, 444527e8bf2bd43c5bfdb2ac7ea8cf05413c1faaeb5Shishir Agrawal IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse); 445566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 446566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.result == null) { 447566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccOpenLogicalChannel: Empty response"); 448566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 449da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (ar.exception != null) { 450da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal loge("iccOpenLogicalChannel: Exception: " + ar.exception); 451da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 452da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 453527e8bf2bd43c5bfdb2ac7ea8cf05413c1faaeb5Shishir Agrawal int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR; 454da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if ((ar.exception != null) && (ar.exception instanceof CommandException)) { 455da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (ar.exception.getMessage().compareTo("MISSING_RESOURCE") == 0) { 456527e8bf2bd43c5bfdb2ac7ea8cf05413c1faaeb5Shishir Agrawal errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE; 457da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else if (ar.exception.getMessage().compareTo("NO_SUCH_ELEMENT") == 0) { 458527e8bf2bd43c5bfdb2ac7ea8cf05413c1faaeb5Shishir Agrawal errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT; 459da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 460da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 461da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal openChannelResp = new IccOpenLogicalChannelResponse( 462da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null); 463566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 46482c8a46052629d1450320c116d14c7353bfe4ea1Shishir Agrawal request.result = openChannelResp; 465566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal synchronized (request) { 466566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.notifyAll(); 467566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 468566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 469566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 470566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case CMD_CLOSE_CHANNEL: 471566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) msg.obj; 472eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (uiccCard == null) { 473eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("iccCloseLogicalChannel: No UICC"); 474eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 475eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal synchronized (request) { 476eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.notifyAll(); 477eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 478eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } else { 479eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request); 480eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted); 481eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 482566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 483566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 484566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case EVENT_CLOSE_CHANNEL_DONE: 485e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "iccCloseLogicalChannel"); 486e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 487e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 488e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_READ_ITEM: 489e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 490e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request); 491e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvReadItem((Integer) request.argument, onCompleted); 492e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 493e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 494e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_READ_ITEM_DONE: 495566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal ar = (AsyncResult) msg.obj; 496566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) ar.userObj; 497e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.exception == null && ar.result != null) { 498e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = ar.result; // String 499566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 500e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = ""; 501e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.result == null) { 502e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge("nvReadItem: Empty response"); 503e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else if (ar.exception instanceof CommandException) { 504e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge("nvReadItem: CommandException: " + 505e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby ar.exception); 506566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 507e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge("nvReadItem: Unknown exception"); 508566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 509566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 510566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal synchronized (request) { 511566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.notifyAll(); 512566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 513566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 514566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 515e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_WRITE_ITEM: 516e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 517e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request); 518e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument; 519e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvWriteItem(idValue.first, idValue.second, onCompleted); 520e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 521e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 522e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_WRITE_ITEM_DONE: 523e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "nvWriteItem"); 524e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 525e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 526e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_WRITE_CDMA_PRL: 527e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 528e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request); 529e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted); 530e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 531e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 532e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_WRITE_CDMA_PRL_DONE: 533e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "nvWriteCdmaPrl"); 534e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 535e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 536e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_RESET_CONFIG: 537e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 538e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_RESET_CONFIG_DONE, request); 539e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvResetConfig((Integer) request.argument, onCompleted); 540e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 541e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 542e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_RESET_CONFIG_DONE: 543e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "nvResetConfig"); 544e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 545e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 5467c27be317e8757948178815426d3a329c852b9eeJake Hamby case CMD_GET_PREFERRED_NETWORK_TYPE: 5477c27be317e8757948178815426d3a329c852b9eeJake Hamby request = (MainThreadRequest) msg.obj; 5487c27be317e8757948178815426d3a329c852b9eeJake Hamby onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request); 5497c27be317e8757948178815426d3a329c852b9eeJake Hamby mPhone.getPreferredNetworkType(onCompleted); 5507c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 5517c27be317e8757948178815426d3a329c852b9eeJake Hamby 5527c27be317e8757948178815426d3a329c852b9eeJake Hamby case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE: 5537c27be317e8757948178815426d3a329c852b9eeJake Hamby ar = (AsyncResult) msg.obj; 5547c27be317e8757948178815426d3a329c852b9eeJake Hamby request = (MainThreadRequest) ar.userObj; 5557c27be317e8757948178815426d3a329c852b9eeJake Hamby if (ar.exception == null && ar.result != null) { 5567c27be317e8757948178815426d3a329c852b9eeJake Hamby request.result = ar.result; // Integer 5577c27be317e8757948178815426d3a329c852b9eeJake Hamby } else { 5587c27be317e8757948178815426d3a329c852b9eeJake Hamby request.result = -1; 5597c27be317e8757948178815426d3a329c852b9eeJake Hamby if (ar.result == null) { 5607c27be317e8757948178815426d3a329c852b9eeJake Hamby loge("getPreferredNetworkType: Empty response"); 5617c27be317e8757948178815426d3a329c852b9eeJake Hamby } else if (ar.exception instanceof CommandException) { 5627c27be317e8757948178815426d3a329c852b9eeJake Hamby loge("getPreferredNetworkType: CommandException: " + 5637c27be317e8757948178815426d3a329c852b9eeJake Hamby ar.exception); 5647c27be317e8757948178815426d3a329c852b9eeJake Hamby } else { 5657c27be317e8757948178815426d3a329c852b9eeJake Hamby loge("getPreferredNetworkType: Unknown exception"); 5667c27be317e8757948178815426d3a329c852b9eeJake Hamby } 5677c27be317e8757948178815426d3a329c852b9eeJake Hamby } 5687c27be317e8757948178815426d3a329c852b9eeJake Hamby synchronized (request) { 5697c27be317e8757948178815426d3a329c852b9eeJake Hamby request.notifyAll(); 5707c27be317e8757948178815426d3a329c852b9eeJake Hamby } 5717c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 5727c27be317e8757948178815426d3a329c852b9eeJake Hamby 5737c27be317e8757948178815426d3a329c852b9eeJake Hamby case CMD_SET_PREFERRED_NETWORK_TYPE: 5747c27be317e8757948178815426d3a329c852b9eeJake Hamby request = (MainThreadRequest) msg.obj; 5757c27be317e8757948178815426d3a329c852b9eeJake Hamby onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request); 5767c27be317e8757948178815426d3a329c852b9eeJake Hamby int networkType = (Integer) request.argument; 5777c27be317e8757948178815426d3a329c852b9eeJake Hamby mPhone.setPreferredNetworkType(networkType, onCompleted); 5787c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 5797c27be317e8757948178815426d3a329c852b9eeJake Hamby 5807c27be317e8757948178815426d3a329c852b9eeJake Hamby case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE: 5817c27be317e8757948178815426d3a329c852b9eeJake Hamby handleNullReturnEvent(msg, "setPreferredNetworkType"); 5827c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 5837c27be317e8757948178815426d3a329c852b9eeJake Hamby 5844bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu case CMD_INVOKE_OEM_RIL_REQUEST_RAW: 5854bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu request = (MainThreadRequest)msg.obj; 5864bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request); 5874bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu mPhone.invokeOemRilRequestRaw((byte[])request.argument, onCompleted); 5884bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu break; 5894bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu 5904bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE: 5914bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu ar = (AsyncResult)msg.obj; 5924bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu request = (MainThreadRequest)ar.userObj; 5934bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu request.result = ar; 5944bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu synchronized (request) { 5954bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu request.notifyAll(); 5964bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } 5974bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu break; 5984bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu 5997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon default: 6007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what); 6017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 6027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 604e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 605e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private void handleNullReturnEvent(Message msg, String command) { 606e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby AsyncResult ar = (AsyncResult) msg.obj; 607e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby MainThreadRequest request = (MainThreadRequest) ar.userObj; 608e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.exception == null) { 609e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = true; 610e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else { 611e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = false; 612e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.exception instanceof CommandException) { 613e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge(command + ": CommandException: " + ar.exception); 614e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else { 615e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge(command + ": Unknown exception"); 616e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 617e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 618e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby synchronized (request) { 619e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.notifyAll(); 620e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 621e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 6227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 6257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Posts the specified command to be executed on the main thread, 6267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * waits for the request to complete, and returns the result. 6277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #sendRequestAsync 6287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 6297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Object sendRequest(int command, Object argument) { 630500b0e04406d2995c1f29dea95c98cedaa669f74Santos Cordon return sendRequest(command, argument, null); 63136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 63236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 63336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 63436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Posts the specified command to be executed on the main thread, 63536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * waits for the request to complete, and returns the result. 63636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * @see #sendRequestAsync 63736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 63836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville private Object sendRequest(int command, Object argument, Object argument2) { 6397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (Looper.myLooper() == mMainThreadHandler.getLooper()) { 6407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon throw new RuntimeException("This method will deadlock if called from the main thread."); 6417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon MainThreadRequest request = new MainThreadRequest(argument); 6447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message msg = mMainThreadHandler.obtainMessage(command, request); 6457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon msg.sendToTarget(); 6467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wait for the request to complete 6487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 6497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon while (request.result == null) { 6507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 6517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.wait(); 6527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 6537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Do nothing, go back and wait until the request is complete 6547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return request.result; 6587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 6617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Asynchronous ("fire and forget") version of sendRequest(): 6627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Posts the specified command to be executed on the main thread, and 6637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * returns immediately. 6647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #sendRequest 6657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 6667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void sendRequestAsync(int command) { 6677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mMainThreadHandler.sendEmptyMessage(command); 6687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 671bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal * Same as {@link #sendRequestAsync(int)} except it takes an argument. 672bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal * @see {@link #sendRequest(int,Object)} 673bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal */ 674bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal private void sendRequestAsync(int command, Object argument) { 675bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal MainThreadRequest request = new MainThreadRequest(argument); 676bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal Message msg = mMainThreadHandler.obtainMessage(command, request); 677bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal msg.sendToTarget(); 678bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal } 679bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal 680bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal /** 6817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Initialize the singleton PhoneInterfaceManager instance. 6827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This is only done once, at startup, from PhoneApp.onCreate(). 6837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 684194161ed3aef6bdeeecd6153403269bbd01314a5Sailesh Nepal /* package */ static PhoneInterfaceManager init(PhoneGlobals app, Phone phone) { 6857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (PhoneInterfaceManager.class) { 6867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (sInstance == null) { 687194161ed3aef6bdeeecd6153403269bbd01314a5Sailesh Nepal sInstance = new PhoneInterfaceManager(app, phone); 6887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 6897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance); 6907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return sInstance; 6927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** Private constructor; @see init() */ 696194161ed3aef6bdeeecd6153403269bbd01314a5Sailesh Nepal private PhoneInterfaceManager(PhoneGlobals app, Phone phone) { 6977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp = app; 6987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone = phone; 6997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCM = PhoneGlobals.getInstance().mCM; 7007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE); 7017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mMainThreadHandler = new MainThreadHandler(); 70297ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan carrierPrivilegeConfigs = 70397ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan PreferenceManager.getDefaultSharedPreferences(mPhone.getContext()); 7047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon publish(); 7057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void publish() { 7087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("publish: " + this); 7097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ServiceManager.addService("phone", this); 7117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 71336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // returns phone associated with the subId. 71436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // getPhone(0) returns default phone in single SIM mode. 71536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville private Phone getPhone(long subId) { 71636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // FIXME: hack for the moment 71736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return mPhone; 71836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // return PhoneUtils.getPhoneUsingSubId(subId); 71936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 7207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 7217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Implementation of the ITelephony interface. 7227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 7237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void dial(String number) { 72536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville dialUsingSubId(getPreferredVoiceSubscription(), number); 72636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 72736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 72836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void dialUsingSubId(long subId, String number) { 7297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("dial: " + number); 7307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No permission check needed here: This is just a wrapper around the 7317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ACTION_DIAL intent, which is available to any app since it puts up 7327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the UI before it does anything. 7337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon String url = createTelUrl(number); 7357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (url == null) { 7367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 7377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // PENDING: should we just silently fail if phone is offhook or ringing? 74036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville PhoneConstants.State state = mCM.getState(subId); 7417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) { 7427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url)); 7437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 74436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville intent.putExtra(SUBSCRIPTION_KEY, subId); 7457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.startActivity(intent); 7467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void call(String callingPackage, String number) { 75036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville callUsingSubId(getPreferredVoiceSubscription(), callingPackage, number); 75136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 75236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 75336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void callUsingSubId(long subId, String callingPackage, String number) { 7547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("call: " + number); 7557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // This is just a wrapper around the ACTION_CALL intent, but we still 7577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // need to do a permission check since we're calling startActivity() 7587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // from the context of the phone app. 7597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceCallPermission(); 7607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mAppOps.noteOp(AppOpsManager.OP_CALL_PHONE, Binder.getCallingUid(), callingPackage) 7627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon != AppOpsManager.MODE_ALLOWED) { 7637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 7647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon String url = createTelUrl(number); 7677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (url == null) { 7687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 7697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url)); 77236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville intent.putExtra(SUBSCRIPTION_KEY, subId); 7737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 7747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.startActivity(intent); 7757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 7787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * End a call based on call state 7797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return true is a call was ended 7807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 7817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean endCall() { 78236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return endCallUsingSubId(getDefaultSubscription()); 78336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 78436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 78536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 78636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * End a call based on the call state of the subId 78736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * @return true is a call was ended 78836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 78936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean endCallUsingSubId(long subId) { 7907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceCallPermission(); 79136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return (Boolean) sendRequest(CMD_END_CALL, subId, null); 7927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void answerRingingCall() { 79536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville answerRingingCallUsingSubId(getDefaultSubscription()); 79636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 79736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 79836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void answerRingingCallUsingSubId(long subId) { 7997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("answerRingingCall..."); 8007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: there should eventually be a separate "ANSWER_PHONE" permission, 8017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // but that can probably wait till the big TelephonyManager API overhaul. 8027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For now, protect this call with the MODIFY_PHONE_STATE permission. 8037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 8047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon sendRequestAsync(CMD_ANSWER_RINGING_CALL); 8057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 8087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make the actual telephony calls to implement answerRingingCall(). 8097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This should only be called from the main thread of the Phone app. 8107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #answerRingingCall 8117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 8127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * TODO: it would be nice to return true if we answered the call, or 8137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * false if there wasn't actually a ringing incoming call, or some 8147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * other error occurred. (In other words, pass back the return value 8157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * from PhoneUtils.answerCall() or PhoneUtils.answerAndEndActive().) 8167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * But that would require calling this method via sendRequest() rather 8177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * than sendRequestAsync(), and right now we don't actually *need* that 8187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * return value, so let's just return void for now. 8197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 8207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void answerRingingCallInternal() { 8217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final boolean hasRingingCall = !mPhone.getRingingCall().isIdle(); 8227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (hasRingingCall) { 8237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final boolean hasActiveCall = !mPhone.getForegroundCall().isIdle(); 8247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final boolean hasHoldingCall = !mPhone.getBackgroundCall().isIdle(); 8257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (hasActiveCall && hasHoldingCall) { 8267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Both lines are in use! 8277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: provide a flag to let the caller specify what 8287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // policy to use if both lines are in use. (The current 8297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // behavior is hardwired to "answer incoming, end ongoing", 8307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // which is how the CALL button is specced to behave.) 8317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.answerAndEndActive(mCM, mCM.getFirstActiveRingingCall()); 8327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 8337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 8347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // answerCall() will automatically hold the current active 8357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // call, if there is one. 8367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.answerCall(mCM.getFirstActiveRingingCall()); 8377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 8387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 8407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No call was ringing. 8417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 8427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void silenceRinger() { 8467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("silenceRinger..."); 8477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: find a more appropriate permission to check here. 8487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // (That can probably wait till the big TelephonyManager API overhaul. 8497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For now, protect this call with the MODIFY_PHONE_STATE permission.) 8507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 8517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon sendRequestAsync(CMD_SILENCE_RINGER); 8527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 8557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Internal implemenation of silenceRinger(). 8567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This should only be called from the main thread of the Phone app. 8577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #silenceRinger 8587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 8597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void silenceRingerInternal() { 8607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((mCM.getState() == PhoneConstants.State.RINGING) 8617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon && mApp.notifier.isRinging()) { 8627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Ringer is actually playing, so silence it. 8637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("silenceRingerInternal: silencing..."); 8647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.notifier.silenceRinger(); 8657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isOffhook() { 86936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return isOffhookUsingSubId(getDefaultSubscription()); 87036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 87136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 87236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean isOffhookUsingSubId(long subId) { 87336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return (getPhone(subId).getState() == PhoneConstants.State.OFFHOOK); 8747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isRinging() { 87736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return (isRingingUsingSubId(getDefaultSubscription())); 87836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 87936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 88036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean isRingingUsingSubId(long subId) { 88136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return (getPhone(subId).getState() == PhoneConstants.State.RINGING); 8827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isIdle() { 88536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return isIdleUsingSubId(getDefaultSubscription()); 88636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 88736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 88836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean isIdleUsingSubId(long subId) { 88936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return (getPhone(subId).getState() == PhoneConstants.State.IDLE); 8907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isSimPinEnabled() { 8937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceReadPermission(); 8947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return (PhoneGlobals.getInstance().isSimPinEnabled()); 8957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean supplyPin(String pin) { 89836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return supplyPinUsingSubId(getDefaultSubscription(), pin); 89936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 90036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 90136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean supplyPinUsingSubId(long subId, String pin) { 90236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville int [] resultArray = supplyPinReportResultUsingSubId(subId, pin); 9039de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false; 9049de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 9059de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville 9069de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville public boolean supplyPuk(String puk, String pin) { 90736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return supplyPukUsingSubId(getDefaultSubscription(), puk, pin); 90836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 90936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 91036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean supplyPukUsingSubId(long subId, String puk, String pin) { 91136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville int [] resultArray = supplyPukReportResultUsingSubId(subId, puk, pin); 9129de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false; 9139de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 9149de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville 9159de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville /** {@hide} */ 9169de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville public int[] supplyPinReportResult(String pin) { 91736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return supplyPinReportResultUsingSubId(getDefaultSubscription(), pin); 91836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 91936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 92036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int[] supplyPinReportResultUsingSubId(long subId, String pin) { 9217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 92236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard()); 9237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon checkSimPin.start(); 9247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return checkSimPin.unlockSim(null, pin); 9257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9279de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville /** {@hide} */ 9289de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville public int[] supplyPukReportResult(String puk, String pin) { 92936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return supplyPukReportResultUsingSubId(getDefaultSubscription(), puk, pin); 93036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 93136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 93236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int[] supplyPukReportResultUsingSubId(long subId, String puk, String pin) { 9337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 93436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard()); 9357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon checkSimPuk.start(); 9367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return checkSimPuk.unlockSim(puk, pin); 9377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 9409de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville * Helper thread to turn async call to SimCard#supplyPin into 9417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * a synchronous one. 9427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 9437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static class UnlockSim extends Thread { 9447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private final IccCard mSimCard; 9467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private boolean mDone = false; 9489de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville private int mResult = PhoneConstants.PIN_GENERAL_FAILURE; 9499de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville private int mRetryCount = -1; 9507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For replies from SimCard interface 9527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Handler mHandler; 9537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For async handler to identify request type 9557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int SUPPLY_PIN_COMPLETE = 100; 9567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public UnlockSim(IccCard simCard) { 9587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSimCard = simCard; 9597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 9627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void run() { 9637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Looper.prepare(); 9647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (UnlockSim.this) { 9657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mHandler = new Handler() { 9667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 9677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void handleMessage(Message msg) { 9687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AsyncResult ar = (AsyncResult) msg.obj; 9697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon switch (msg.what) { 9707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case SUPPLY_PIN_COMPLETE: 9717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE"); 9727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (UnlockSim.this) { 9739de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mRetryCount = msg.arg1; 9749de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville if (ar.exception != null) { 9759de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville if (ar.exception instanceof CommandException && 9769de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville ((CommandException)(ar.exception)).getCommandError() 9779de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville == CommandException.Error.PASSWORD_INCORRECT) { 9789de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mResult = PhoneConstants.PIN_PASSWORD_INCORRECT; 9799de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } else { 9809de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mResult = PhoneConstants.PIN_GENERAL_FAILURE; 9819de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 9829de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } else { 9839de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mResult = PhoneConstants.PIN_RESULT_SUCCESS; 9849de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 9857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mDone = true; 9867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon UnlockSim.this.notifyAll(); 9877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 9897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon }; 9927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon UnlockSim.this.notifyAll(); 9937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Looper.loop(); 9957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* 9987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Use PIN or PUK to unlock SIM card 9997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 10007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * If PUK is null, unlock SIM card with PIN 10017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 10027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * If PUK is not null, unlock SIM card with PUK and set PIN code 10037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 10049de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville synchronized int[] unlockSim(String puk, String pin) { 10057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon while (mHandler == null) { 10077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 10087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon wait(); 10097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 10107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Thread.currentThread().interrupt(); 10117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE); 10147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (puk == null) { 10167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSimCard.supplyPin(pin, callback); 10177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 10187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSimCard.supplyPuk(puk, pin, callback); 10197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon while (!mDone) { 10227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 10237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "wait for done"); 10247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon wait(); 10257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 10267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Restore the interrupted status 10277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Thread.currentThread().interrupt(); 10287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "done"); 10319de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville int[] resultArray = new int[2]; 10329de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville resultArray[0] = mResult; 10339de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville resultArray[1] = mRetryCount; 10349de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville return resultArray; 10357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void updateServiceLocation() { 103936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville updateServiceLocationUsingSubId(getDefaultSubscription()); 104036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 104136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 104236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 104336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void updateServiceLocationUsingSubId(long subId) { 10447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No permission check needed here: this call is harmless, and it's 10457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // needed for the ServiceState.requestStateUpdate() call (which is 10467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // already intentionally exposed to 3rd parties.) 104736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).updateServiceLocation(); 10487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isRadioOn() { 105136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return isRadioOnUsingSubId(getDefaultSubscription()); 105236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 105336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 105436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean isRadioOnUsingSubId(long subId) { 105536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getServiceState().getState() != ServiceState.STATE_POWER_OFF; 10567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void toggleRadioOnOff() { 105936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville toggleRadioOnOffUsingSubId(getDefaultSubscription()); 106036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 106136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 106236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 106336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void toggleRadioOnOffUsingSubId(long subId) { 10647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 106536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).setRadioPower(!isRadioOnUsingSubId(subId)); 10667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 106736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 10687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean setRadio(boolean turnOn) { 106936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return setRadioUsingSubId(getDefaultSubscription(), turnOn); 107036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 107136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 107236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean setRadioUsingSubId(long subId, boolean turnOn) { 10737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 107436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville if ((getPhone(subId).getServiceState().getState() != 107536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville ServiceState.STATE_POWER_OFF) != turnOn) { 107636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville toggleRadioOnOffUsingSubId(subId); 10777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 10797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 108036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 10811fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla public boolean needMobileRadioShutdown() { 10821fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla /* 10831fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla * If any of the Radios are available, it will need to be 10841fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla * shutdown. So return true if any Radio is available. 10851fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla */ 10861fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { 10871fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla Phone phone = PhoneFactory.getPhone(i); 10881fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla if (phone != null && phone.isRadioAvailable()) return true; 10891fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 10901fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown."); 10911fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla return false; 10921fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 10931fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla 10941fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla public void shutdownMobileRadios() { 10951fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { 10961fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla logv("Shutting down Phone " + i); 10971fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla shutdownRadioUsingPhoneId(i); 10981fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 10991fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 11001fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla 11011fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla private void shutdownRadioUsingPhoneId(int phoneId) { 11021fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla enforceModifyPermission(); 11031fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla Phone phone = PhoneFactory.getPhone(phoneId); 11041fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla if (phone != null && phone.isRadioAvailable()) { 11051fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla phone.shutdownRadio(); 11061fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 11071fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 11081fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla 11097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean setRadioPower(boolean turnOn) { 111036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return setRadioPowerUsingSubId(getDefaultSubscription(), turnOn); 111136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 111236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 111336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean setRadioPowerUsingSubId(long subId, boolean turnOn) { 11147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 111536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).setRadioPower(turnOn); 11167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 11177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 111936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // FIXME: subId version needed 11207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean enableDataConnectivity() { 11217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 112236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville long subId = SubscriptionManager.getDefaultDataSubId(); 112336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).setDataEnabled(true); 11247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 11257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 112736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // FIXME: subId version needed 11287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean disableDataConnectivity() { 11297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 113036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville long subId = SubscriptionManager.getDefaultDataSubId(); 113136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).setDataEnabled(false); 11327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 11337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 113536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // FIXME: subId version needed 11367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isDataConnectivityPossible() { 113736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville long subId = SubscriptionManager.getDefaultDataSubId(); 113836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).isDataConnectivityPossible(); 11397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean handlePinMmi(String dialString) { 114236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return handlePinMmiUsingSubId(getDefaultSubscription(), dialString); 114336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 114436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 114536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean handlePinMmiUsingSubId(long subId, String dialString) { 11467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 114736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId); 11487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getCallState() { 115136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getCallStateUsingSubId(getDefaultSubscription()); 115236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 115336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 115436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getCallStateUsingSubId(long subId) { 115536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return DefaultPhoneNotifier.convertCallState(getPhone(subId).getState()); 11567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getDataState() { 115936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville Phone phone = getPhone(SubscriptionManager.getDefaultDataSubId()); 116036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return DefaultPhoneNotifier.convertDataState(phone.getDataConnectionState()); 11617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getDataActivity() { 116436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville Phone phone = getPhone(SubscriptionManager.getDefaultDataSubId()); 116536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState()); 11667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 11697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public Bundle getCellLocation() { 11707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 11717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 11727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_FINE_LOCATION, null); 11737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (SecurityException e) { 11747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If we have ACCESS_FINE_LOCATION permission, skip the check for ACCESS_COARSE_LOCATION 11757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // A failure should throw the SecurityException from ACCESS_COARSE_LOCATION since this 11767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // is the weaker precondition 11777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 11787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 11797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1181e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (checkIfCallerIsSelfOrForegroundUser()) { 11827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getCellLocation: is active user"); 11837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Bundle data = new Bundle(); 11847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.getCellLocation().fillInNotifierBundle(data); 11857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return data; 11867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 11877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getCellLocation: suppress non-active user"); 11887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 11897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 11937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void enableLocationUpdates() { 119436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville enableLocationUpdatesUsingSubId(getDefaultSubscription()); 119536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 119636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 119736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void enableLocationUpdatesUsingSubId(long subId) { 11987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 11997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.CONTROL_LOCATION_UPDATES, null); 120036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).enableLocationUpdates(); 12017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 12047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void disableLocationUpdates() { 120536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville disableLocationUpdatesUsingSubId(getDefaultSubscription()); 120636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 120736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 120836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void disableLocationUpdatesUsingSubId(long subId) { 12097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 12107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.CONTROL_LOCATION_UPDATES, null); 121136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).disableLocationUpdates(); 12127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 12157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @SuppressWarnings("unchecked") 12167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage) { 12177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 12187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 12197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_FINE_LOCATION, null); 12207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (SecurityException e) { 12217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If we have ACCESS_FINE_LOCATION permission, skip the check 12227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // for ACCESS_COARSE_LOCATION 12237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // A failure should throw the SecurityException from 12247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ACCESS_COARSE_LOCATION since this is the weaker precondition 12257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 12267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 12277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(), 12307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon callingPackage) != AppOpsManager.MODE_ALLOWED) { 12317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 12327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1233e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (checkIfCallerIsSelfOrForegroundUser()) { 12347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getNeighboringCellInfo: is active user"); 12357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ArrayList<NeighboringCellInfo> cells = null; 12377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 12397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon cells = (ArrayList<NeighboringCellInfo>) sendRequest( 124036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville CMD_HANDLE_NEIGHBORING_CELL, null, null); 12417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (RuntimeException e) { 124236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville Log.e(LOG_TAG, "getNeighboringCellInfo " + e); 12437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return cells; 12457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 12467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getNeighboringCellInfo: suppress non-active user"); 12477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 12487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 12537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public List<CellInfo> getAllCellInfo() { 12547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 12557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 12567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_FINE_LOCATION, null); 12577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (SecurityException e) { 12587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If we have ACCESS_FINE_LOCATION permission, skip the check for ACCESS_COARSE_LOCATION 12597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // A failure should throw the SecurityException from ACCESS_COARSE_LOCATION since this 12607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // is the weaker precondition 12617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 12627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 12637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1265e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (checkIfCallerIsSelfOrForegroundUser()) { 12667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getAllCellInfo: is active user"); 12677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getAllCellInfo(); 12687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 12697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getAllCellInfo: suppress non-active user"); 12707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 12717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1274bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal @Override 12757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void setCellInfoListRate(int rateInMillis) { 12767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.setCellInfoListRate(rateInMillis); 12777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 12807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Internal helper methods. 12817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 12827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1283e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static boolean checkIfCallerIsSelfOrForegroundUser() { 12847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean ok; 12857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean self = Binder.getCallingUid() == Process.myUid(); 12877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!self) { 12887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Get the caller's user id then clear the calling identity 12897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // which will be restored in the finally clause. 12907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int callingUser = UserHandle.getCallingUserId(); 12917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon long ident = Binder.clearCallingIdentity(); 12927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 12947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // With calling identity cleared the current user is the foreground user. 12957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int foregroundUser = ActivityManager.getCurrentUser(); 12967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ok = (foregroundUser == callingUser); 12977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) { 12987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon log("checkIfCallerIsSelfOrForegoundUser: foregroundUser=" + foregroundUser 12997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon + " callingUser=" + callingUser + " ok=" + ok); 13007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (Exception ex) { 13027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) loge("checkIfCallerIsSelfOrForegoundUser: Exception ex=" + ex); 13037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ok = false; 13047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } finally { 13057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Binder.restoreCallingIdentity(ident); 13067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 13087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("checkIfCallerIsSelfOrForegoundUser: is self"); 13097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ok = true; 13107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("checkIfCallerIsSelfOrForegoundUser: ret=" + ok); 13127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return ok; 13137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 13167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make sure the caller has the READ_PHONE_STATE permission. 13177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 13187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @throws SecurityException if the caller does not have the required permission 13197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 13207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void enforceReadPermission() { 13217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE, null); 13227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 13257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make sure the caller has the MODIFY_PHONE_STATE permission. 13267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 13277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @throws SecurityException if the caller does not have the required permission 13287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 13297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void enforceModifyPermission() { 13307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null); 13317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1334a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * Make sure either system app or the caller has carrier privilege. 1335a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * 1336a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * @throws SecurityException if the caller does not have the required permission/privilege 1337a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu */ 1338a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu private void enforceModifyPermissionOrCarrierPrivilege() { 1339f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal int permission = mApp.checkCallingOrSelfPermission( 1340f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal android.Manifest.permission.MODIFY_PHONE_STATE); 1341f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal if (permission == PackageManager.PERMISSION_GRANTED) { 1342f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal return; 1343f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal } 1344f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal 1345f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal log("No modify permission, check carrier privilege next."); 1346f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal if (hasCarrierPrivileges() != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 1347f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal loge("No Carrier Privilege."); 1348f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal throw new SecurityException("No modify permission or carrier privilege."); 1349a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu } 1350a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu } 1351a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu 1352a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu /** 1353a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * Make sure the caller has carrier privilege. 1354a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * 1355a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * @throws SecurityException if the caller does not have the required permission 1356a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu */ 1357a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu private void enforceCarrierPrivilege() { 1358a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu if (hasCarrierPrivileges() != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 1359f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal loge("No Carrier Privilege."); 1360f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal throw new SecurityException("No Carrier Privilege."); 1361a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu } 1362a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu } 1363a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu 1364a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu /** 13657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make sure the caller has the CALL_PHONE permission. 13667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 13677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @throws SecurityException if the caller does not have the required permission 13687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 13697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void enforceCallPermission() { 13707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null); 13717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1373566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal /** 137436ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal * Make sure the caller has the READ_PRIVILEGED_PHONE_STATE permission. 137536ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal * 137636ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal * @throws SecurityException if the caller does not have the required permission 137736ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal */ 137836ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal private void enforcePrivilegedPhoneStatePermission() { 137936ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 138036ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal null); 138136ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal } 138236ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal 13837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private String createTelUrl(String number) { 13847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (TextUtils.isEmpty(number)) { 13857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 13867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1388e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return "tel:" + number; 13897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1391f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad private static void log(String msg) { 13927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg); 13937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13951fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla private static void logv(String msg) { 13961fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg); 13971fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 13981fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla 1399f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad private static void loge(String msg) { 14007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg); 14017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getActivePhoneType() { 140436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getActivePhoneTypeUsingSubId(getDefaultSubscription()); 140536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 140636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 140736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getActivePhoneTypeUsingSubId(long subId) { 140836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getPhoneType(); 14097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 14127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the CDMA ERI icon index to display 14137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 14147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getCdmaEriIconIndex() { 141536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getCdmaEriIconIndexUsingSubId(getDefaultSubscription()); 141636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 141736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 141836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 141936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getCdmaEriIconIndexUsingSubId(long subId) { 142036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getCdmaEriIconIndex(); 14217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 14247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the CDMA ERI icon mode, 14257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 0 - ON 14267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 1 - FLASHING 14277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 14287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getCdmaEriIconMode() { 142936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getCdmaEriIconModeUsingSubId(getDefaultSubscription()); 143036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 143136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 143236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getCdmaEriIconModeUsingSubId(long subId) { 143336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getCdmaEriIconMode(); 14347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 14377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the CDMA ERI text, 14387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 14397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public String getCdmaEriText() { 144036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getCdmaEriTextUsingSubId(getDefaultSubscription()); 144136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 144236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 144336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public String getCdmaEriTextUsingSubId(long subId) { 144436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getCdmaEriText(); 14457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1448ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu * Returns the CDMA MDN. 1449ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu */ 1450ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu public String getCdmaMdn(long subId) { 1451ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1452ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 1453ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu return getPhone(subId).getLine1Number(); 1454ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu } else { 1455ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu return null; 1456ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu } 1457ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu } 1458ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu 1459ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu /** 1460ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu * Returns the CDMA MIN. 1461ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu */ 1462ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu public String getCdmaMin(long subId) { 1463ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1464ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 1465ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu return getPhone(subId).getCdmaMin(); 1466ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu } else { 1467ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu return null; 1468ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu } 1469ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu } 1470ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu 1471ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu /** 14727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns true if CDMA provisioning needs to run. 14737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 14747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean needsOtaServiceProvisioning() { 14757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.needsOtaServiceProvisioning(); 14767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 14797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the unread count of voicemails 14807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 14817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getVoiceMessageCount() { 148236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getVoiceMessageCountUsingSubId(getDefaultSubscription()); 148336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 148436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 148536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 148636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns the unread count of voicemails for a subId 148736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 148836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getVoiceMessageCountUsingSubId( long subId) { 148936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getVoiceMessageCount(); 14907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 14937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the data network type 14947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 14957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @Deprecated to be removed Q3 2013 use {@link #getDataNetworkType}. 14967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 14977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 14987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getNetworkType() { 149936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getNetworkTypeUsingSubId(getDefaultSubscription()); 150036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 150136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 150236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 150336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns the network type for a subId 150436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 150536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville @Override 150636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getNetworkTypeUsingSubId(long subId) { 150736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getServiceState().getDataNetworkType(); 15087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 15117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the data network type 15127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 15137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 15147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getDataNetworkType() { 151536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getDataNetworkTypeUsingSubId(getDefaultSubscription()); 151636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 151736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 151836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 151936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns the data network type for a subId 152036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 152136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville @Override 152236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getDataNetworkTypeUsingSubId(long subId) { 152336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getServiceState().getDataNetworkType(); 15247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 15277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the data network type 15287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 15297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 15307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getVoiceNetworkType() { 153136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getVoiceNetworkTypeUsingSubId(getDefaultSubscription()); 153236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 153336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 153436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 153536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns the Voice network type for a subId 153636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 153736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville @Override 153836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getVoiceNetworkTypeUsingSubId(long subId) { 153936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getServiceState().getVoiceNetworkType(); 15407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 15437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return true if a ICC card is present 15447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 15457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean hasIccCard() { 154636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // FIXME Make changes to pass defaultSimId of type int 154736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return hasIccCardUsingSlotId(getDefaultSubscription()); 154836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 154936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 155036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 155136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * @return true if a ICC card is present for a slotId 155236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 155336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean hasIccCardUsingSlotId(long slotId) { 155436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(slotId).getIccCard().hasIccCard(); 15557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 15587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Return if the current radio is LTE on CDMA. This 15597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * is a tri-state return value as for a period of time 15607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * the mode may be unknown. 15617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 15627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE} 1563e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * or {@link Phone#LTE_ON_CDMA_TRUE} 15647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 15657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getLteOnCdmaMode() { 156636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getLteOnCdmaModeUsingSubId(getDefaultSubscription()); 156736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 156836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 156936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getLteOnCdmaModeUsingSubId(long subId) { 157036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getLteOnCdmaMode(); 157136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 157236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 157336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void setPhone(Phone phone) { 157436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville mPhone = phone; 157536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 157636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 157736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 157836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * {@hide} 157936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns Default subId, 0 in the case of single standby. 158036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 158136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville private long getDefaultSubscription() { 158236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return SubscriptionManager.getDefaultSubId(); 158336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 158436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 158536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville private long getPreferredVoiceSubscription() { 158636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return SubscriptionManager.getDefaultVoiceSubId(); 15877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1588f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad 1589f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad /** 1590f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad * @see android.telephony.TelephonyManager.WifiCallingChoices 1591f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad */ 1592f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad public int getWhenToMakeWifiCalls() { 1593d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal return Settings.System.getInt(mPhone.getContext().getContentResolver(), 1594d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal Settings.System.WHEN_TO_MAKE_WIFI_CALLS, getWhenToMakeWifiCallsDefaultPreference()); 1595f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad } 1596f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad 1597f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad /** 1598f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad * @see android.telephony.TelephonyManager.WifiCallingChoices 1599f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad */ 1600f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad public void setWhenToMakeWifiCalls(int preference) { 1601d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference); 1602d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal Settings.System.putInt(mPhone.getContext().getContentResolver(), 1603d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference); 1604f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad } 1605f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad 1606d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal private static int getWhenToMakeWifiCallsDefaultPreference() { 1607da120f4e3d32ca97c5b4c21d6c505d834a29ab8dSantos Cordon // TODO: Use a build property to choose this value. 16089829e880f73f76119ba76ba032db42aad042858fEvan Charlton return TelephonyManager.WifiCallingChoices.ALWAYS_USE; 1609f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad } 161069f68120b94cecb2d87fe856bc115714b4e77bcdShishir Agrawal 1611566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal @Override 1612da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal public IccOpenLogicalChannelResponse iccOpenLogicalChannel(String AID) { 1613a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1614566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1615566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccOpenLogicalChannel: " + AID); 1616da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse)sendRequest( 1617da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal CMD_OPEN_CHANNEL, AID); 1618da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (DBG) log("iccOpenLogicalChannel: " + response); 1619da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal return response; 1620566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1621566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1622566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal @Override 1623566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public boolean iccCloseLogicalChannel(int channel) { 1624a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1625566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1626566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccCloseLogicalChannel: " + channel); 1627566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (channel < 0) { 1628566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return false; 1629566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1630e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean)sendRequest(CMD_CLOSE_CHANNEL, channel); 1631566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccCloseLogicalChannel: " + success); 1632566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return success; 1633566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1634566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1635566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal @Override 1636566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public String iccTransmitApduLogicalChannel(int channel, int cla, 1637566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal int command, int p1, int p2, int p3, String data) { 1638a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1639566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1640566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) { 1641566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal log("iccTransmitApduLogicalChannel: chnl=" + channel + " cla=" + cla + 1642566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + 1643566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal " data=" + data); 1644566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1645566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1646566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (channel < 0) { 1647566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return ""; 1648566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1649566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1650da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccIoResult response = (IccIoResult)sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL, 1651566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal new IccAPDUArgument(channel, cla, command, p1, p2, p3, data)); 1652566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccTransmitApduLogicalChannel: " + response); 1653566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1654566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal // Append the returned status code to the end of the response payload. 1655566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal String s = Integer.toHexString( 1656566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 16575ec14172e42d180d7dd6110ef8eb1dedb0a0a7fbShishir Agrawal if (response.payload != null) { 16585ec14172e42d180d7dd6110ef8eb1dedb0a0a7fbShishir Agrawal s = IccUtils.bytesToHexString(response.payload) + s; 16595ec14172e42d180d7dd6110ef8eb1dedb0a0a7fbShishir Agrawal } 1660566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return s; 1661566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1662e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 1663c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton @Override 1664da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal public String iccTransmitApduBasicChannel(int cla, int command, int p1, int p2, 1665da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal int p3, String data) { 1666da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal enforceModifyPermissionOrCarrierPrivilege(); 1667da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1668da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (DBG) { 1669da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal log("iccTransmitApduBasicChannel: cla=" + cla + " cmd=" + command + " p1=" 1670da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data); 1671da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 1672da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1673da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccIoResult response = (IccIoResult)sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL, 1674da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal new IccAPDUArgument(0, cla, command, p1, p2, p3, data)); 1675da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (DBG) log("iccTransmitApduBasicChannel: " + response); 1676da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1677da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal // Append the returned status code to the end of the response payload. 1678da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal String s = Integer.toHexString( 1679da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 16805ec14172e42d180d7dd6110ef8eb1dedb0a0a7fbShishir Agrawal if (response.payload != null) { 16815ec14172e42d180d7dd6110ef8eb1dedb0a0a7fbShishir Agrawal s = IccUtils.bytesToHexString(response.payload) + s; 16825ec14172e42d180d7dd6110ef8eb1dedb0a0a7fbShishir Agrawal } 1683da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal return s; 1684da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 1685da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1686da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal @Override 1687da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal public byte[] iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3, 1688da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal String filePath) { 1689da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal enforceModifyPermissionOrCarrierPrivilege(); 1690da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1691da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (DBG) { 1692da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal log("Exchange SIM_IO " + fileID + ":" + command + " " + 1693da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal p1 + " " + p2 + " " + p3 + ":" + filePath); 1694da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 1695da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1696da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccIoResult response = 1697da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal (IccIoResult)sendRequest(CMD_EXCHANGE_SIM_IO, 1698da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal new IccAPDUArgument(fileID, command, -1, p1, p2, p3, filePath)); 1699da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1700da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (DBG) { 1701da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal log("Exchange SIM_IO [R]" + response); 1702da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 1703da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1704da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal byte[] result = null; 1705da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal int length = 2; 1706da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (response.payload != null) { 1707da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal length = 2 + response.payload.length; 1708da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal result = new byte[length]; 1709da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal System.arraycopy(response.payload, 0, result, 0, response.payload.length); 1710da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else { 1711da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal result = new byte[length]; 1712da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 1713da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1714da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal result[length - 1] = (byte) response.sw2; 1715da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal result[length - 2] = (byte) response.sw1; 1716da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal return result; 1717da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 1718da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1719da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal @Override 1720c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton public String sendEnvelopeWithStatus(String content) { 1721a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1722c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton 1723c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton IccIoResult response = (IccIoResult)sendRequest(CMD_SEND_ENVELOPE, content); 1724c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton if (response.payload == null) { 1725c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton return ""; 1726c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton } 1727c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton 1728c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton // Append the returned status code to the end of the response payload. 1729c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton String s = Integer.toHexString( 1730c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 1731c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton s = IccUtils.bytesToHexString(response.payload) + s; 1732c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton return s; 1733c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton } 1734c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton 1735e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 1736e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems} 1737e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators. 1738e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 1739e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param itemID the ID of the item to read 1740e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return the NV item as a String, or null on error. 1741e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 1742e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 1743e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public String nvReadItem(int itemID) { 1744a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1745e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvReadItem: item " + itemID); 1746e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID); 1747e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"'); 1748e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return value; 1749e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 1750e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 1751e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 1752e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems} 1753e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators. 1754e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 1755e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param itemID the ID of the item to read 1756e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param itemValue the value to write, as a String 1757e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return true on success; false on any failure 1758e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 1759e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 1760e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public boolean nvWriteItem(int itemID, String itemValue) { 1761a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1762e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"'); 1763e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM, 1764e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby new Pair<Integer, String>(itemID, itemValue)); 1765e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail")); 1766e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return success; 1767e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 1768e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 1769e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 1770e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage. 1771e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Used for device configuration by some CDMA operators. 1772e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 1773e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param preferredRoamingList byte array containing the new PRL 1774e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return true on success; false on any failure 1775e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 1776e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 1777e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) { 1778a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1779e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList)); 1780e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList); 1781e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail")); 1782e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return success; 1783e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 1784e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 1785e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 1786e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Perform the specified type of NV config reset. 1787e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Used for device configuration by some CDMA operators. 1788e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 1789e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset) 1790e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return true on success; false on any failure 1791e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 1792e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 1793e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public boolean nvResetConfig(int resetType) { 1794a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1795e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvResetConfig: type " + resetType); 1796e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean) sendRequest(CMD_NV_RESET_CONFIG, resetType); 1797e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvResetConfig: type " + resetType + ' ' + (success ? "ok" : "fail")); 1798e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return success; 1799e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 18007c27be317e8757948178815426d3a329c852b9eeJake Hamby 18017c27be317e8757948178815426d3a329c852b9eeJake Hamby /** 180236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * {@hide} 180336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns Default sim, 0 in the case of single standby. 180436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 180536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getDefaultSim() { 180636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville //TODO Need to get it from Telephony Devcontroller 180736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return 0; 180836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 180936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 181087fca6f34c10e43e4dcfdd3f4e35bd4050e19582ram public String[] getPcscfAddress(String apnType) { 181136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville enforceReadPermission(); 181287fca6f34c10e43e4dcfdd3f4e35bd4050e19582ram return mPhone.getPcscfAddress(apnType); 181336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 181436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 181536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void setImsRegistrationState(boolean registered) { 181636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville enforceModifyPermission(); 181736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville mPhone.setImsRegistrationState(registered); 181836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 181936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 182036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 182184d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu * Get the calculated preferred network type. 182284d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu * Used for debugging incorrect network type. 182384d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu * 182484d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu * @return the preferred network type, defined in RILConstants.java. 182584d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu */ 182684d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu @Override 182784d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu public int getCalculatedPreferredNetworkType() { 182884d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu enforceReadPermission(); 182984d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu return PhoneFactory.calculatePreferredNetworkType(mPhone.getContext()); 183084d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu } 183184d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu 183284d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu /** 18337c27be317e8757948178815426d3a329c852b9eeJake Hamby * Get the preferred network type. 18347c27be317e8757948178815426d3a329c852b9eeJake Hamby * Used for device configuration by some CDMA operators. 18357c27be317e8757948178815426d3a329c852b9eeJake Hamby * 18367c27be317e8757948178815426d3a329c852b9eeJake Hamby * @return the preferred network type, defined in RILConstants.java. 18377c27be317e8757948178815426d3a329c852b9eeJake Hamby */ 18387c27be317e8757948178815426d3a329c852b9eeJake Hamby @Override 18397c27be317e8757948178815426d3a329c852b9eeJake Hamby public int getPreferredNetworkType() { 1840a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 18417c27be317e8757948178815426d3a329c852b9eeJake Hamby if (DBG) log("getPreferredNetworkType"); 18427c27be317e8757948178815426d3a329c852b9eeJake Hamby int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null); 18437c27be317e8757948178815426d3a329c852b9eeJake Hamby int networkType = (result != null ? result[0] : -1); 18447c27be317e8757948178815426d3a329c852b9eeJake Hamby if (DBG) log("getPreferredNetworkType: " + networkType); 18457c27be317e8757948178815426d3a329c852b9eeJake Hamby return networkType; 18467c27be317e8757948178815426d3a329c852b9eeJake Hamby } 18477c27be317e8757948178815426d3a329c852b9eeJake Hamby 18487c27be317e8757948178815426d3a329c852b9eeJake Hamby /** 18497c27be317e8757948178815426d3a329c852b9eeJake Hamby * Set the preferred network type. 18507c27be317e8757948178815426d3a329c852b9eeJake Hamby * Used for device configuration by some CDMA operators. 18517c27be317e8757948178815426d3a329c852b9eeJake Hamby * 18527c27be317e8757948178815426d3a329c852b9eeJake Hamby * @param networkType the preferred network type, defined in RILConstants.java. 18537c27be317e8757948178815426d3a329c852b9eeJake Hamby * @return true on success; false on any failure. 18547c27be317e8757948178815426d3a329c852b9eeJake Hamby */ 18557c27be317e8757948178815426d3a329c852b9eeJake Hamby @Override 18567c27be317e8757948178815426d3a329c852b9eeJake Hamby public boolean setPreferredNetworkType(int networkType) { 1857a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 18587c27be317e8757948178815426d3a329c852b9eeJake Hamby if (DBG) log("setPreferredNetworkType: type " + networkType); 18597c27be317e8757948178815426d3a329c852b9eeJake Hamby Boolean success = (Boolean) sendRequest(CMD_SET_PREFERRED_NETWORK_TYPE, networkType); 18607c27be317e8757948178815426d3a329c852b9eeJake Hamby if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail")); 186180bc0d1614b46c89fa7a2c1d68fdb3ccb018625dJunda Liu if (success) { 186280bc0d1614b46c89fa7a2c1d68fdb3ccb018625dJunda Liu Settings.Global.putInt(mPhone.getContext().getContentResolver(), 186380bc0d1614b46c89fa7a2c1d68fdb3ccb018625dJunda Liu Settings.Global.PREFERRED_NETWORK_MODE, networkType); 186480bc0d1614b46c89fa7a2c1d68fdb3ccb018625dJunda Liu } 18657c27be317e8757948178815426d3a329c852b9eeJake Hamby return success; 18667c27be317e8757948178815426d3a329c852b9eeJake Hamby } 1867ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt 1868ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt /** 1869ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * Set mobile data enabled 1870ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * Used by the user through settings etc to turn on/off mobile data 1871ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * 1872ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * @param enable {@code true} turn turn data on, else {@code false} 1873ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt */ 1874ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt @Override 1875ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt public void setDataEnabled(boolean enable) { 1876ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt enforceModifyPermission(); 1877ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt mPhone.setDataEnabled(enable); 1878ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt } 1879ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt 1880ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt /** 1881646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * Get whether mobile data is enabled. 1882646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * 1883646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * Note that this used to be available from ConnectivityService, gated by 1884646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * ACCESS_NETWORK_STATE permission, so this will accept either that or 1885646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * our MODIFY_PHONE_STATE. 1886ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * 1887ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * @return {@code true} if data is enabled else {@code false} 1888ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt */ 1889ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt @Override 1890ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt public boolean getDataEnabled() { 1891646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt try { 1892646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE, 1893646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt null); 1894646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt } catch (Exception e) { 1895646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, 1896646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt null); 1897646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt } 1898ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt return mPhone.getDataEnabled(); 1899ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt } 190060f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawal 190160f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawal @Override 190260f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawal public int hasCarrierPrivileges() { 1903eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal UiccCard card = UiccController.getInstance().getUiccCard(); 1904eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (card == null) { 1905eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("hasCarrierPrivileges: No UICC"); 1906eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 1907eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 1908eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal return card.getCarrierPrivilegeStatusForCurrentTransaction( 1909f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal mPhone.getContext().getPackageManager()); 191060f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawal } 19112934034e04c5ca7839de41d0cc8f8bab89b1e336Junda Liu 19122934034e04c5ca7839de41d0cc8f8bab89b1e336Junda Liu @Override 19136d5a285c9ebe1d3a6952542b6cad3d6df51ac298Shishir Agrawal public int checkCarrierPrivilegesForPackage(String pkgname) { 1914eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal UiccCard card = UiccController.getInstance().getUiccCard(); 1915eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (card == null) { 1916eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("checkCarrierPrivilegesForPackage: No UICC"); 1917eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 1918eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 1919eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal return card.getCarrierPrivilegeStatus(mPhone.getContext().getPackageManager(), pkgname); 19202934034e04c5ca7839de41d0cc8f8bab89b1e336Junda Liu } 192189e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan 192289e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan @Override 1923af74c86463b193100a48a0a2b83d0096863bf110Diego Pontoriero public List<String> getCarrierPackageNamesForIntent(Intent intent) { 1924eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal UiccCard card = UiccController.getInstance().getUiccCard(); 1925eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal if (card == null) { 1926af74c86463b193100a48a0a2b83d0096863bf110Diego Pontoriero loge("getCarrierPackageNamesForIntent: No UICC"); 1927eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal return null ; 1928eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal } 1929af74c86463b193100a48a0a2b83d0096863bf110Diego Pontoriero return card.getCarrierPackageNamesForIntent( 1930eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal mPhone.getContext().getPackageManager(), intent); 1931eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal } 1932eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal 193397ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan private String getIccId(long subId) { 193497ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan UiccCard card = getPhone(subId).getUiccCard(); 193597ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan if (card == null) { 193697ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan loge("getIccId: No UICC"); 193797ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return null; 193897ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } 193997ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String iccId = card.getIccId(); 194097ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan if (TextUtils.isEmpty(iccId)) { 194197ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan loge("getIccId: ICC ID is null or empty."); 194297ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return null; 194397ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } 194497ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return iccId; 194597ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } 194697ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan 1947eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal @Override 194889e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan public void enableSimplifiedNetworkSettings(long subId, boolean enable) { 1949352d8cdf7ed125668d865f61172abfc31835c5a9Derek Tan enforceModifyPermissionOrCarrierPrivilege(); 195097ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan 195197ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String iccId = getIccId(subId); 195297ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan if (iccId != null) { 195397ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String snsPrefKey = PREF_CARRIERS_SIMPLIFIED_NETWORK_SETTINGS_PREFIX + iccId; 195497ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan SharedPreferences.Editor editor = carrierPrivilegeConfigs.edit(); 195597ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan if (enable) { 195697ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan editor.putBoolean(snsPrefKey, true); 195797ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } else { 195897ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan editor.remove(snsPrefKey); 195997ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } 196097ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan editor.commit(); 196189e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan } 196289e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan } 196389e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan 196489e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan @Override 196589e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan public boolean getSimplifiedNetworkSettingsEnabled(long subId) { 196689e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan enforceReadPermission(); 196797ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String iccId = getIccId(subId); 196897ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan if (iccId != null) { 196997ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String snsPrefKey = PREF_CARRIERS_SIMPLIFIED_NETWORK_SETTINGS_PREFIX + iccId; 197097ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return carrierPrivilegeConfigs.getBoolean(snsPrefKey, false); 197197ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } 197297ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return false; 197389e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan } 19747226c84acb402f96e527650347391fa025294350Derek Tan 19757226c84acb402f96e527650347391fa025294350Derek Tan @Override 19767226c84acb402f96e527650347391fa025294350Derek Tan public void setLine1NumberForDisplay(long subId, String alphaTag, String number) { 1977352d8cdf7ed125668d865f61172abfc31835c5a9Derek Tan enforceModifyPermissionOrCarrierPrivilege(); 197897ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan 197997ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String iccId = getIccId(subId); 198097ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan if (iccId != null) { 198197ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId; 198297ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan SharedPreferences.Editor editor = carrierPrivilegeConfigs.edit(); 198397ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan if (alphaTag == null) { 198497ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan editor.remove(alphaTagPrefKey); 198597ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } else { 198697ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan editor.putString(alphaTagPrefKey, alphaTag); 198797ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } 198897ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan 198997ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId; 199097ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan if (number == null) { 199197ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan editor.remove(numberPrefKey); 199297ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } else { 199397ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan editor.putString(numberPrefKey, number); 199497ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } 199597ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan editor.commit(); 199697ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } 19977226c84acb402f96e527650347391fa025294350Derek Tan } 19987226c84acb402f96e527650347391fa025294350Derek Tan 19997226c84acb402f96e527650347391fa025294350Derek Tan @Override 20007226c84acb402f96e527650347391fa025294350Derek Tan public String getLine1NumberForDisplay(long subId) { 20017226c84acb402f96e527650347391fa025294350Derek Tan enforceReadPermission(); 200297ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan 200397ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String iccId = getIccId(subId); 200497ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan if (iccId != null) { 200597ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId; 200697ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return carrierPrivilegeConfigs.getString(numberPrefKey, null); 20077226c84acb402f96e527650347391fa025294350Derek Tan } 200897ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return null; 20097226c84acb402f96e527650347391fa025294350Derek Tan } 20107226c84acb402f96e527650347391fa025294350Derek Tan 20117226c84acb402f96e527650347391fa025294350Derek Tan @Override 20127226c84acb402f96e527650347391fa025294350Derek Tan public String getLine1AlphaTagForDisplay(long subId) { 20137226c84acb402f96e527650347391fa025294350Derek Tan enforceReadPermission(); 201497ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan 201597ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String iccId = getIccId(subId); 201697ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan if (iccId != null) { 201797ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId; 201897ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return carrierPrivilegeConfigs.getString(alphaTagPrefKey, null); 20197226c84acb402f96e527650347391fa025294350Derek Tan } 202097ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return null; 20217226c84acb402f96e527650347391fa025294350Derek Tan } 2022b1ebf8c3755b7e1cb207cbd49f6c8bdfa3566668Shishir Agrawal 2023b1ebf8c3755b7e1cb207cbd49f6c8bdfa3566668Shishir Agrawal @Override 2024a3dfd75141d37ae7e170eeb200374f62235b092eShishir Agrawal public boolean setOperatorBrandOverride(String brand) { 2025b1ebf8c3755b7e1cb207cbd49f6c8bdfa3566668Shishir Agrawal enforceModifyPermissionOrCarrierPrivilege(); 2026a3dfd75141d37ae7e170eeb200374f62235b092eShishir Agrawal return mPhone.setOperatorBrandOverride(brand); 2027b1ebf8c3755b7e1cb207cbd49f6c8bdfa3566668Shishir Agrawal } 20284bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu 20294bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu @Override 20304bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) { 20314bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu enforceModifyPermission(); 20324bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu 20334bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu int returnValue = 0; 20344bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu try { 20354bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu AsyncResult result = (AsyncResult)sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq); 20364bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu if(result.exception == null) { 20374bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu if (result.result != null) { 20384bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu byte[] responseData = (byte[])(result.result); 20394bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu if(responseData.length > oemResp.length) { 20404bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " + 20414bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu responseData.length + "bytes. Buffer Size is " + 20424bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu oemResp.length + "bytes."); 20434bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } 20444bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu System.arraycopy(responseData, 0, oemResp, 0, responseData.length); 20454bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu returnValue = responseData.length; 20464bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } 20474bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } else { 20484bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu CommandException ex = (CommandException) result.exception; 20494bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu returnValue = ex.getCommandError().ordinal(); 20504bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu if(returnValue > 0) returnValue *= -1; 20514bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } 20524bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } catch (RuntimeException e) { 20534bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception"); 20544bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal()); 20554bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu if(returnValue > 0) returnValue *= -1; 20564bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } 20574bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu 20584bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu return returnValue; 20594bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } 20607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon} 2061