PhoneInterfaceManager.java revision eb6439a7bd453313f7ed7972d30e2478243801ff
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; 2460f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawalimport android.content.pm.PackageInfo; 2560f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawalimport android.content.pm.PackageManager; 2660f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawalimport android.content.pm.Signature; 2736469e74b7c79ed84148754190c38196eb9a2c49Wink Savilleimport android.net.ConnectivityManager; 287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.net.Uri; 297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.AsyncResult; 307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Binder; 317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Bundle; 327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Handler; 3336ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport android.os.IBinder; 347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Looper; 357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Message; 367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Process; 3736ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport android.os.RemoteException; 387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.ServiceManager; 397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.UserHandle; 40f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awadimport android.provider.Settings; 417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.telephony.CellInfo; 42e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport android.telephony.NeighboringCellInfo; 437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.telephony.ServiceState; 4436469e74b7c79ed84148754190c38196eb9a2c49Wink Savilleimport android.telephony.SubscriptionManager; 45f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awadimport android.telephony.TelephonyManager; 467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.text.TextUtils; 477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.util.Log; 48e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport android.util.Pair; 497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 50566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.CallManager; 51566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.CommandException; 5236ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport com.android.internal.telephony.Connection; 537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.DefaultPhoneNotifier; 547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.ITelephony; 55e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport com.android.internal.telephony.IccCard; 567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.Phone; 5736469e74b7c79ed84148754190c38196eb9a2c49Wink Savilleimport com.android.internal.telephony.PhoneFactory; 5836469e74b7c79ed84148754190c38196eb9a2c49Wink Savilleimport com.android.internal.telephony.CallManager; 5936469e74b7c79ed84148754190c38196eb9a2c49Wink Savilleimport com.android.internal.telephony.CommandException; 607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.PhoneConstants; 6136469e74b7c79ed84148754190c38196eb9a2c49Wink Savilleimport com.android.internal.telephony.dataconnection.DctController; 627226c84acb402f96e527650347391fa025294350Derek Tanimport com.android.internal.telephony.uicc.AdnRecord; 63566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.uicc.IccIoResult; 64566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.uicc.IccUtils; 65eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawalimport com.android.internal.telephony.uicc.UiccCard; 6660f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawalimport com.android.internal.telephony.uicc.UiccCarrierPrivilegeRules; 67566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.uicc.UiccController; 68e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport com.android.internal.util.HexDump; 697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7036469e74b7c79ed84148754190c38196eb9a2c49Wink Savilleimport static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY; 7136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport java.util.ArrayList; 7336ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport java.util.HashMap; 7489e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tanimport java.util.HashSet; 7536ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport java.util.Iterator; 76e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport java.util.List; 7736ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport java.util.Map; 7889e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tanimport java.util.Set; 797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon/** 817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Implementation of the ITelephony interface. 827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 83117fee7467c140dccdc66972f60031dae2d55b35Santos Cordonpublic class PhoneInterfaceManager extends ITelephony.Stub { 847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final String LOG_TAG = "PhoneInterfaceManager"; 857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2); 867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final boolean DBG_LOC = false; 877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Message codes used with mMainThreadHandler 897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_HANDLE_PIN_MMI = 1; 907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_HANDLE_NEIGHBORING_CELL = 2; 917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int EVENT_NEIGHBORING_CELL_DONE = 3; 927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_ANSWER_RINGING_CALL = 4; 937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_END_CALL = 5; // not used yet 947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_SILENCE_RINGER = 6; 95566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int CMD_TRANSMIT_APDU = 7; 96566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int EVENT_TRANSMIT_APDU_DONE = 8; 97566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int CMD_OPEN_CHANNEL = 9; 98566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int EVENT_OPEN_CHANNEL_DONE = 10; 99566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int CMD_CLOSE_CHANNEL = 11; 100566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int EVENT_CLOSE_CHANNEL_DONE = 12; 101e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_READ_ITEM = 13; 102e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_READ_ITEM_DONE = 14; 103e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_WRITE_ITEM = 15; 104e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_WRITE_ITEM_DONE = 16; 105e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_WRITE_CDMA_PRL = 17; 106e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18; 107e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_RESET_CONFIG = 19; 108e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_RESET_CONFIG_DONE = 20; 1097c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21; 1107c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22; 1117c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23; 1127c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24; 11335b5945231af96ad0d7ebf4cfcaafeb677d8c75cSailesh Nepal private static final int CMD_SEND_ENVELOPE = 25; 11435b5945231af96ad0d7ebf4cfcaafeb677d8c75cSailesh Nepal private static final int EVENT_SEND_ENVELOPE_DONE = 26; 115787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu private static final int CMD_SET_CDMA_SUBSCRIPTION = 27; 116787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu private static final int EVENT_SET_CDMA_SUBSCRIPTION_DONE = 28; 1177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The singleton instance. */ 1197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static PhoneInterfaceManager sInstance; 1207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneGlobals mApp; 1227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Phone mPhone; 1237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CallManager mCM; 1247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AppOpsManager mAppOps; 1257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon MainThreadHandler mMainThreadHandler; 1267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 12889e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan * Indicates if Android should display a simplified Mobile Network Settings UI in a specific 12989e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan * subscription. 13089e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan */ 13189e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan Set<Long> mSimplifiedNetworkSettings; 1327226c84acb402f96e527650347391fa025294350Derek Tan Map<Long, AdnRecord> mAdnRecordsForDisplay; 13389e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan 13489e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan /** 135566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal * A request object to use for transmitting data to an ICC. 136566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal */ 137566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final class IccAPDUArgument { 138566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public int channel, cla, command, p1, p2, p3; 139566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public String data; 140566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 141566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public IccAPDUArgument(int channel, int cla, int command, 142566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal int p1, int p2, int p3, String data) { 143566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.channel = channel; 144566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.cla = cla; 145566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.command = command; 146566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.p1 = p1; 147566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.p2 = p2; 148566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.p3 = p3; 149566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.data = data; 150566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 151566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 152566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 153566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal /** 1547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the 1557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * request after sending. The main thread will notify the request when it is complete. 1567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 1577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final class MainThreadRequest { 1587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The argument to use for the request */ 1597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public Object argument; 1607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The result of the request that is run on the main thread */ 1617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public Object result; 1627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public MainThreadRequest(Object argument) { 1647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon this.argument = argument; 1657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 168cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal private static final class IncomingThirdPartyCallArgs { 169cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public final ComponentName component; 170cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public final String callId; 171cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public final String callerDisplayName; 172cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal 173cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public IncomingThirdPartyCallArgs(ComponentName component, String callId, 174cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal String callerDisplayName) { 175cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal this.component = component; 176cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal this.callId = callId; 177cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal this.callerDisplayName = callerDisplayName; 178cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal } 179cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal } 180cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal 1817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * A handler that processes messages on the main thread in the phone process. Since many 1837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * of the Phone calls are not thread safe this is needed to shuttle the requests from the 1847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * inbound binder threads to the main thread in the phone process. The Binder thread 1857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting 1867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * on, which will be notified when the operation completes and will contain the result of the 1877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * request. 1887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 1897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * <p>If a MainThreadRequest object is provided in the msg.obj field, 1907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * note that request.result must be set to something non-null for the calling thread to 1917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * unblock. 1927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 1937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private final class MainThreadHandler extends Handler { 1947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 1957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void handleMessage(Message msg) { 1967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon MainThreadRequest request; 1977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message onCompleted; 1987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AsyncResult ar; 199eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal UiccCard uiccCard = UiccController.getInstance().getUiccCard(); 2007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon switch (msg.what) { 2027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_HANDLE_PIN_MMI: 2037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) msg.obj; 204e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = mPhone.handlePinMmi((String) request.argument); 2057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wake up the requesting thread 2067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 2077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.notifyAll(); 2087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_HANDLE_NEIGHBORING_CELL: 2127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) msg.obj; 2137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onCompleted = obtainMessage(EVENT_NEIGHBORING_CELL_DONE, 2147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request); 2157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.getNeighboringCids(onCompleted); 2167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case EVENT_NEIGHBORING_CELL_DONE: 2197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ar = (AsyncResult) msg.obj; 2207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) ar.userObj; 2217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (ar.exception == null && ar.result != null) { 2227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.result = ar.result; 2237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 2247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // create an empty list to notify the waiting thread 225e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = new ArrayList<NeighboringCellInfo>(0); 2267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wake up the requesting thread 2287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 2297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.notifyAll(); 2307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_ANSWER_RINGING_CALL: 2347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon answerRingingCallInternal(); 2357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_SILENCE_RINGER: 2387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon silenceRingerInternal(); 2397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_END_CALL: 2427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) msg.obj; 243e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby boolean hungUp; 2447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int phoneType = mPhone.getPhoneType(); 2457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { 2467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // CDMA: If the user presses the Power button we treat it as 2477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ending the complete call session 2487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon hungUp = PhoneUtils.hangupRingingAndActive(mPhone); 2497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) { 2507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // GSM: End the call as per the Phone state 2517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon hungUp = PhoneUtils.hangup(mCM); 2527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 2537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon throw new IllegalStateException("Unexpected phone type: " + phoneType); 2547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("CMD_END_CALL: " + (hungUp ? "hung up!" : "no call to hang up")); 2567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.result = hungUp; 2577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wake up the requesting thread 2587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 2597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.notifyAll(); 2607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 263566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case CMD_TRANSMIT_APDU: 264566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) msg.obj; 265566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal IccAPDUArgument argument = (IccAPDUArgument) request.argument; 266eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (uiccCard == null) { 267eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("iccTransmitApduLogicalChannel: No UICC"); 268eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 269eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal synchronized (request) { 270eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.notifyAll(); 271eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 272eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } else { 273eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_DONE, request); 274eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal uiccCard.iccTransmitApduLogicalChannel( 275566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal argument.channel, argument.cla, argument.command, 276566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal argument.p1, argument.p2, argument.p3, argument.data, 277566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal onCompleted); 278eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 279566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 280566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 281566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case EVENT_TRANSMIT_APDU_DONE: 282566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal ar = (AsyncResult) msg.obj; 283566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) ar.userObj; 284566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.exception == null && ar.result != null) { 285566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.result = ar.result; 286566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 287566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 288566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.result == null) { 289566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccTransmitApduLogicalChannel: Empty response"); 290e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else if (ar.exception instanceof CommandException) { 291566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccTransmitApduLogicalChannel: CommandException: " + 292e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby ar.exception); 293566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 294566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccTransmitApduLogicalChannel: Unknown exception"); 295566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 296566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 297566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal synchronized (request) { 298566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.notifyAll(); 299566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 300566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 301566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 3024d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan case CMD_SEND_ENVELOPE: 3034d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan request = (MainThreadRequest) msg.obj; 304eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (uiccCard == null) { 305eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("sendEnvelopeWithStatus: No UICC"); 306eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 307eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal synchronized (request) { 308eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.notifyAll(); 309eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 310eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } else { 311eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request); 312eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted); 313eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 3144d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan break; 3154d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan 3164d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan case EVENT_SEND_ENVELOPE_DONE: 3174d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan ar = (AsyncResult) msg.obj; 3184d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan request = (MainThreadRequest) ar.userObj; 3199f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal if (ar.exception == null && ar.result != null) { 3209f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal request.result = ar.result; 3214d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan } else { 3229f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 3239f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal if (ar.result == null) { 3249f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal loge("sendEnvelopeWithStatus: Empty response"); 3259f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal } else if (ar.exception instanceof CommandException) { 3269f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal loge("sendEnvelopeWithStatus: CommandException: " + 3279f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal ar.exception); 3289f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal } else { 3299f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal loge("sendEnvelopeWithStatus: exception:" + ar.exception); 3309f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal } 3314d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan } 3324d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan synchronized (request) { 3334d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan request.notifyAll(); 3344d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan } 3354d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan break; 3364d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan 337566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case CMD_OPEN_CHANNEL: 338566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) msg.obj; 339eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (uiccCard == null) { 340eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("iccOpenLogicalChannel: No UICC"); 341eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 342eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal synchronized (request) { 343eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.notifyAll(); 344eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 345eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } else { 346eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request); 347eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal uiccCard.iccOpenLogicalChannel((String)request.argument, onCompleted); 348eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 349566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 350566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 351566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case EVENT_OPEN_CHANNEL_DONE: 352566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal ar = (AsyncResult) msg.obj; 353566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) ar.userObj; 354566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.exception == null && ar.result != null) { 355e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = ((int[]) ar.result)[0]; 356566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 357e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = -1; 358566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.result == null) { 359566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccOpenLogicalChannel: Empty response"); 360e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else if (ar.exception instanceof CommandException) { 361566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccOpenLogicalChannel: CommandException: " + 362e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby ar.exception); 363566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 364566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccOpenLogicalChannel: Unknown exception"); 365566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 366566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 367566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal synchronized (request) { 368566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.notifyAll(); 369566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 370566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 371566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 372566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case CMD_CLOSE_CHANNEL: 373566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) msg.obj; 374eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (uiccCard == null) { 375eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("iccCloseLogicalChannel: No UICC"); 376eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 377eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal synchronized (request) { 378eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.notifyAll(); 379eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 380eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } else { 381eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request); 382eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted); 383eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 384566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 385566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 386566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case EVENT_CLOSE_CHANNEL_DONE: 387e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "iccCloseLogicalChannel"); 388e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 389e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 390e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_READ_ITEM: 391e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 392e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request); 393e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvReadItem((Integer) request.argument, onCompleted); 394e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 395e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 396e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_READ_ITEM_DONE: 397566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal ar = (AsyncResult) msg.obj; 398566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) ar.userObj; 399e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.exception == null && ar.result != null) { 400e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = ar.result; // String 401566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 402e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = ""; 403e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.result == null) { 404e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge("nvReadItem: Empty response"); 405e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else if (ar.exception instanceof CommandException) { 406e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge("nvReadItem: CommandException: " + 407e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby ar.exception); 408566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 409e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge("nvReadItem: Unknown exception"); 410566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 411566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 412566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal synchronized (request) { 413566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.notifyAll(); 414566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 415566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 416566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 417e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_WRITE_ITEM: 418e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 419e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request); 420e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument; 421e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvWriteItem(idValue.first, idValue.second, onCompleted); 422e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 423e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 424e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_WRITE_ITEM_DONE: 425e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "nvWriteItem"); 426e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 427e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 428e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_WRITE_CDMA_PRL: 429e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 430e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request); 431e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted); 432e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 433e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 434e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_WRITE_CDMA_PRL_DONE: 435e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "nvWriteCdmaPrl"); 436e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 437e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 438e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_RESET_CONFIG: 439e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 440e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_RESET_CONFIG_DONE, request); 441e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvResetConfig((Integer) request.argument, onCompleted); 442e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 443e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 444e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_RESET_CONFIG_DONE: 445e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "nvResetConfig"); 446e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 447e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 4487c27be317e8757948178815426d3a329c852b9eeJake Hamby case CMD_GET_PREFERRED_NETWORK_TYPE: 4497c27be317e8757948178815426d3a329c852b9eeJake Hamby request = (MainThreadRequest) msg.obj; 4507c27be317e8757948178815426d3a329c852b9eeJake Hamby onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request); 4517c27be317e8757948178815426d3a329c852b9eeJake Hamby mPhone.getPreferredNetworkType(onCompleted); 4527c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 4537c27be317e8757948178815426d3a329c852b9eeJake Hamby 4547c27be317e8757948178815426d3a329c852b9eeJake Hamby case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE: 4557c27be317e8757948178815426d3a329c852b9eeJake Hamby ar = (AsyncResult) msg.obj; 4567c27be317e8757948178815426d3a329c852b9eeJake Hamby request = (MainThreadRequest) ar.userObj; 4577c27be317e8757948178815426d3a329c852b9eeJake Hamby if (ar.exception == null && ar.result != null) { 4587c27be317e8757948178815426d3a329c852b9eeJake Hamby request.result = ar.result; // Integer 4597c27be317e8757948178815426d3a329c852b9eeJake Hamby } else { 4607c27be317e8757948178815426d3a329c852b9eeJake Hamby request.result = -1; 4617c27be317e8757948178815426d3a329c852b9eeJake Hamby if (ar.result == null) { 4627c27be317e8757948178815426d3a329c852b9eeJake Hamby loge("getPreferredNetworkType: Empty response"); 4637c27be317e8757948178815426d3a329c852b9eeJake Hamby } else if (ar.exception instanceof CommandException) { 4647c27be317e8757948178815426d3a329c852b9eeJake Hamby loge("getPreferredNetworkType: CommandException: " + 4657c27be317e8757948178815426d3a329c852b9eeJake Hamby ar.exception); 4667c27be317e8757948178815426d3a329c852b9eeJake Hamby } else { 4677c27be317e8757948178815426d3a329c852b9eeJake Hamby loge("getPreferredNetworkType: Unknown exception"); 4687c27be317e8757948178815426d3a329c852b9eeJake Hamby } 4697c27be317e8757948178815426d3a329c852b9eeJake Hamby } 4707c27be317e8757948178815426d3a329c852b9eeJake Hamby synchronized (request) { 4717c27be317e8757948178815426d3a329c852b9eeJake Hamby request.notifyAll(); 4727c27be317e8757948178815426d3a329c852b9eeJake Hamby } 4737c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 4747c27be317e8757948178815426d3a329c852b9eeJake Hamby 4757c27be317e8757948178815426d3a329c852b9eeJake Hamby case CMD_SET_PREFERRED_NETWORK_TYPE: 4767c27be317e8757948178815426d3a329c852b9eeJake Hamby request = (MainThreadRequest) msg.obj; 4777c27be317e8757948178815426d3a329c852b9eeJake Hamby onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request); 4787c27be317e8757948178815426d3a329c852b9eeJake Hamby int networkType = (Integer) request.argument; 4797c27be317e8757948178815426d3a329c852b9eeJake Hamby mPhone.setPreferredNetworkType(networkType, onCompleted); 4807c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 4817c27be317e8757948178815426d3a329c852b9eeJake Hamby 4827c27be317e8757948178815426d3a329c852b9eeJake Hamby case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE: 4837c27be317e8757948178815426d3a329c852b9eeJake Hamby handleNullReturnEvent(msg, "setPreferredNetworkType"); 4847c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 4857c27be317e8757948178815426d3a329c852b9eeJake Hamby 486787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu case CMD_SET_CDMA_SUBSCRIPTION: 487787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu request = (MainThreadRequest) msg.obj; 488787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_DONE, request); 489787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu int subscriptionType = (Integer) request.argument; 490787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu mPhone.setCdmaSubscription(subscriptionType, onCompleted); 491787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu break; 492787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu 493787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu case EVENT_SET_CDMA_SUBSCRIPTION_DONE: 494787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu handleNullReturnEvent(msg, "setCdmaSubscription"); 495787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu break; 496787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu 4977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon default: 4987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what); 4997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 5007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 502e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 503e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private void handleNullReturnEvent(Message msg, String command) { 504e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby AsyncResult ar = (AsyncResult) msg.obj; 505e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby MainThreadRequest request = (MainThreadRequest) ar.userObj; 506e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.exception == null) { 507e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = true; 508e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else { 509e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = false; 510e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.exception instanceof CommandException) { 511e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge(command + ": CommandException: " + ar.exception); 512e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else { 513e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge(command + ": Unknown exception"); 514e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 515e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 516e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby synchronized (request) { 517e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.notifyAll(); 518e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 519e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 5207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 5237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Posts the specified command to be executed on the main thread, 5247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * waits for the request to complete, and returns the result. 5257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #sendRequestAsync 5267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 5277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Object sendRequest(int command, Object argument) { 528500b0e04406d2995c1f29dea95c98cedaa669f74Santos Cordon return sendRequest(command, argument, null); 52936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 53036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 53136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 53236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Posts the specified command to be executed on the main thread, 53336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * waits for the request to complete, and returns the result. 53436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * @see #sendRequestAsync 53536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 53636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville private Object sendRequest(int command, Object argument, Object argument2) { 5377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (Looper.myLooper() == mMainThreadHandler.getLooper()) { 5387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon throw new RuntimeException("This method will deadlock if called from the main thread."); 5397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon MainThreadRequest request = new MainThreadRequest(argument); 5427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message msg = mMainThreadHandler.obtainMessage(command, request); 5437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon msg.sendToTarget(); 5447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wait for the request to complete 5467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 5477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon while (request.result == null) { 5487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 5497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.wait(); 5507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 5517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Do nothing, go back and wait until the request is complete 5527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return request.result; 5567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 5597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Asynchronous ("fire and forget") version of sendRequest(): 5607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Posts the specified command to be executed on the main thread, and 5617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * returns immediately. 5627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #sendRequest 5637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 5647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void sendRequestAsync(int command) { 5657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mMainThreadHandler.sendEmptyMessage(command); 5667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 569bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal * Same as {@link #sendRequestAsync(int)} except it takes an argument. 570bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal * @see {@link #sendRequest(int,Object)} 571bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal */ 572bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal private void sendRequestAsync(int command, Object argument) { 573bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal MainThreadRequest request = new MainThreadRequest(argument); 574bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal Message msg = mMainThreadHandler.obtainMessage(command, request); 575bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal msg.sendToTarget(); 576bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal } 577bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal 578bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal /** 5797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Initialize the singleton PhoneInterfaceManager instance. 5807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This is only done once, at startup, from PhoneApp.onCreate(). 5817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 582194161ed3aef6bdeeecd6153403269bbd01314a5Sailesh Nepal /* package */ static PhoneInterfaceManager init(PhoneGlobals app, Phone phone) { 5837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (PhoneInterfaceManager.class) { 5847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (sInstance == null) { 585194161ed3aef6bdeeecd6153403269bbd01314a5Sailesh Nepal sInstance = new PhoneInterfaceManager(app, phone); 5867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 5877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance); 5887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return sInstance; 5907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** Private constructor; @see init() */ 594194161ed3aef6bdeeecd6153403269bbd01314a5Sailesh Nepal private PhoneInterfaceManager(PhoneGlobals app, Phone phone) { 5957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp = app; 5967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone = phone; 5977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCM = PhoneGlobals.getInstance().mCM; 59889e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan mSimplifiedNetworkSettings = new HashSet<Long>(); 5997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE); 6007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mMainThreadHandler = new MainThreadHandler(); 6017226c84acb402f96e527650347391fa025294350Derek Tan mAdnRecordsForDisplay = new HashMap<Long, AdnRecord>(); 6027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon publish(); 6037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void publish() { 6067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("publish: " + this); 6077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ServiceManager.addService("phone", this); 6097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 61136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // returns phone associated with the subId. 61236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // getPhone(0) returns default phone in single SIM mode. 61336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville private Phone getPhone(long subId) { 61436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // FIXME: hack for the moment 61536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return mPhone; 61636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // return PhoneUtils.getPhoneUsingSubId(subId); 61736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 6187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 6197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Implementation of the ITelephony interface. 6207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 6217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void dial(String number) { 62336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville dialUsingSubId(getPreferredVoiceSubscription(), number); 62436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 62536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 62636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void dialUsingSubId(long subId, String number) { 6277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("dial: " + number); 6287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No permission check needed here: This is just a wrapper around the 6297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ACTION_DIAL intent, which is available to any app since it puts up 6307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the UI before it does anything. 6317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon String url = createTelUrl(number); 6337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (url == null) { 6347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 6357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // PENDING: should we just silently fail if phone is offhook or ringing? 63836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville PhoneConstants.State state = mCM.getState(subId); 6397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) { 6407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url)); 6417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 64236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville intent.putExtra(SUBSCRIPTION_KEY, subId); 6437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.startActivity(intent); 6447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void call(String callingPackage, String number) { 64836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville callUsingSubId(getPreferredVoiceSubscription(), callingPackage, number); 64936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 65036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 65136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void callUsingSubId(long subId, String callingPackage, String number) { 6527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("call: " + number); 6537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // This is just a wrapper around the ACTION_CALL intent, but we still 6557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // need to do a permission check since we're calling startActivity() 6567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // from the context of the phone app. 6577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceCallPermission(); 6587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mAppOps.noteOp(AppOpsManager.OP_CALL_PHONE, Binder.getCallingUid(), callingPackage) 6607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon != AppOpsManager.MODE_ALLOWED) { 6617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 6627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon String url = createTelUrl(number); 6657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (url == null) { 6667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 6677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url)); 67036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville intent.putExtra(SUBSCRIPTION_KEY, subId); 6717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 6727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.startActivity(intent); 6737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 6767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * End a call based on call state 6777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return true is a call was ended 6787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 6797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean endCall() { 68036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return endCallUsingSubId(getDefaultSubscription()); 68136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 68236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 68336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 68436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * End a call based on the call state of the subId 68536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * @return true is a call was ended 68636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 68736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean endCallUsingSubId(long subId) { 6887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceCallPermission(); 68936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return (Boolean) sendRequest(CMD_END_CALL, subId, null); 6907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void answerRingingCall() { 69336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville answerRingingCallUsingSubId(getDefaultSubscription()); 69436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 69536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 69636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void answerRingingCallUsingSubId(long subId) { 6977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("answerRingingCall..."); 6987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: there should eventually be a separate "ANSWER_PHONE" permission, 6997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // but that can probably wait till the big TelephonyManager API overhaul. 7007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For now, protect this call with the MODIFY_PHONE_STATE permission. 7017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 7027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon sendRequestAsync(CMD_ANSWER_RINGING_CALL); 7037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 7067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make the actual telephony calls to implement answerRingingCall(). 7077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This should only be called from the main thread of the Phone app. 7087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #answerRingingCall 7097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 7107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * TODO: it would be nice to return true if we answered the call, or 7117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * false if there wasn't actually a ringing incoming call, or some 7127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * other error occurred. (In other words, pass back the return value 7137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * from PhoneUtils.answerCall() or PhoneUtils.answerAndEndActive().) 7147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * But that would require calling this method via sendRequest() rather 7157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * than sendRequestAsync(), and right now we don't actually *need* that 7167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * return value, so let's just return void for now. 7177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 7187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void answerRingingCallInternal() { 7197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final boolean hasRingingCall = !mPhone.getRingingCall().isIdle(); 7207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (hasRingingCall) { 7217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final boolean hasActiveCall = !mPhone.getForegroundCall().isIdle(); 7227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final boolean hasHoldingCall = !mPhone.getBackgroundCall().isIdle(); 7237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (hasActiveCall && hasHoldingCall) { 7247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Both lines are in use! 7257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: provide a flag to let the caller specify what 7267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // policy to use if both lines are in use. (The current 7277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // behavior is hardwired to "answer incoming, end ongoing", 7287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // which is how the CALL button is specced to behave.) 7297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.answerAndEndActive(mCM, mCM.getFirstActiveRingingCall()); 7307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 7317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 7327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // answerCall() will automatically hold the current active 7337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // call, if there is one. 7347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.answerCall(mCM.getFirstActiveRingingCall()); 7357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 7367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 7387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No call was ringing. 7397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 7407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void silenceRinger() { 7447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("silenceRinger..."); 7457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: find a more appropriate permission to check here. 7467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // (That can probably wait till the big TelephonyManager API overhaul. 7477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For now, protect this call with the MODIFY_PHONE_STATE permission.) 7487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 7497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon sendRequestAsync(CMD_SILENCE_RINGER); 7507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 7537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Internal implemenation of silenceRinger(). 7547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This should only be called from the main thread of the Phone app. 7557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #silenceRinger 7567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 7577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void silenceRingerInternal() { 7587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((mCM.getState() == PhoneConstants.State.RINGING) 7597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon && mApp.notifier.isRinging()) { 7607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Ringer is actually playing, so silence it. 7617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("silenceRingerInternal: silencing..."); 7627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.notifier.silenceRinger(); 7637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isOffhook() { 76736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return isOffhookUsingSubId(getDefaultSubscription()); 76836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 76936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 77036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean isOffhookUsingSubId(long subId) { 77136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return (getPhone(subId).getState() == PhoneConstants.State.OFFHOOK); 7727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isRinging() { 77536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return (isRingingUsingSubId(getDefaultSubscription())); 77636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 77736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 77836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean isRingingUsingSubId(long subId) { 77936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return (getPhone(subId).getState() == PhoneConstants.State.RINGING); 7807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isIdle() { 78336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return isIdleUsingSubId(getDefaultSubscription()); 78436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 78536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 78636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean isIdleUsingSubId(long subId) { 78736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return (getPhone(subId).getState() == PhoneConstants.State.IDLE); 7887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isSimPinEnabled() { 7917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceReadPermission(); 7927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return (PhoneGlobals.getInstance().isSimPinEnabled()); 7937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean supplyPin(String pin) { 79636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return supplyPinUsingSubId(getDefaultSubscription(), pin); 79736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 79836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 79936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean supplyPinUsingSubId(long subId, String pin) { 80036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville int [] resultArray = supplyPinReportResultUsingSubId(subId, pin); 8019de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false; 8029de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 8039de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville 8049de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville public boolean supplyPuk(String puk, String pin) { 80536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return supplyPukUsingSubId(getDefaultSubscription(), puk, pin); 80636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 80736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 80836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean supplyPukUsingSubId(long subId, String puk, String pin) { 80936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville int [] resultArray = supplyPukReportResultUsingSubId(subId, puk, pin); 8109de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false; 8119de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 8129de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville 8139de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville /** {@hide} */ 8149de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville public int[] supplyPinReportResult(String pin) { 81536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return supplyPinReportResultUsingSubId(getDefaultSubscription(), pin); 81636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 81736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 81836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int[] supplyPinReportResultUsingSubId(long subId, String pin) { 8197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 82036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard()); 8217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon checkSimPin.start(); 8227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return checkSimPin.unlockSim(null, pin); 8237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8259de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville /** {@hide} */ 8269de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville public int[] supplyPukReportResult(String puk, String pin) { 82736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return supplyPukReportResultUsingSubId(getDefaultSubscription(), puk, pin); 82836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 82936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 83036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int[] supplyPukReportResultUsingSubId(long subId, String puk, String pin) { 8317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 83236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard()); 8337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon checkSimPuk.start(); 8347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return checkSimPuk.unlockSim(puk, pin); 8357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 8389de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville * Helper thread to turn async call to SimCard#supplyPin into 8397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * a synchronous one. 8407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 8417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static class UnlockSim extends Thread { 8427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private final IccCard mSimCard; 8447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private boolean mDone = false; 8469de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville private int mResult = PhoneConstants.PIN_GENERAL_FAILURE; 8479de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville private int mRetryCount = -1; 8487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For replies from SimCard interface 8507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Handler mHandler; 8517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For async handler to identify request type 8537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int SUPPLY_PIN_COMPLETE = 100; 8547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public UnlockSim(IccCard simCard) { 8567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSimCard = simCard; 8577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 8607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void run() { 8617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Looper.prepare(); 8627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (UnlockSim.this) { 8637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mHandler = new Handler() { 8647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 8657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void handleMessage(Message msg) { 8667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AsyncResult ar = (AsyncResult) msg.obj; 8677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon switch (msg.what) { 8687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case SUPPLY_PIN_COMPLETE: 8697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE"); 8707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (UnlockSim.this) { 8719de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mRetryCount = msg.arg1; 8729de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville if (ar.exception != null) { 8739de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville if (ar.exception instanceof CommandException && 8749de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville ((CommandException)(ar.exception)).getCommandError() 8759de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville == CommandException.Error.PASSWORD_INCORRECT) { 8769de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mResult = PhoneConstants.PIN_PASSWORD_INCORRECT; 8779de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } else { 8789de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mResult = PhoneConstants.PIN_GENERAL_FAILURE; 8799de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 8809de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } else { 8819de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mResult = PhoneConstants.PIN_RESULT_SUCCESS; 8829de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 8837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mDone = true; 8847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon UnlockSim.this.notifyAll(); 8857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 8877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon }; 8907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon UnlockSim.this.notifyAll(); 8917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Looper.loop(); 8937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* 8967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Use PIN or PUK to unlock SIM card 8977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 8987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * If PUK is null, unlock SIM card with PIN 8997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 9007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * If PUK is not null, unlock SIM card with PUK and set PIN code 9017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 9029de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville synchronized int[] unlockSim(String puk, String pin) { 9037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon while (mHandler == null) { 9057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 9067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon wait(); 9077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 9087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Thread.currentThread().interrupt(); 9097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE); 9127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (puk == null) { 9147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSimCard.supplyPin(pin, callback); 9157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 9167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSimCard.supplyPuk(puk, pin, callback); 9177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon while (!mDone) { 9207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 9217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "wait for done"); 9227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon wait(); 9237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 9247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Restore the interrupted status 9257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Thread.currentThread().interrupt(); 9267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "done"); 9299de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville int[] resultArray = new int[2]; 9309de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville resultArray[0] = mResult; 9319de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville resultArray[1] = mRetryCount; 9329de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville return resultArray; 9337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void updateServiceLocation() { 93736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville updateServiceLocationUsingSubId(getDefaultSubscription()); 93836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 93936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 94036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 94136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void updateServiceLocationUsingSubId(long subId) { 9427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No permission check needed here: this call is harmless, and it's 9437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // needed for the ServiceState.requestStateUpdate() call (which is 9447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // already intentionally exposed to 3rd parties.) 94536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).updateServiceLocation(); 9467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isRadioOn() { 94936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return isRadioOnUsingSubId(getDefaultSubscription()); 95036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 95136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 95236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean isRadioOnUsingSubId(long subId) { 95336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getServiceState().getState() != ServiceState.STATE_POWER_OFF; 9547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void toggleRadioOnOff() { 95736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville toggleRadioOnOffUsingSubId(getDefaultSubscription()); 95836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 95936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 96036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 96136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void toggleRadioOnOffUsingSubId(long subId) { 9627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 96336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).setRadioPower(!isRadioOnUsingSubId(subId)); 9647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 96536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 9667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean setRadio(boolean turnOn) { 96736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return setRadioUsingSubId(getDefaultSubscription(), turnOn); 96836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 96936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 97036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean setRadioUsingSubId(long subId, boolean turnOn) { 9717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 97236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville if ((getPhone(subId).getServiceState().getState() != 97336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville ServiceState.STATE_POWER_OFF) != turnOn) { 97436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville toggleRadioOnOffUsingSubId(subId); 9757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 9777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 97836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 9797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean setRadioPower(boolean turnOn) { 98036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return setRadioPowerUsingSubId(getDefaultSubscription(), turnOn); 98136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 98236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 98336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean setRadioPowerUsingSubId(long subId, boolean turnOn) { 9847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 98536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).setRadioPower(turnOn); 9867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 9877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 98936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // FIXME: subId version needed 9907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean enableDataConnectivity() { 9917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 99236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville long subId = SubscriptionManager.getDefaultDataSubId(); 99336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).setDataEnabled(true); 9947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 9957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 99736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // FIXME: subId version needed 9987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean disableDataConnectivity() { 9997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 100036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville long subId = SubscriptionManager.getDefaultDataSubId(); 100136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).setDataEnabled(false); 10027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 10037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 100536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // FIXME: subId version needed 10067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isDataConnectivityPossible() { 100736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville long subId = SubscriptionManager.getDefaultDataSubId(); 100836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).isDataConnectivityPossible(); 10097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean handlePinMmi(String dialString) { 101236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return handlePinMmiUsingSubId(getDefaultSubscription(), dialString); 101336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 101436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 101536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean handlePinMmiUsingSubId(long subId, String dialString) { 10167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 101736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId); 10187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getCallState() { 102136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getCallStateUsingSubId(getDefaultSubscription()); 102236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 102336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 102436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getCallStateUsingSubId(long subId) { 102536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return DefaultPhoneNotifier.convertCallState(getPhone(subId).getState()); 10267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getDataState() { 102936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville Phone phone = getPhone(SubscriptionManager.getDefaultDataSubId()); 103036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return DefaultPhoneNotifier.convertDataState(phone.getDataConnectionState()); 10317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getDataActivity() { 103436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville Phone phone = getPhone(SubscriptionManager.getDefaultDataSubId()); 103536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState()); 10367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 10397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public Bundle getCellLocation() { 10407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 10417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 10427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_FINE_LOCATION, null); 10437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (SecurityException e) { 10447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If we have ACCESS_FINE_LOCATION permission, skip the check for ACCESS_COARSE_LOCATION 10457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // A failure should throw the SecurityException from ACCESS_COARSE_LOCATION since this 10467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // is the weaker precondition 10477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 10487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 10497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1051e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (checkIfCallerIsSelfOrForegroundUser()) { 10527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getCellLocation: is active user"); 10537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Bundle data = new Bundle(); 10547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.getCellLocation().fillInNotifierBundle(data); 10557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return data; 10567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 10577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getCellLocation: suppress non-active user"); 10587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 10597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 10637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void enableLocationUpdates() { 106436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville enableLocationUpdatesUsingSubId(getDefaultSubscription()); 106536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 106636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 106736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void enableLocationUpdatesUsingSubId(long subId) { 10687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 10697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.CONTROL_LOCATION_UPDATES, null); 107036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).enableLocationUpdates(); 10717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 10747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void disableLocationUpdates() { 107536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville disableLocationUpdatesUsingSubId(getDefaultSubscription()); 107636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 107736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 107836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void disableLocationUpdatesUsingSubId(long subId) { 10797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 10807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.CONTROL_LOCATION_UPDATES, null); 108136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).disableLocationUpdates(); 10827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 10857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @SuppressWarnings("unchecked") 10867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage) { 10877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 10887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 10897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_FINE_LOCATION, null); 10907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (SecurityException e) { 10917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If we have ACCESS_FINE_LOCATION permission, skip the check 10927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // for ACCESS_COARSE_LOCATION 10937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // A failure should throw the SecurityException from 10947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ACCESS_COARSE_LOCATION since this is the weaker precondition 10957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 10967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 10977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(), 11007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon callingPackage) != AppOpsManager.MODE_ALLOWED) { 11017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 11027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1103e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (checkIfCallerIsSelfOrForegroundUser()) { 11047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getNeighboringCellInfo: is active user"); 11057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ArrayList<NeighboringCellInfo> cells = null; 11077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 11097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon cells = (ArrayList<NeighboringCellInfo>) sendRequest( 111036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville CMD_HANDLE_NEIGHBORING_CELL, null, null); 11117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (RuntimeException e) { 111236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville Log.e(LOG_TAG, "getNeighboringCellInfo " + e); 11137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return cells; 11157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 11167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getNeighboringCellInfo: suppress non-active user"); 11177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 11187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 11237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public List<CellInfo> getAllCellInfo() { 11247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 11257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 11267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_FINE_LOCATION, null); 11277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (SecurityException e) { 11287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If we have ACCESS_FINE_LOCATION permission, skip the check for ACCESS_COARSE_LOCATION 11297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // A failure should throw the SecurityException from ACCESS_COARSE_LOCATION since this 11307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // is the weaker precondition 11317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 11327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 11337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1135e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (checkIfCallerIsSelfOrForegroundUser()) { 11367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getAllCellInfo: is active user"); 11377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getAllCellInfo(); 11387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 11397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getAllCellInfo: suppress non-active user"); 11407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 11417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1144bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal @Override 11457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void setCellInfoListRate(int rateInMillis) { 11467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.setCellInfoListRate(rateInMillis); 11477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 11507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Internal helper methods. 11517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 11527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1153e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static boolean checkIfCallerIsSelfOrForegroundUser() { 11547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean ok; 11557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean self = Binder.getCallingUid() == Process.myUid(); 11577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!self) { 11587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Get the caller's user id then clear the calling identity 11597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // which will be restored in the finally clause. 11607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int callingUser = UserHandle.getCallingUserId(); 11617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon long ident = Binder.clearCallingIdentity(); 11627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 11647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // With calling identity cleared the current user is the foreground user. 11657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int foregroundUser = ActivityManager.getCurrentUser(); 11667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ok = (foregroundUser == callingUser); 11677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) { 11687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon log("checkIfCallerIsSelfOrForegoundUser: foregroundUser=" + foregroundUser 11697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon + " callingUser=" + callingUser + " ok=" + ok); 11707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (Exception ex) { 11727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) loge("checkIfCallerIsSelfOrForegoundUser: Exception ex=" + ex); 11737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ok = false; 11747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } finally { 11757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Binder.restoreCallingIdentity(ident); 11767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 11787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("checkIfCallerIsSelfOrForegoundUser: is self"); 11797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ok = true; 11807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("checkIfCallerIsSelfOrForegoundUser: ret=" + ok); 11827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return ok; 11837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 11867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make sure the caller has the READ_PHONE_STATE permission. 11877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 11887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @throws SecurityException if the caller does not have the required permission 11897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 11907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void enforceReadPermission() { 11917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE, null); 11927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 11957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make sure the caller has the MODIFY_PHONE_STATE permission. 11967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 11977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @throws SecurityException if the caller does not have the required permission 11987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 11997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void enforceModifyPermission() { 12007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null); 12017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1204a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * Make sure either system app or the caller has carrier privilege. 1205a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * 1206a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * @throws SecurityException if the caller does not have the required permission/privilege 1207a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu */ 1208a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu private void enforceModifyPermissionOrCarrierPrivilege() { 1209f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal int permission = mApp.checkCallingOrSelfPermission( 1210f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal android.Manifest.permission.MODIFY_PHONE_STATE); 1211f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal if (permission == PackageManager.PERMISSION_GRANTED) { 1212f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal return; 1213f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal } 1214f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal 1215f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal log("No modify permission, check carrier privilege next."); 1216f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal if (hasCarrierPrivileges() != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 1217f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal loge("No Carrier Privilege."); 1218f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal throw new SecurityException("No modify permission or carrier privilege."); 1219a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu } 1220a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu } 1221a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu 1222a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu /** 1223a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * Make sure the caller has carrier privilege. 1224a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * 1225a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * @throws SecurityException if the caller does not have the required permission 1226a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu */ 1227a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu private void enforceCarrierPrivilege() { 1228a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu if (hasCarrierPrivileges() != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 1229f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal loge("No Carrier Privilege."); 1230f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal throw new SecurityException("No Carrier Privilege."); 1231a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu } 1232a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu } 1233a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu 1234a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu /** 12357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make sure the caller has the CALL_PHONE permission. 12367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 12377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @throws SecurityException if the caller does not have the required permission 12387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 12397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void enforceCallPermission() { 12407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null); 12417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1243566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal /** 124436ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal * Make sure the caller has the READ_PRIVILEGED_PHONE_STATE permission. 124536ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal * 124636ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal * @throws SecurityException if the caller does not have the required permission 124736ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal */ 124836ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal private void enforcePrivilegedPhoneStatePermission() { 124936ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 125036ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal null); 125136ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal } 125236ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal 12537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private String createTelUrl(String number) { 12547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (TextUtils.isEmpty(number)) { 12557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 12567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1258e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return "tel:" + number; 12597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1261f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad private static void log(String msg) { 12627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg); 12637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1265f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad private static void loge(String msg) { 12667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg); 12677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getActivePhoneType() { 127036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getActivePhoneTypeUsingSubId(getDefaultSubscription()); 127136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 127236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 127336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getActivePhoneTypeUsingSubId(long subId) { 127436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getPhoneType(); 12757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 12787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the CDMA ERI icon index to display 12797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 12807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getCdmaEriIconIndex() { 128136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getCdmaEriIconIndexUsingSubId(getDefaultSubscription()); 128236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 128336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 128436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 128536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getCdmaEriIconIndexUsingSubId(long subId) { 128636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getCdmaEriIconIndex(); 12877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 12907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the CDMA ERI icon mode, 12917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 0 - ON 12927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 1 - FLASHING 12937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 12947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getCdmaEriIconMode() { 129536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getCdmaEriIconModeUsingSubId(getDefaultSubscription()); 129636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 129736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 129836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getCdmaEriIconModeUsingSubId(long subId) { 129936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getCdmaEriIconMode(); 13007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 13037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the CDMA ERI text, 13047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 13057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public String getCdmaEriText() { 130636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getCdmaEriTextUsingSubId(getDefaultSubscription()); 130736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 130836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 130936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public String getCdmaEriTextUsingSubId(long subId) { 131036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getCdmaEriText(); 13117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 13147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns true if CDMA provisioning needs to run. 13157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 13167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean needsOtaServiceProvisioning() { 13177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.needsOtaServiceProvisioning(); 13187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 13217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the unread count of voicemails 13227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 13237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getVoiceMessageCount() { 132436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getVoiceMessageCountUsingSubId(getDefaultSubscription()); 132536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 132636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 132736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 132836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns the unread count of voicemails for a subId 132936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 133036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getVoiceMessageCountUsingSubId( long subId) { 133136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getVoiceMessageCount(); 13327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 13357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the data network type 13367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 13377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @Deprecated to be removed Q3 2013 use {@link #getDataNetworkType}. 13387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 13397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 13407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getNetworkType() { 134136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getNetworkTypeUsingSubId(getDefaultSubscription()); 134236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 134336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 134436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 134536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns the network type for a subId 134636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 134736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville @Override 134836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getNetworkTypeUsingSubId(long subId) { 134936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getServiceState().getDataNetworkType(); 13507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 13537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the data network type 13547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 13557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 13567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getDataNetworkType() { 135736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getDataNetworkTypeUsingSubId(getDefaultSubscription()); 135836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 135936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 136036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 136136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns the data network type for a subId 136236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 136336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville @Override 136436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getDataNetworkTypeUsingSubId(long subId) { 136536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getServiceState().getDataNetworkType(); 13667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 13697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the data network type 13707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 13717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 13727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getVoiceNetworkType() { 137336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getVoiceNetworkTypeUsingSubId(getDefaultSubscription()); 137436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 137536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 137636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 137736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns the Voice network type for a subId 137836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 137936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville @Override 138036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getVoiceNetworkTypeUsingSubId(long subId) { 138136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getServiceState().getVoiceNetworkType(); 13827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 13857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return true if a ICC card is present 13867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 13877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean hasIccCard() { 138836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // FIXME Make changes to pass defaultSimId of type int 138936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return hasIccCardUsingSlotId(getDefaultSubscription()); 139036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 139136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 139236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 139336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * @return true if a ICC card is present for a slotId 139436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 139536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public boolean hasIccCardUsingSlotId(long slotId) { 139636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(slotId).getIccCard().hasIccCard(); 13977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 14007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Return if the current radio is LTE on CDMA. This 14017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * is a tri-state return value as for a period of time 14027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * the mode may be unknown. 14037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 14047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE} 1405e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * or {@link Phone#LTE_ON_CDMA_TRUE} 14067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 14077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getLteOnCdmaMode() { 140836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getLteOnCdmaModeUsingSubId(getDefaultSubscription()); 140936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 141036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 141136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getLteOnCdmaModeUsingSubId(long subId) { 141236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getLteOnCdmaMode(); 141336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 141436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 141536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void setPhone(Phone phone) { 141636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville mPhone = phone; 141736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 141836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 141936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 142036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * {@hide} 142136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns Default subId, 0 in the case of single standby. 142236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 142336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville private long getDefaultSubscription() { 142436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return SubscriptionManager.getDefaultSubId(); 142536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 142636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 142736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville private long getPreferredVoiceSubscription() { 142836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return SubscriptionManager.getDefaultVoiceSubId(); 14297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1430f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad 1431f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad /** 1432f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad * @see android.telephony.TelephonyManager.WifiCallingChoices 1433f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad */ 1434f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad public int getWhenToMakeWifiCalls() { 1435d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal return Settings.System.getInt(mPhone.getContext().getContentResolver(), 1436d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal Settings.System.WHEN_TO_MAKE_WIFI_CALLS, getWhenToMakeWifiCallsDefaultPreference()); 1437f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad } 1438f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad 1439f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad /** 1440f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad * @see android.telephony.TelephonyManager.WifiCallingChoices 1441f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad */ 1442f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad public void setWhenToMakeWifiCalls(int preference) { 1443d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference); 1444d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal Settings.System.putInt(mPhone.getContext().getContentResolver(), 1445d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference); 1446f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad } 1447f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad 1448d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal private static int getWhenToMakeWifiCallsDefaultPreference() { 1449d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal // TODO(sail): Use a build property to choose this value. 14509829e880f73f76119ba76ba032db42aad042858fEvan Charlton return TelephonyManager.WifiCallingChoices.ALWAYS_USE; 1451f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad } 145269f68120b94cecb2d87fe856bc115714b4e77bcdShishir Agrawal 1453566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal @Override 1454566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public int iccOpenLogicalChannel(String AID) { 1455a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1456566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1457566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccOpenLogicalChannel: " + AID); 1458566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal Integer channel = (Integer)sendRequest(CMD_OPEN_CHANNEL, AID); 1459566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccOpenLogicalChannel: " + channel); 1460e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return channel; 1461566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1462566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1463566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal @Override 1464566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public boolean iccCloseLogicalChannel(int channel) { 1465a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1466566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1467566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccCloseLogicalChannel: " + channel); 1468566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (channel < 0) { 1469566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return false; 1470566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1471e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean)sendRequest(CMD_CLOSE_CHANNEL, channel); 1472566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccCloseLogicalChannel: " + success); 1473566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return success; 1474566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1475566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1476566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal @Override 1477566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public String iccTransmitApduLogicalChannel(int channel, int cla, 1478566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal int command, int p1, int p2, int p3, String data) { 1479a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1480566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1481566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) { 1482566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal log("iccTransmitApduLogicalChannel: chnl=" + channel + " cla=" + cla + 1483566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + 1484566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal " data=" + data); 1485566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1486566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1487566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (channel < 0) { 1488566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return ""; 1489566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1490566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1491566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal IccIoResult response = (IccIoResult)sendRequest(CMD_TRANSMIT_APDU, 1492566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal new IccAPDUArgument(channel, cla, command, p1, p2, p3, data)); 1493566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccTransmitApduLogicalChannel: " + response); 1494566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1495566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal // If the payload is null, there was an error. Indicate that by returning 1496566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal // an empty string. 1497566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (response.payload == null) { 1498566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return ""; 1499566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1500566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1501566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal // Append the returned status code to the end of the response payload. 1502566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal String s = Integer.toHexString( 1503566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 1504566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal s = IccUtils.bytesToHexString(response.payload) + s; 1505566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return s; 1506566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1507e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 1508c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton @Override 1509c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton public String sendEnvelopeWithStatus(String content) { 1510a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1511c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton 1512c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton IccIoResult response = (IccIoResult)sendRequest(CMD_SEND_ENVELOPE, content); 1513c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton if (response.payload == null) { 1514c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton return ""; 1515c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton } 1516c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton 1517c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton // Append the returned status code to the end of the response payload. 1518c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton String s = Integer.toHexString( 1519c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 1520c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton s = IccUtils.bytesToHexString(response.payload) + s; 1521c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton return s; 1522c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton } 1523c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton 1524e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 1525e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems} 1526e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators. 1527e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 1528e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param itemID the ID of the item to read 1529e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return the NV item as a String, or null on error. 1530e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 1531e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 1532e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public String nvReadItem(int itemID) { 1533a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1534e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvReadItem: item " + itemID); 1535e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID); 1536e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"'); 1537e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return value; 1538e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 1539e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 1540e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 1541e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems} 1542e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators. 1543e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 1544e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param itemID the ID of the item to read 1545e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param itemValue the value to write, as a String 1546e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return true on success; false on any failure 1547e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 1548e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 1549e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public boolean nvWriteItem(int itemID, String itemValue) { 1550a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1551e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"'); 1552e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM, 1553e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby new Pair<Integer, String>(itemID, itemValue)); 1554e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail")); 1555e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return success; 1556e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 1557e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 1558e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 1559e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage. 1560e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Used for device configuration by some CDMA operators. 1561e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 1562e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param preferredRoamingList byte array containing the new PRL 1563e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return true on success; false on any failure 1564e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 1565e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 1566e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) { 1567a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1568e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList)); 1569e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList); 1570e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail")); 1571e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return success; 1572e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 1573e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 1574e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 1575e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Perform the specified type of NV config reset. 1576e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Used for device configuration by some CDMA operators. 1577e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 1578e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset) 1579e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return true on success; false on any failure 1580e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 1581e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 1582e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public boolean nvResetConfig(int resetType) { 1583a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1584e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvResetConfig: type " + resetType); 1585e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean) sendRequest(CMD_NV_RESET_CONFIG, resetType); 1586e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvResetConfig: type " + resetType + ' ' + (success ? "ok" : "fail")); 1587e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return success; 1588e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 15897c27be317e8757948178815426d3a329c852b9eeJake Hamby 15907c27be317e8757948178815426d3a329c852b9eeJake Hamby /** 159136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * {@hide} 159236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns Default sim, 0 in the case of single standby. 159336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 159436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getDefaultSim() { 159536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville //TODO Need to get it from Telephony Devcontroller 159636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return 0; 159736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 159836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 159936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public String[] getPcscfAddress() { 160036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville enforceReadPermission(); 160136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return mPhone.getPcscfAddress(); 160236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 160336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 160436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void setImsRegistrationState(boolean registered) { 160536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville enforceModifyPermission(); 160636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville mPhone.setImsRegistrationState(registered); 160736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 160836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 160936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 161084d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu * Get the calculated preferred network type. 161184d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu * Used for debugging incorrect network type. 161284d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu * 161384d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu * @return the preferred network type, defined in RILConstants.java. 161484d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu */ 161584d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu @Override 161684d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu public int getCalculatedPreferredNetworkType() { 161784d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu enforceReadPermission(); 161884d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu return PhoneFactory.calculatePreferredNetworkType(mPhone.getContext()); 161984d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu } 162084d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu 162184d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu /** 16227c27be317e8757948178815426d3a329c852b9eeJake Hamby * Get the preferred network type. 16237c27be317e8757948178815426d3a329c852b9eeJake Hamby * Used for device configuration by some CDMA operators. 16247c27be317e8757948178815426d3a329c852b9eeJake Hamby * 16257c27be317e8757948178815426d3a329c852b9eeJake Hamby * @return the preferred network type, defined in RILConstants.java. 16267c27be317e8757948178815426d3a329c852b9eeJake Hamby */ 16277c27be317e8757948178815426d3a329c852b9eeJake Hamby @Override 16287c27be317e8757948178815426d3a329c852b9eeJake Hamby public int getPreferredNetworkType() { 1629a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 16307c27be317e8757948178815426d3a329c852b9eeJake Hamby if (DBG) log("getPreferredNetworkType"); 16317c27be317e8757948178815426d3a329c852b9eeJake Hamby int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null); 16327c27be317e8757948178815426d3a329c852b9eeJake Hamby int networkType = (result != null ? result[0] : -1); 16337c27be317e8757948178815426d3a329c852b9eeJake Hamby if (DBG) log("getPreferredNetworkType: " + networkType); 16347c27be317e8757948178815426d3a329c852b9eeJake Hamby return networkType; 16357c27be317e8757948178815426d3a329c852b9eeJake Hamby } 16367c27be317e8757948178815426d3a329c852b9eeJake Hamby 16377c27be317e8757948178815426d3a329c852b9eeJake Hamby /** 16387c27be317e8757948178815426d3a329c852b9eeJake Hamby * Set the preferred network type. 16397c27be317e8757948178815426d3a329c852b9eeJake Hamby * Used for device configuration by some CDMA operators. 16407c27be317e8757948178815426d3a329c852b9eeJake Hamby * 16417c27be317e8757948178815426d3a329c852b9eeJake Hamby * @param networkType the preferred network type, defined in RILConstants.java. 16427c27be317e8757948178815426d3a329c852b9eeJake Hamby * @return true on success; false on any failure. 16437c27be317e8757948178815426d3a329c852b9eeJake Hamby */ 16447c27be317e8757948178815426d3a329c852b9eeJake Hamby @Override 16457c27be317e8757948178815426d3a329c852b9eeJake Hamby public boolean setPreferredNetworkType(int networkType) { 1646a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 16477c27be317e8757948178815426d3a329c852b9eeJake Hamby if (DBG) log("setPreferredNetworkType: type " + networkType); 16487c27be317e8757948178815426d3a329c852b9eeJake Hamby Boolean success = (Boolean) sendRequest(CMD_SET_PREFERRED_NETWORK_TYPE, networkType); 16497c27be317e8757948178815426d3a329c852b9eeJake Hamby if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail")); 165080bc0d1614b46c89fa7a2c1d68fdb3ccb018625dJunda Liu if (success) { 165180bc0d1614b46c89fa7a2c1d68fdb3ccb018625dJunda Liu Settings.Global.putInt(mPhone.getContext().getContentResolver(), 165280bc0d1614b46c89fa7a2c1d68fdb3ccb018625dJunda Liu Settings.Global.PREFERRED_NETWORK_MODE, networkType); 165380bc0d1614b46c89fa7a2c1d68fdb3ccb018625dJunda Liu } 16547c27be317e8757948178815426d3a329c852b9eeJake Hamby return success; 16557c27be317e8757948178815426d3a329c852b9eeJake Hamby } 1656ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt 1657ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt /** 1658787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu * Set the CDMA subscription source. 1659787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu * Used for device supporting both NV and RUIM for CDMA. 1660787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu * 1661787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu * @param subscriptionType the subscription type, 0 for RUIM, 1 for NV. 1662787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu * @return true on success; false on any failure. 1663787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu */ 1664787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu @Override 1665787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu public boolean setCdmaSubscription(int subscriptionType) { 1666a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1667787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu if (DBG) log("setCdmaSubscription: type " + subscriptionType); 1668787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu if (subscriptionType != mPhone.CDMA_SUBSCRIPTION_RUIM_SIM && 1669787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu subscriptionType != mPhone.CDMA_SUBSCRIPTION_NV) { 1670787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu loge("setCdmaSubscription: unsupported subscriptionType."); 1671787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu return false; 1672787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu } 1673787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu Boolean success = (Boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION, subscriptionType); 1674787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu if (DBG) log("setCdmaSubscription: " + (success ? "ok" : "fail")); 1675787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu if (success) { 1676787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu Settings.Global.putInt(mPhone.getContext().getContentResolver(), 1677787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu Settings.Global.CDMA_SUBSCRIPTION_MODE, subscriptionType); 1678787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu } 1679787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu return success; 1680787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu } 1681787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu 1682787bc7e2fd1cfbaeb16748663e190bf27aec06b2Junda Liu /** 1683ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * Set mobile data enabled 1684ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * Used by the user through settings etc to turn on/off mobile data 1685ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * 1686ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * @param enable {@code true} turn turn data on, else {@code false} 1687ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt */ 1688ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt @Override 1689ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt public void setDataEnabled(boolean enable) { 1690ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt enforceModifyPermission(); 1691ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt mPhone.setDataEnabled(enable); 1692ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt } 1693ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt 1694ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt /** 1695646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * Get whether mobile data is enabled. 1696646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * 1697646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * Note that this used to be available from ConnectivityService, gated by 1698646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * ACCESS_NETWORK_STATE permission, so this will accept either that or 1699646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * our MODIFY_PHONE_STATE. 1700ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * 1701ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * @return {@code true} if data is enabled else {@code false} 1702ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt */ 1703ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt @Override 1704ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt public boolean getDataEnabled() { 1705646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt try { 1706646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE, 1707646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt null); 1708646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt } catch (Exception e) { 1709646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, 1710646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt null); 1711646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt } 1712ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt return mPhone.getDataEnabled(); 1713ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt } 171460f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawal 171560f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawal @Override 171660f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawal public int hasCarrierPrivileges() { 1717eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal UiccCard card = UiccController.getInstance().getUiccCard(); 1718eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (card == null) { 1719eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("hasCarrierPrivileges: No UICC"); 1720eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 1721eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 1722eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal return card.getCarrierPrivilegeStatusForCurrentTransaction( 1723f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal mPhone.getContext().getPackageManager()); 172460f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawal } 17252934034e04c5ca7839de41d0cc8f8bab89b1e336Junda Liu 17262934034e04c5ca7839de41d0cc8f8bab89b1e336Junda Liu @Override 17276d5a285c9ebe1d3a6952542b6cad3d6df51ac298Shishir Agrawal public int checkCarrierPrivilegesForPackage(String pkgname) { 1728eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal UiccCard card = UiccController.getInstance().getUiccCard(); 1729eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (card == null) { 1730eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("checkCarrierPrivilegesForPackage: No UICC"); 1731eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 1732eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 1733eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal return card.getCarrierPrivilegeStatus(mPhone.getContext().getPackageManager(), pkgname); 17342934034e04c5ca7839de41d0cc8f8bab89b1e336Junda Liu } 173589e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan 173689e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan @Override 1737eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal public List<String> getCarrierPackageNamesForBroadcastIntent(Intent intent) { 1738eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal UiccCard card = UiccController.getInstance().getUiccCard(); 1739eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal if (card == null) { 1740eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal loge("getCarrierPackageNamesForBroadcastIntent: No UICC"); 1741eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal return null ; 1742eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal } 1743eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal return card.getCarrierPackageNamesForBroadcastIntent( 1744eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal mPhone.getContext().getPackageManager(), intent); 1745eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal } 1746eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal 1747eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal @Override 174889e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan public void enableSimplifiedNetworkSettings(long subId, boolean enable) { 1749352d8cdf7ed125668d865f61172abfc31835c5a9Derek Tan enforceModifyPermissionOrCarrierPrivilege(); 175089e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan if (enable) { 175189e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan mSimplifiedNetworkSettings.add(subId); 175289e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan } else { 175389e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan mSimplifiedNetworkSettings.remove(subId); 175489e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan } 175589e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan } 175689e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan 175789e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan @Override 175889e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan public boolean getSimplifiedNetworkSettingsEnabled(long subId) { 175989e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan enforceReadPermission(); 176089e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan return mSimplifiedNetworkSettings.contains(subId); 176189e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan } 17627226c84acb402f96e527650347391fa025294350Derek Tan 17637226c84acb402f96e527650347391fa025294350Derek Tan @Override 17647226c84acb402f96e527650347391fa025294350Derek Tan public void setLine1NumberForDisplay(long subId, String alphaTag, String number) { 1765352d8cdf7ed125668d865f61172abfc31835c5a9Derek Tan enforceModifyPermissionOrCarrierPrivilege(); 17667226c84acb402f96e527650347391fa025294350Derek Tan mAdnRecordsForDisplay.put(subId, new AdnRecord(alphaTag, number)); 17677226c84acb402f96e527650347391fa025294350Derek Tan } 17687226c84acb402f96e527650347391fa025294350Derek Tan 17697226c84acb402f96e527650347391fa025294350Derek Tan @Override 17707226c84acb402f96e527650347391fa025294350Derek Tan public String getLine1NumberForDisplay(long subId) { 17717226c84acb402f96e527650347391fa025294350Derek Tan enforceReadPermission(); 17727226c84acb402f96e527650347391fa025294350Derek Tan if (!mAdnRecordsForDisplay.containsKey(subId)) { 17737226c84acb402f96e527650347391fa025294350Derek Tan return null; 17747226c84acb402f96e527650347391fa025294350Derek Tan } 17757226c84acb402f96e527650347391fa025294350Derek Tan AdnRecord adnRecord = mAdnRecordsForDisplay.get(subId); 17767226c84acb402f96e527650347391fa025294350Derek Tan if (adnRecord.getNumber() == null || adnRecord.getNumber().isEmpty()) { 17777226c84acb402f96e527650347391fa025294350Derek Tan return null; 17787226c84acb402f96e527650347391fa025294350Derek Tan } 17797226c84acb402f96e527650347391fa025294350Derek Tan return adnRecord.getNumber(); 17807226c84acb402f96e527650347391fa025294350Derek Tan } 17817226c84acb402f96e527650347391fa025294350Derek Tan 17827226c84acb402f96e527650347391fa025294350Derek Tan @Override 17837226c84acb402f96e527650347391fa025294350Derek Tan public String getLine1AlphaTagForDisplay(long subId) { 17847226c84acb402f96e527650347391fa025294350Derek Tan enforceReadPermission(); 17857226c84acb402f96e527650347391fa025294350Derek Tan if (!mAdnRecordsForDisplay.containsKey(subId)) { 17867226c84acb402f96e527650347391fa025294350Derek Tan return null; 17877226c84acb402f96e527650347391fa025294350Derek Tan } 17887226c84acb402f96e527650347391fa025294350Derek Tan AdnRecord adnRecord = mAdnRecordsForDisplay.get(subId); 17897226c84acb402f96e527650347391fa025294350Derek Tan if (adnRecord.getAlphaTag() == null || adnRecord.getAlphaTag().isEmpty()) { 17907226c84acb402f96e527650347391fa025294350Derek Tan return null; 17917226c84acb402f96e527650347391fa025294350Derek Tan } 17927226c84acb402f96e527650347391fa025294350Derek Tan return adnRecord.getAlphaTag(); 17937226c84acb402f96e527650347391fa025294350Derek Tan } 1794b1ebf8c3755b7e1cb207cbd49f6c8bdfa3566668Shishir Agrawal 1795b1ebf8c3755b7e1cb207cbd49f6c8bdfa3566668Shishir Agrawal @Override 1796b1ebf8c3755b7e1cb207cbd49f6c8bdfa3566668Shishir Agrawal public boolean setOperatorBrandOverride(String iccId, String brand) { 1797b1ebf8c3755b7e1cb207cbd49f6c8bdfa3566668Shishir Agrawal enforceModifyPermissionOrCarrierPrivilege(); 1798b1ebf8c3755b7e1cb207cbd49f6c8bdfa3566668Shishir Agrawal return mPhone.setOperatorBrandOverride(iccId, brand); 1799b1ebf8c3755b7e1cb207cbd49f6c8bdfa3566668Shishir Agrawal } 18007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon} 1801