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