PhoneInterfaceManager.java revision 117fee7467c140dccdc66972f60031dae2d55b35
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; 247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.net.ConnectivityManager; 257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.net.Uri; 267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.AsyncResult; 277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Binder; 287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Bundle; 297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Handler; 3036ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport android.os.IBinder; 317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Looper; 327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Message; 337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Process; 3436ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport android.os.RemoteException; 357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.ServiceManager; 367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.UserHandle; 37f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awadimport android.provider.Settings; 387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.telephony.CellInfo; 39e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport android.telephony.NeighboringCellInfo; 407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.telephony.ServiceState; 41f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awadimport android.telephony.TelephonyManager; 427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.text.TextUtils; 437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.util.Log; 44e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport android.util.Pair; 457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 46566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.CallManager; 47566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.CommandException; 4836ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport com.android.internal.telephony.Connection; 497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.DefaultPhoneNotifier; 507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.ITelephony; 51e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport com.android.internal.telephony.IccCard; 527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.Phone; 537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.PhoneConstants; 54566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.uicc.IccIoResult; 55566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.uicc.IccUtils; 56566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.uicc.UiccController; 57e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport com.android.internal.util.HexDump; 5836ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport com.android.services.telephony.common.Call; 597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport java.util.ArrayList; 6136ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport java.util.HashMap; 6236ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport java.util.Iterator; 63e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport java.util.List; 6436ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Pealimport java.util.Map; 657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon/** 677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Implementation of the ITelephony interface. 687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 69117fee7467c140dccdc66972f60031dae2d55b35Santos Cordonpublic class PhoneInterfaceManager extends ITelephony.Stub { 707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final String LOG_TAG = "PhoneInterfaceManager"; 717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2); 727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final boolean DBG_LOC = false; 737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Message codes used with mMainThreadHandler 757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_HANDLE_PIN_MMI = 1; 767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_HANDLE_NEIGHBORING_CELL = 2; 777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int EVENT_NEIGHBORING_CELL_DONE = 3; 787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_ANSWER_RINGING_CALL = 4; 797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_END_CALL = 5; // not used yet 807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_SILENCE_RINGER = 6; 81566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int CMD_TRANSMIT_APDU = 7; 82566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int EVENT_TRANSMIT_APDU_DONE = 8; 83566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int CMD_OPEN_CHANNEL = 9; 84566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int EVENT_OPEN_CHANNEL_DONE = 10; 85566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int CMD_CLOSE_CHANNEL = 11; 86566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int EVENT_CLOSE_CHANNEL_DONE = 12; 87e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_READ_ITEM = 13; 88e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_READ_ITEM_DONE = 14; 89e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_WRITE_ITEM = 15; 90e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_WRITE_ITEM_DONE = 16; 91e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_WRITE_CDMA_PRL = 17; 92e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18; 93e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_RESET_CONFIG = 19; 94e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_RESET_CONFIG_DONE = 20; 957c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21; 967c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22; 977c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23; 987c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24; 9935b5945231af96ad0d7ebf4cfcaafeb677d8c75cSailesh Nepal private static final int CMD_SEND_ENVELOPE = 25; 10035b5945231af96ad0d7ebf4cfcaafeb677d8c75cSailesh Nepal private static final int EVENT_SEND_ENVELOPE_DONE = 26; 1017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The singleton instance. */ 1037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static PhoneInterfaceManager sInstance; 1047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneGlobals mApp; 1067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Phone mPhone; 1077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CallManager mCM; 1087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AppOpsManager mAppOps; 1097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon MainThreadHandler mMainThreadHandler; 110406c0341600bd414fe7561b4edd8cdf7ed11f315Santos Cordon CallHandlerServiceProxy mCallHandlerService; 1117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 113566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal * A request object to use for transmitting data to an ICC. 114566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal */ 115566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final class IccAPDUArgument { 116566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public int channel, cla, command, p1, p2, p3; 117566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public String data; 118566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 119566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public IccAPDUArgument(int channel, int cla, int command, 120566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal int p1, int p2, int p3, String data) { 121566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.channel = channel; 122566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.cla = cla; 123566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.command = command; 124566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.p1 = p1; 125566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.p2 = p2; 126566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.p3 = p3; 127566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.data = data; 128566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 129566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 130566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 131566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal /** 1327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the 1337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * request after sending. The main thread will notify the request when it is complete. 1347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 1357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final class MainThreadRequest { 1367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The argument to use for the request */ 1377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public Object argument; 1387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The result of the request that is run on the main thread */ 1397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public Object result; 1407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public MainThreadRequest(Object argument) { 1427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon this.argument = argument; 1437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 146cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal private static final class IncomingThirdPartyCallArgs { 147cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public final ComponentName component; 148cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public final String callId; 149cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public final String callerDisplayName; 150cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal 151cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public IncomingThirdPartyCallArgs(ComponentName component, String callId, 152cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal String callerDisplayName) { 153cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal this.component = component; 154cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal this.callId = callId; 155cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal this.callerDisplayName = callerDisplayName; 156cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal } 157cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal } 158cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal 1597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * A handler that processes messages on the main thread in the phone process. Since many 1617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * of the Phone calls are not thread safe this is needed to shuttle the requests from the 1627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * inbound binder threads to the main thread in the phone process. The Binder thread 1637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting 1647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * on, which will be notified when the operation completes and will contain the result of the 1657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * request. 1667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 1677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * <p>If a MainThreadRequest object is provided in the msg.obj field, 1687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * note that request.result must be set to something non-null for the calling thread to 1697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * unblock. 1707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 1717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private final class MainThreadHandler extends Handler { 1727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 1737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void handleMessage(Message msg) { 1747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon MainThreadRequest request; 1757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message onCompleted; 1767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AsyncResult ar; 1777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon switch (msg.what) { 1797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_HANDLE_PIN_MMI: 1807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) msg.obj; 181e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = mPhone.handlePinMmi((String) request.argument); 1827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wake up the requesting thread 1837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 1847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.notifyAll(); 1857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 1877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_HANDLE_NEIGHBORING_CELL: 1897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) msg.obj; 1907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onCompleted = obtainMessage(EVENT_NEIGHBORING_CELL_DONE, 1917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request); 1927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.getNeighboringCids(onCompleted); 1937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 1947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case EVENT_NEIGHBORING_CELL_DONE: 1967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ar = (AsyncResult) msg.obj; 1977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) ar.userObj; 1987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (ar.exception == null && ar.result != null) { 1997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.result = ar.result; 2007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 2017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // create an empty list to notify the waiting thread 202e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = new ArrayList<NeighboringCellInfo>(0); 2037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wake up the requesting thread 2057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 2067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.notifyAll(); 2077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_ANSWER_RINGING_CALL: 2117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon answerRingingCallInternal(); 2127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_SILENCE_RINGER: 2157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon silenceRingerInternal(); 2167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_END_CALL: 2197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) msg.obj; 220e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby boolean hungUp; 2217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int phoneType = mPhone.getPhoneType(); 2227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { 2237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // CDMA: If the user presses the Power button we treat it as 2247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ending the complete call session 2257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon hungUp = PhoneUtils.hangupRingingAndActive(mPhone); 2267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) { 2277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // GSM: End the call as per the Phone state 2287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon hungUp = PhoneUtils.hangup(mCM); 2297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 2307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon throw new IllegalStateException("Unexpected phone type: " + phoneType); 2317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("CMD_END_CALL: " + (hungUp ? "hung up!" : "no call to hang up")); 2337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.result = hungUp; 2347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wake up the requesting thread 2357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 2367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.notifyAll(); 2377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 240566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case CMD_TRANSMIT_APDU: 241566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) msg.obj; 242566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal IccAPDUArgument argument = (IccAPDUArgument) request.argument; 243566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_DONE, request); 244566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal UiccController.getInstance().getUiccCard().iccTransmitApduLogicalChannel( 245566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal argument.channel, argument.cla, argument.command, 246566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal argument.p1, argument.p2, argument.p3, argument.data, 247566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal onCompleted); 248566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 249566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 250566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case EVENT_TRANSMIT_APDU_DONE: 251566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal ar = (AsyncResult) msg.obj; 252566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) ar.userObj; 253566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.exception == null && ar.result != null) { 254566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.result = ar.result; 255566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 256566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 257566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.result == null) { 258566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccTransmitApduLogicalChannel: Empty response"); 259e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else if (ar.exception instanceof CommandException) { 260566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccTransmitApduLogicalChannel: CommandException: " + 261e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby ar.exception); 262566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 263566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccTransmitApduLogicalChannel: Unknown exception"); 264566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 265566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 266566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal synchronized (request) { 267566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.notifyAll(); 268566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 269566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 270566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 2714d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan case CMD_SEND_ENVELOPE: 2724d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan request = (MainThreadRequest) msg.obj; 2734d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request); 2749f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal UiccController.getInstance().getUiccCard().sendEnvelopeWithStatus( 2754d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan (String)request.argument, onCompleted); 2764d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan break; 2774d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan 2784d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan case EVENT_SEND_ENVELOPE_DONE: 2794d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan ar = (AsyncResult) msg.obj; 2804d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan request = (MainThreadRequest) ar.userObj; 2819f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal if (ar.exception == null && ar.result != null) { 2829f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal request.result = ar.result; 2834d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan } else { 2849f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 2859f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal if (ar.result == null) { 2869f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal loge("sendEnvelopeWithStatus: Empty response"); 2879f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal } else if (ar.exception instanceof CommandException) { 2889f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal loge("sendEnvelopeWithStatus: CommandException: " + 2899f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal ar.exception); 2909f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal } else { 2919f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal loge("sendEnvelopeWithStatus: exception:" + ar.exception); 2929f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal } 2934d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan } 2944d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan synchronized (request) { 2954d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan request.notifyAll(); 2964d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan } 2974d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan break; 2984d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan 299566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case CMD_OPEN_CHANNEL: 300566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) msg.obj; 301566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request); 302566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal UiccController.getInstance().getUiccCard().iccOpenLogicalChannel( 303566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal (String)request.argument, onCompleted); 304566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 305566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 306566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case EVENT_OPEN_CHANNEL_DONE: 307566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal ar = (AsyncResult) msg.obj; 308566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) ar.userObj; 309566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.exception == null && ar.result != null) { 310e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = ((int[]) ar.result)[0]; 311566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 312e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = -1; 313566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.result == null) { 314566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccOpenLogicalChannel: Empty response"); 315e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else if (ar.exception instanceof CommandException) { 316566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccOpenLogicalChannel: CommandException: " + 317e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby ar.exception); 318566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 319566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccOpenLogicalChannel: Unknown exception"); 320566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 321566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 322566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal synchronized (request) { 323566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.notifyAll(); 324566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 325566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 326566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 327566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case CMD_CLOSE_CHANNEL: 328566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) msg.obj; 329566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, 330566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request); 331566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal UiccController.getInstance().getUiccCard().iccCloseLogicalChannel( 332e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby (Integer) request.argument, 333566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal onCompleted); 334566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 335566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 336566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case EVENT_CLOSE_CHANNEL_DONE: 337e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "iccCloseLogicalChannel"); 338e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 339e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 340e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_READ_ITEM: 341e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 342e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request); 343e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvReadItem((Integer) request.argument, onCompleted); 344e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 345e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 346e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_READ_ITEM_DONE: 347566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal ar = (AsyncResult) msg.obj; 348566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) ar.userObj; 349e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.exception == null && ar.result != null) { 350e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = ar.result; // String 351566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 352e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = ""; 353e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.result == null) { 354e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge("nvReadItem: Empty response"); 355e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else if (ar.exception instanceof CommandException) { 356e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge("nvReadItem: CommandException: " + 357e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby ar.exception); 358566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 359e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge("nvReadItem: Unknown exception"); 360566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 361566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 362566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal synchronized (request) { 363566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.notifyAll(); 364566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 365566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 366566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 367e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_WRITE_ITEM: 368e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 369e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request); 370e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument; 371e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvWriteItem(idValue.first, idValue.second, onCompleted); 372e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 373e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 374e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_WRITE_ITEM_DONE: 375e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "nvWriteItem"); 376e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 377e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 378e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_WRITE_CDMA_PRL: 379e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 380e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request); 381e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted); 382e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 383e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 384e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_WRITE_CDMA_PRL_DONE: 385e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "nvWriteCdmaPrl"); 386e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 387e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 388e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_RESET_CONFIG: 389e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 390e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_RESET_CONFIG_DONE, request); 391e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvResetConfig((Integer) request.argument, onCompleted); 392e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 393e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 394e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_RESET_CONFIG_DONE: 395e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "nvResetConfig"); 396e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 397e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 3987c27be317e8757948178815426d3a329c852b9eeJake Hamby case CMD_GET_PREFERRED_NETWORK_TYPE: 3997c27be317e8757948178815426d3a329c852b9eeJake Hamby request = (MainThreadRequest) msg.obj; 4007c27be317e8757948178815426d3a329c852b9eeJake Hamby onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request); 4017c27be317e8757948178815426d3a329c852b9eeJake Hamby mPhone.getPreferredNetworkType(onCompleted); 4027c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 4037c27be317e8757948178815426d3a329c852b9eeJake Hamby 4047c27be317e8757948178815426d3a329c852b9eeJake Hamby case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE: 4057c27be317e8757948178815426d3a329c852b9eeJake Hamby ar = (AsyncResult) msg.obj; 4067c27be317e8757948178815426d3a329c852b9eeJake Hamby request = (MainThreadRequest) ar.userObj; 4077c27be317e8757948178815426d3a329c852b9eeJake Hamby if (ar.exception == null && ar.result != null) { 4087c27be317e8757948178815426d3a329c852b9eeJake Hamby request.result = ar.result; // Integer 4097c27be317e8757948178815426d3a329c852b9eeJake Hamby } else { 4107c27be317e8757948178815426d3a329c852b9eeJake Hamby request.result = -1; 4117c27be317e8757948178815426d3a329c852b9eeJake Hamby if (ar.result == null) { 4127c27be317e8757948178815426d3a329c852b9eeJake Hamby loge("getPreferredNetworkType: Empty response"); 4137c27be317e8757948178815426d3a329c852b9eeJake Hamby } else if (ar.exception instanceof CommandException) { 4147c27be317e8757948178815426d3a329c852b9eeJake Hamby loge("getPreferredNetworkType: CommandException: " + 4157c27be317e8757948178815426d3a329c852b9eeJake Hamby ar.exception); 4167c27be317e8757948178815426d3a329c852b9eeJake Hamby } else { 4177c27be317e8757948178815426d3a329c852b9eeJake Hamby loge("getPreferredNetworkType: Unknown exception"); 4187c27be317e8757948178815426d3a329c852b9eeJake Hamby } 4197c27be317e8757948178815426d3a329c852b9eeJake Hamby } 4207c27be317e8757948178815426d3a329c852b9eeJake Hamby synchronized (request) { 4217c27be317e8757948178815426d3a329c852b9eeJake Hamby request.notifyAll(); 4227c27be317e8757948178815426d3a329c852b9eeJake Hamby } 4237c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 4247c27be317e8757948178815426d3a329c852b9eeJake Hamby 4257c27be317e8757948178815426d3a329c852b9eeJake Hamby case CMD_SET_PREFERRED_NETWORK_TYPE: 4267c27be317e8757948178815426d3a329c852b9eeJake Hamby request = (MainThreadRequest) msg.obj; 4277c27be317e8757948178815426d3a329c852b9eeJake Hamby onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request); 4287c27be317e8757948178815426d3a329c852b9eeJake Hamby int networkType = (Integer) request.argument; 4297c27be317e8757948178815426d3a329c852b9eeJake Hamby mPhone.setPreferredNetworkType(networkType, onCompleted); 4307c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 4317c27be317e8757948178815426d3a329c852b9eeJake Hamby 4327c27be317e8757948178815426d3a329c852b9eeJake Hamby case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE: 4337c27be317e8757948178815426d3a329c852b9eeJake Hamby handleNullReturnEvent(msg, "setPreferredNetworkType"); 4347c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 4357c27be317e8757948178815426d3a329c852b9eeJake Hamby 4367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon default: 4377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what); 4387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 4397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 441e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 442e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private void handleNullReturnEvent(Message msg, String command) { 443e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby AsyncResult ar = (AsyncResult) msg.obj; 444e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby MainThreadRequest request = (MainThreadRequest) ar.userObj; 445e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.exception == null) { 446e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = true; 447e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else { 448e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = false; 449e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.exception instanceof CommandException) { 450e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge(command + ": CommandException: " + ar.exception); 451e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else { 452e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge(command + ": Unknown exception"); 453e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 454e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 455e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby synchronized (request) { 456e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.notifyAll(); 457e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 458e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 4597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 4627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Posts the specified command to be executed on the main thread, 4637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * waits for the request to complete, and returns the result. 4647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #sendRequestAsync 4657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 4667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Object sendRequest(int command, Object argument) { 4677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (Looper.myLooper() == mMainThreadHandler.getLooper()) { 4687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon throw new RuntimeException("This method will deadlock if called from the main thread."); 4697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon MainThreadRequest request = new MainThreadRequest(argument); 4727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message msg = mMainThreadHandler.obtainMessage(command, request); 4737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon msg.sendToTarget(); 4747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wait for the request to complete 4767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 4777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon while (request.result == null) { 4787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 4797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.wait(); 4807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 4817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Do nothing, go back and wait until the request is complete 4827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return request.result; 4867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 4897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Asynchronous ("fire and forget") version of sendRequest(): 4907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Posts the specified command to be executed on the main thread, and 4917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * returns immediately. 4927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #sendRequest 4937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 4947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void sendRequestAsync(int command) { 4957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mMainThreadHandler.sendEmptyMessage(command); 4967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 499bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal * Same as {@link #sendRequestAsync(int)} except it takes an argument. 500bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal * @see {@link #sendRequest(int,Object)} 501bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal */ 502bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal private void sendRequestAsync(int command, Object argument) { 503bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal MainThreadRequest request = new MainThreadRequest(argument); 504bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal Message msg = mMainThreadHandler.obtainMessage(command, request); 505bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal msg.sendToTarget(); 506bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal } 507bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal 508bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal /** 5097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Initialize the singleton PhoneInterfaceManager instance. 5107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This is only done once, at startup, from PhoneApp.onCreate(). 5117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 512406c0341600bd414fe7561b4edd8cdf7ed11f315Santos Cordon /* package */ static PhoneInterfaceManager init(PhoneGlobals app, Phone phone, 513117fee7467c140dccdc66972f60031dae2d55b35Santos Cordon CallHandlerServiceProxy callHandlerService) { 5147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (PhoneInterfaceManager.class) { 5157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (sInstance == null) { 516117fee7467c140dccdc66972f60031dae2d55b35Santos Cordon sInstance = new PhoneInterfaceManager(app, phone, callHandlerService); 5177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 5187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance); 5197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return sInstance; 5217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** Private constructor; @see init() */ 525406c0341600bd414fe7561b4edd8cdf7ed11f315Santos Cordon private PhoneInterfaceManager(PhoneGlobals app, Phone phone, 526117fee7467c140dccdc66972f60031dae2d55b35Santos Cordon CallHandlerServiceProxy callHandlerService) { 5277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp = app; 5287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone = phone; 5297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCM = PhoneGlobals.getInstance().mCM; 5307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE); 5317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mMainThreadHandler = new MainThreadHandler(); 532406c0341600bd414fe7561b4edd8cdf7ed11f315Santos Cordon mCallHandlerService = callHandlerService; 5337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon publish(); 5347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void publish() { 5377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("publish: " + this); 5387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ServiceManager.addService("phone", this); 5407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 5437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Implementation of the ITelephony interface. 5447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 5457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void dial(String number) { 5477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("dial: " + number); 5487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No permission check needed here: This is just a wrapper around the 5497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ACTION_DIAL intent, which is available to any app since it puts up 5507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the UI before it does anything. 5517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon String url = createTelUrl(number); 5537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (url == null) { 5547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 5557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // PENDING: should we just silently fail if phone is offhook or ringing? 5587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneConstants.State state = mCM.getState(); 5597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) { 5607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url)); 5617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 5627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.startActivity(intent); 5637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void call(String callingPackage, String number) { 5677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("call: " + number); 5687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // This is just a wrapper around the ACTION_CALL intent, but we still 5707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // need to do a permission check since we're calling startActivity() 5717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // from the context of the phone app. 5727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceCallPermission(); 5737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mAppOps.noteOp(AppOpsManager.OP_CALL_PHONE, Binder.getCallingUid(), callingPackage) 5757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon != AppOpsManager.MODE_ALLOWED) { 5767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 5777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon String url = createTelUrl(number); 5807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (url == null) { 5817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 5827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url)); 5857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 5867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.startActivity(intent); 5877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private boolean showCallScreenInternal(boolean specifyInitialDialpadState, 590bcf2099b92870b863f53e79288d4c8e73a4dc42dMakoto Onuki boolean showDialpad) { 5917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!PhoneGlobals.sVoiceCapable) { 5927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Never allow the InCallScreen to appear on data-only devices. 5937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return false; 5947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (isIdle()) { 5967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return false; 5977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If the phone isn't idle then go to the in-call screen 5997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon long callingId = Binder.clearCallingIdentity(); 600406c0341600bd414fe7561b4edd8cdf7ed11f315Santos Cordon 601bcf2099b92870b863f53e79288d4c8e73a4dc42dMakoto Onuki mCallHandlerService.bringToForeground(showDialpad); 602406c0341600bd414fe7561b4edd8cdf7ed11f315Santos Cordon 603406c0341600bd414fe7561b4edd8cdf7ed11f315Santos Cordon Binder.restoreCallingIdentity(callingId); 6047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 6057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Show the in-call screen without specifying the initial dialpad state. 6087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean showCallScreen() { 6097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return showCallScreenInternal(false, false); 6107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // The variation of showCallScreen() that specifies the initial dialpad state. 6137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // (Ideally this would be called showCallScreen() too, just with a different 6147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // signature, but AIDL doesn't allow that.) 6157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean showCallScreenWithDialpad(boolean showDialpad) { 6167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return showCallScreenInternal(true, showDialpad); 6177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 6207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * End a call based on call state 6217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return true is a call was ended 6227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 6237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean endCall() { 6247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceCallPermission(); 6257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return (Boolean) sendRequest(CMD_END_CALL, null); 6267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void answerRingingCall() { 6297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("answerRingingCall..."); 6307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: there should eventually be a separate "ANSWER_PHONE" permission, 6317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // but that can probably wait till the big TelephonyManager API overhaul. 6327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For now, protect this call with the MODIFY_PHONE_STATE permission. 6337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 6347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon sendRequestAsync(CMD_ANSWER_RINGING_CALL); 6357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 6387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make the actual telephony calls to implement answerRingingCall(). 6397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This should only be called from the main thread of the Phone app. 6407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #answerRingingCall 6417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 6427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * TODO: it would be nice to return true if we answered the call, or 6437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * false if there wasn't actually a ringing incoming call, or some 6447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * other error occurred. (In other words, pass back the return value 6457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * from PhoneUtils.answerCall() or PhoneUtils.answerAndEndActive().) 6467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * But that would require calling this method via sendRequest() rather 6477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * than sendRequestAsync(), and right now we don't actually *need* that 6487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * return value, so let's just return void for now. 6497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 6507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void answerRingingCallInternal() { 6517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final boolean hasRingingCall = !mPhone.getRingingCall().isIdle(); 6527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (hasRingingCall) { 6537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final boolean hasActiveCall = !mPhone.getForegroundCall().isIdle(); 6547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final boolean hasHoldingCall = !mPhone.getBackgroundCall().isIdle(); 6557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (hasActiveCall && hasHoldingCall) { 6567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Both lines are in use! 6577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: provide a flag to let the caller specify what 6587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // policy to use if both lines are in use. (The current 6597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // behavior is hardwired to "answer incoming, end ongoing", 6607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // which is how the CALL button is specced to behave.) 6617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.answerAndEndActive(mCM, mCM.getFirstActiveRingingCall()); 6627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 6637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 6647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // answerCall() will automatically hold the current active 6657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // call, if there is one. 6667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.answerCall(mCM.getFirstActiveRingingCall()); 6677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 6687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 6707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No call was ringing. 6717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 6727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void silenceRinger() { 6767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("silenceRinger..."); 6777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: find a more appropriate permission to check here. 6787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // (That can probably wait till the big TelephonyManager API overhaul. 6797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For now, protect this call with the MODIFY_PHONE_STATE permission.) 6807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 6817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon sendRequestAsync(CMD_SILENCE_RINGER); 6827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 6857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Internal implemenation of silenceRinger(). 6867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This should only be called from the main thread of the Phone app. 6877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #silenceRinger 6887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 6897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void silenceRingerInternal() { 6907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((mCM.getState() == PhoneConstants.State.RINGING) 6917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon && mApp.notifier.isRinging()) { 6927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Ringer is actually playing, so silence it. 6937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("silenceRingerInternal: silencing..."); 6947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.notifier.silenceRinger(); 6957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isOffhook() { 6997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return (mCM.getState() == PhoneConstants.State.OFFHOOK); 7007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isRinging() { 7037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return (mCM.getState() == PhoneConstants.State.RINGING); 7047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isIdle() { 7077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return (mCM.getState() == PhoneConstants.State.IDLE); 7087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isSimPinEnabled() { 7117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceReadPermission(); 7127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return (PhoneGlobals.getInstance().isSimPinEnabled()); 7137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean supplyPin(String pin) { 7169de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville int [] resultArray = supplyPinReportResult(pin); 7179de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false; 7189de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 7199de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville 7209de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville public boolean supplyPuk(String puk, String pin) { 7219de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville int [] resultArray = supplyPukReportResult(puk, pin); 7229de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false; 7239de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 7249de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville 7259de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville /** {@hide} */ 7269de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville public int[] supplyPinReportResult(String pin) { 7277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 7287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final UnlockSim checkSimPin = new UnlockSim(mPhone.getIccCard()); 7297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon checkSimPin.start(); 7307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return checkSimPin.unlockSim(null, pin); 7317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7339de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville /** {@hide} */ 7349de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville public int[] supplyPukReportResult(String puk, String pin) { 7357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 7367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final UnlockSim checkSimPuk = new UnlockSim(mPhone.getIccCard()); 7377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon checkSimPuk.start(); 7387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return checkSimPuk.unlockSim(puk, pin); 7397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 7429de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville * Helper thread to turn async call to SimCard#supplyPin into 7437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * a synchronous one. 7447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 7457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static class UnlockSim extends Thread { 7467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private final IccCard mSimCard; 7487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private boolean mDone = false; 7509de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville private int mResult = PhoneConstants.PIN_GENERAL_FAILURE; 7519de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville private int mRetryCount = -1; 7527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For replies from SimCard interface 7547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Handler mHandler; 7557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For async handler to identify request type 7577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int SUPPLY_PIN_COMPLETE = 100; 7587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public UnlockSim(IccCard simCard) { 7607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSimCard = simCard; 7617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 7647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void run() { 7657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Looper.prepare(); 7667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (UnlockSim.this) { 7677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mHandler = new Handler() { 7687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 7697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void handleMessage(Message msg) { 7707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AsyncResult ar = (AsyncResult) msg.obj; 7717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon switch (msg.what) { 7727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case SUPPLY_PIN_COMPLETE: 7737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE"); 7747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (UnlockSim.this) { 7759de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mRetryCount = msg.arg1; 7769de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville if (ar.exception != null) { 7779de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville if (ar.exception instanceof CommandException && 7789de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville ((CommandException)(ar.exception)).getCommandError() 7799de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville == CommandException.Error.PASSWORD_INCORRECT) { 7809de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mResult = PhoneConstants.PIN_PASSWORD_INCORRECT; 7819de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } else { 7829de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mResult = PhoneConstants.PIN_GENERAL_FAILURE; 7839de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 7849de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } else { 7859de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mResult = PhoneConstants.PIN_RESULT_SUCCESS; 7869de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 7877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mDone = true; 7887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon UnlockSim.this.notifyAll(); 7897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 7917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon }; 7947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon UnlockSim.this.notifyAll(); 7957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Looper.loop(); 7977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* 8007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Use PIN or PUK to unlock SIM card 8017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 8027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * If PUK is null, unlock SIM card with PIN 8037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 8047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * If PUK is not null, unlock SIM card with PUK and set PIN code 8057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 8069de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville synchronized int[] unlockSim(String puk, String pin) { 8077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon while (mHandler == null) { 8097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 8107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon wait(); 8117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 8127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Thread.currentThread().interrupt(); 8137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE); 8167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (puk == null) { 8187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSimCard.supplyPin(pin, callback); 8197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 8207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSimCard.supplyPuk(puk, pin, callback); 8217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon while (!mDone) { 8247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 8257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "wait for done"); 8267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon wait(); 8277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 8287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Restore the interrupted status 8297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Thread.currentThread().interrupt(); 8307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "done"); 8339de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville int[] resultArray = new int[2]; 8349de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville resultArray[0] = mResult; 8359de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville resultArray[1] = mRetryCount; 8369de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville return resultArray; 8377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void updateServiceLocation() { 8417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No permission check needed here: this call is harmless, and it's 8427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // needed for the ServiceState.requestStateUpdate() call (which is 8437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // already intentionally exposed to 3rd parties.) 8447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.updateServiceLocation(); 8457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isRadioOn() { 8487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getServiceState().getVoiceRegState() != ServiceState.STATE_POWER_OFF; 8497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void toggleRadioOnOff() { 8527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 8537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.setRadioPower(!isRadioOn()); 8547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean setRadio(boolean turnOn) { 8567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 8577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((mPhone.getServiceState().getVoiceRegState() != ServiceState.STATE_POWER_OFF) != turnOn) { 8587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toggleRadioOnOff(); 8597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 8617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean setRadioPower(boolean turnOn) { 8637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 8647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.setRadioPower(turnOn); 8657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 8667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean enableDataConnectivity() { 8697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 8707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ConnectivityManager cm = 8717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (ConnectivityManager)mApp.getSystemService(Context.CONNECTIVITY_SERVICE); 8727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon cm.setMobileDataEnabled(true); 8737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 8747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int enableApnType(String type) { 8777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 8787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.enableApnType(type); 8797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int disableApnType(String type) { 8827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 8837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.disableApnType(type); 8847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean disableDataConnectivity() { 8877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 8887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ConnectivityManager cm = 8897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (ConnectivityManager)mApp.getSystemService(Context.CONNECTIVITY_SERVICE); 8907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon cm.setMobileDataEnabled(false); 8917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 8927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isDataConnectivityPossible() { 8957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.isDataConnectivityPossible(); 8967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean handlePinMmi(String dialString) { 8997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 9007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString); 9017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void cancelMissedCallsNotification() { 9047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 9057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.notificationMgr.cancelMissedCallNotification(); 9067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getCallState() { 9097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return DefaultPhoneNotifier.convertCallState(mCM.getState()); 9107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getDataState() { 9137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return DefaultPhoneNotifier.convertDataState(mPhone.getDataConnectionState()); 9147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getDataActivity() { 9177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return DefaultPhoneNotifier.convertDataActivityState(mPhone.getDataActivityState()); 9187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 9217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public Bundle getCellLocation() { 9227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 9237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 9247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_FINE_LOCATION, null); 9257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (SecurityException e) { 9267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If we have ACCESS_FINE_LOCATION permission, skip the check for ACCESS_COARSE_LOCATION 9277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // A failure should throw the SecurityException from ACCESS_COARSE_LOCATION since this 9287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // is the weaker precondition 9297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 9307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 9317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 933e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (checkIfCallerIsSelfOrForegroundUser()) { 9347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getCellLocation: is active user"); 9357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Bundle data = new Bundle(); 9367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.getCellLocation().fillInNotifierBundle(data); 9377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return data; 9387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 9397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getCellLocation: suppress non-active user"); 9407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 9417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 9457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void enableLocationUpdates() { 9467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 9477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.CONTROL_LOCATION_UPDATES, null); 9487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.enableLocationUpdates(); 9497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 9527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void disableLocationUpdates() { 9537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 9547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.CONTROL_LOCATION_UPDATES, null); 9557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.disableLocationUpdates(); 9567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 9597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @SuppressWarnings("unchecked") 9607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage) { 9617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 9627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 9637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_FINE_LOCATION, null); 9647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (SecurityException e) { 9657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If we have ACCESS_FINE_LOCATION permission, skip the check 9667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // for ACCESS_COARSE_LOCATION 9677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // A failure should throw the SecurityException from 9687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ACCESS_COARSE_LOCATION since this is the weaker precondition 9697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 9707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 9717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(), 9747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon callingPackage) != AppOpsManager.MODE_ALLOWED) { 9757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 9767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 977e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (checkIfCallerIsSelfOrForegroundUser()) { 9787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getNeighboringCellInfo: is active user"); 9797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ArrayList<NeighboringCellInfo> cells = null; 9817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 9837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon cells = (ArrayList<NeighboringCellInfo>) sendRequest( 9847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CMD_HANDLE_NEIGHBORING_CELL, null); 9857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (RuntimeException e) { 986566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("getNeighboringCellInfo " + e); 9877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return cells; 9897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 9907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getNeighboringCellInfo: suppress non-active user"); 9917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 9927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 9977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public List<CellInfo> getAllCellInfo() { 9987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 9997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 10007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_FINE_LOCATION, null); 10017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (SecurityException e) { 10027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If we have ACCESS_FINE_LOCATION permission, skip the check for ACCESS_COARSE_LOCATION 10037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // A failure should throw the SecurityException from ACCESS_COARSE_LOCATION since this 10047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // is the weaker precondition 10057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 10067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 10077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1009e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (checkIfCallerIsSelfOrForegroundUser()) { 10107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getAllCellInfo: is active user"); 10117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getAllCellInfo(); 10127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 10137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getAllCellInfo: suppress non-active user"); 10147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 10157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1018bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal @Override 10197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void setCellInfoListRate(int rateInMillis) { 10207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.setCellInfoListRate(rateInMillis); 10217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 10247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Internal helper methods. 10257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 10267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1027e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static boolean checkIfCallerIsSelfOrForegroundUser() { 10287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean ok; 10297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean self = Binder.getCallingUid() == Process.myUid(); 10317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!self) { 10327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Get the caller's user id then clear the calling identity 10337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // which will be restored in the finally clause. 10347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int callingUser = UserHandle.getCallingUserId(); 10357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon long ident = Binder.clearCallingIdentity(); 10367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 10387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // With calling identity cleared the current user is the foreground user. 10397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int foregroundUser = ActivityManager.getCurrentUser(); 10407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ok = (foregroundUser == callingUser); 10417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) { 10427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon log("checkIfCallerIsSelfOrForegoundUser: foregroundUser=" + foregroundUser 10437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon + " callingUser=" + callingUser + " ok=" + ok); 10447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (Exception ex) { 10467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) loge("checkIfCallerIsSelfOrForegoundUser: Exception ex=" + ex); 10477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ok = false; 10487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } finally { 10497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Binder.restoreCallingIdentity(ident); 10507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 10527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("checkIfCallerIsSelfOrForegoundUser: is self"); 10537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ok = true; 10547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("checkIfCallerIsSelfOrForegoundUser: ret=" + ok); 10567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return ok; 10577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 10607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make sure the caller has the READ_PHONE_STATE permission. 10617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 10627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @throws SecurityException if the caller does not have the required permission 10637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 10647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void enforceReadPermission() { 10657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE, null); 10667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 10697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make sure the caller has the MODIFY_PHONE_STATE permission. 10707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 10717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @throws SecurityException if the caller does not have the required permission 10727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 10737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void enforceModifyPermission() { 10747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null); 10757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 10787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make sure the caller has the CALL_PHONE permission. 10797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 10807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @throws SecurityException if the caller does not have the required permission 10817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 10827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void enforceCallPermission() { 10837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null); 10847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1086566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal /** 108736ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal * Make sure the caller has the READ_PRIVILEGED_PHONE_STATE permission. 108836ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal * 108936ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal * @throws SecurityException if the caller does not have the required permission 109036ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal */ 109136ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal private void enforcePrivilegedPhoneStatePermission() { 109236ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 109336ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal null); 109436ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal } 109536ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal 109636ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal /** 1097566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal * Make sure the caller has SIM_COMMUNICATION permission. 1098566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal * 1099566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal * @throws SecurityException if the caller does not have the required permission. 1100566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal */ 1101566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private void enforceSimCommunicationPermission() { 1102566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal mApp.enforceCallingOrSelfPermission(android.Manifest.permission.SIM_COMMUNICATION, null); 1103566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 11047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private String createTelUrl(String number) { 11067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (TextUtils.isEmpty(number)) { 11077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 11087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1110e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return "tel:" + number; 11117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1113f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad private static void log(String msg) { 11147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg); 11157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1117f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad private static void loge(String msg) { 11187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg); 11197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getActivePhoneType() { 11227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getPhoneType(); 11237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 11267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the CDMA ERI icon index to display 11277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 11287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getCdmaEriIconIndex() { 11297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getCdmaEriIconIndex(); 11307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 11337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the CDMA ERI icon mode, 11347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 0 - ON 11357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 1 - FLASHING 11367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 11377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getCdmaEriIconMode() { 11387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getCdmaEriIconMode(); 11397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 11427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the CDMA ERI text, 11437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 11447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public String getCdmaEriText() { 11457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getCdmaEriText(); 11467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 11497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns true if CDMA provisioning needs to run. 11507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 11517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean needsOtaServiceProvisioning() { 11527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.needsOtaServiceProvisioning(); 11537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 11567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the unread count of voicemails 11577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 11587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getVoiceMessageCount() { 11597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getVoiceMessageCount(); 11607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 11637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the data network type 11647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 11657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @Deprecated to be removed Q3 2013 use {@link #getDataNetworkType}. 11667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 11677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 11687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getNetworkType() { 11697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getServiceState().getDataNetworkType(); 11707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 11737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the data network type 11747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 11757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 11767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getDataNetworkType() { 11777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getServiceState().getDataNetworkType(); 11787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 11817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the data network type 11827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 11837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 11847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getVoiceNetworkType() { 11857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getServiceState().getVoiceNetworkType(); 11867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 11897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return true if a ICC card is present 11907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 11917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean hasIccCard() { 11927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getIccCard().hasIccCard(); 11937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 11967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Return if the current radio is LTE on CDMA. This 11977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * is a tri-state return value as for a period of time 11987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * the mode may be unknown. 11997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 12007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE} 1201e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * or {@link Phone#LTE_ON_CDMA_TRUE} 12027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 12037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getLteOnCdmaMode() { 12047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getLteOnCdmaMode(); 12057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1206f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad 1207f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad /** 1208f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad * @see android.telephony.TelephonyManager.WifiCallingChoices 1209f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad */ 1210f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad public int getWhenToMakeWifiCalls() { 1211d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal return Settings.System.getInt(mPhone.getContext().getContentResolver(), 1212d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal Settings.System.WHEN_TO_MAKE_WIFI_CALLS, getWhenToMakeWifiCallsDefaultPreference()); 1213f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad } 1214f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad 1215f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad /** 1216f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad * @see android.telephony.TelephonyManager.WifiCallingChoices 1217f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad */ 1218f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad public void setWhenToMakeWifiCalls(int preference) { 1219d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference); 1220d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal Settings.System.putInt(mPhone.getContext().getContentResolver(), 1221d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference); 1222f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad } 1223f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad 1224d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal private static int getWhenToMakeWifiCallsDefaultPreference() { 1225d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal // TODO(sail): Use a build property to choose this value. 12269829e880f73f76119ba76ba032db42aad042858fEvan Charlton return TelephonyManager.WifiCallingChoices.ALWAYS_USE; 1227f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad } 122869f68120b94cecb2d87fe856bc115714b4e77bcdShishir Agrawal 1229566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal @Override 1230566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public int iccOpenLogicalChannel(String AID) { 1231566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal enforceSimCommunicationPermission(); 1232566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1233566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccOpenLogicalChannel: " + AID); 1234566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal Integer channel = (Integer)sendRequest(CMD_OPEN_CHANNEL, AID); 1235566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccOpenLogicalChannel: " + channel); 1236e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return channel; 1237566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1238566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1239566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal @Override 1240566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public boolean iccCloseLogicalChannel(int channel) { 1241566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal enforceSimCommunicationPermission(); 1242566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1243566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccCloseLogicalChannel: " + channel); 1244566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (channel < 0) { 1245566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return false; 1246566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1247e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean)sendRequest(CMD_CLOSE_CHANNEL, channel); 1248566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccCloseLogicalChannel: " + success); 1249566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return success; 1250566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1251566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1252566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal @Override 1253566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public String iccTransmitApduLogicalChannel(int channel, int cla, 1254566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal int command, int p1, int p2, int p3, String data) { 1255566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal enforceSimCommunicationPermission(); 1256566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1257566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) { 1258566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal log("iccTransmitApduLogicalChannel: chnl=" + channel + " cla=" + cla + 1259566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + 1260566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal " data=" + data); 1261566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1262566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1263566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (channel < 0) { 1264566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return ""; 1265566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1266566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1267566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal IccIoResult response = (IccIoResult)sendRequest(CMD_TRANSMIT_APDU, 1268566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal new IccAPDUArgument(channel, cla, command, p1, p2, p3, data)); 1269566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccTransmitApduLogicalChannel: " + response); 1270566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1271566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal // If the payload is null, there was an error. Indicate that by returning 1272566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal // an empty string. 1273566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (response.payload == null) { 1274566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return ""; 1275566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1276566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1277566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal // Append the returned status code to the end of the response payload. 1278566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal String s = Integer.toHexString( 1279566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 1280566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal s = IccUtils.bytesToHexString(response.payload) + s; 1281566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return s; 1282566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1283e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 1284c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton @Override 1285c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton public String sendEnvelopeWithStatus(String content) { 1286c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton enforceSimCommunicationPermission(); 1287c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton 1288c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton IccIoResult response = (IccIoResult)sendRequest(CMD_SEND_ENVELOPE, content); 1289c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton if (response.payload == null) { 1290c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton return ""; 1291c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton } 1292c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton 1293c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton // Append the returned status code to the end of the response payload. 1294c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton String s = Integer.toHexString( 1295c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 1296c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton s = IccUtils.bytesToHexString(response.payload) + s; 1297c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton return s; 1298c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton } 1299c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton 1300e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 1301e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems} 1302e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators. 1303e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 1304e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param itemID the ID of the item to read 1305e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return the NV item as a String, or null on error. 1306e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 1307e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 1308e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public String nvReadItem(int itemID) { 1309e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby enforceModifyPermission(); 1310e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvReadItem: item " + itemID); 1311e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID); 1312e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"'); 1313e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return value; 1314e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 1315e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 1316e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 1317e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems} 1318e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators. 1319e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 1320e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param itemID the ID of the item to read 1321e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param itemValue the value to write, as a String 1322e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return true on success; false on any failure 1323e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 1324e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 1325e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public boolean nvWriteItem(int itemID, String itemValue) { 1326e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby enforceModifyPermission(); 1327e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"'); 1328e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM, 1329e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby new Pair<Integer, String>(itemID, itemValue)); 1330e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail")); 1331e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return success; 1332e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 1333e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 1334e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 1335e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage. 1336e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Used for device configuration by some CDMA operators. 1337e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 1338e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param preferredRoamingList byte array containing the new PRL 1339e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return true on success; false on any failure 1340e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 1341e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 1342e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) { 1343e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby enforceModifyPermission(); 1344e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList)); 1345e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList); 1346e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail")); 1347e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return success; 1348e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 1349e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 1350e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 1351e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Perform the specified type of NV config reset. 1352e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Used for device configuration by some CDMA operators. 1353e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 1354e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset) 1355e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return true on success; false on any failure 1356e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 1357e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 1358e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public boolean nvResetConfig(int resetType) { 1359e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby enforceModifyPermission(); 1360e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvResetConfig: type " + resetType); 1361e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean) sendRequest(CMD_NV_RESET_CONFIG, resetType); 1362e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvResetConfig: type " + resetType + ' ' + (success ? "ok" : "fail")); 1363e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return success; 1364e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 13657c27be317e8757948178815426d3a329c852b9eeJake Hamby 13667c27be317e8757948178815426d3a329c852b9eeJake Hamby /** 13677c27be317e8757948178815426d3a329c852b9eeJake Hamby * Get the preferred network type. 13687c27be317e8757948178815426d3a329c852b9eeJake Hamby * Used for device configuration by some CDMA operators. 13697c27be317e8757948178815426d3a329c852b9eeJake Hamby * 13707c27be317e8757948178815426d3a329c852b9eeJake Hamby * @return the preferred network type, defined in RILConstants.java. 13717c27be317e8757948178815426d3a329c852b9eeJake Hamby */ 13727c27be317e8757948178815426d3a329c852b9eeJake Hamby @Override 13737c27be317e8757948178815426d3a329c852b9eeJake Hamby public int getPreferredNetworkType() { 13747c27be317e8757948178815426d3a329c852b9eeJake Hamby enforceModifyPermission(); 13757c27be317e8757948178815426d3a329c852b9eeJake Hamby if (DBG) log("getPreferredNetworkType"); 13767c27be317e8757948178815426d3a329c852b9eeJake Hamby int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null); 13777c27be317e8757948178815426d3a329c852b9eeJake Hamby int networkType = (result != null ? result[0] : -1); 13787c27be317e8757948178815426d3a329c852b9eeJake Hamby if (DBG) log("getPreferredNetworkType: " + networkType); 13797c27be317e8757948178815426d3a329c852b9eeJake Hamby return networkType; 13807c27be317e8757948178815426d3a329c852b9eeJake Hamby } 13817c27be317e8757948178815426d3a329c852b9eeJake Hamby 13827c27be317e8757948178815426d3a329c852b9eeJake Hamby /** 13837c27be317e8757948178815426d3a329c852b9eeJake Hamby * Set the preferred network type. 13847c27be317e8757948178815426d3a329c852b9eeJake Hamby * Used for device configuration by some CDMA operators. 13857c27be317e8757948178815426d3a329c852b9eeJake Hamby * 13867c27be317e8757948178815426d3a329c852b9eeJake Hamby * @param networkType the preferred network type, defined in RILConstants.java. 13877c27be317e8757948178815426d3a329c852b9eeJake Hamby * @return true on success; false on any failure. 13887c27be317e8757948178815426d3a329c852b9eeJake Hamby */ 13897c27be317e8757948178815426d3a329c852b9eeJake Hamby @Override 13907c27be317e8757948178815426d3a329c852b9eeJake Hamby public boolean setPreferredNetworkType(int networkType) { 13917c27be317e8757948178815426d3a329c852b9eeJake Hamby enforceModifyPermission(); 13927c27be317e8757948178815426d3a329c852b9eeJake Hamby if (DBG) log("setPreferredNetworkType: type " + networkType); 13937c27be317e8757948178815426d3a329c852b9eeJake Hamby Boolean success = (Boolean) sendRequest(CMD_SET_PREFERRED_NETWORK_TYPE, networkType); 13947c27be317e8757948178815426d3a329c852b9eeJake Hamby if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail")); 13957c27be317e8757948178815426d3a329c852b9eeJake Hamby return success; 13967c27be317e8757948178815426d3a329c852b9eeJake Hamby } 13977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon} 1398