PhoneInterfaceManager.java revision 61a60ad2e6944a80944898e636c2e9d9fd7b0e70
17d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon/* 27d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Copyright (C) 2006 The Android Open Source Project 37d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 47d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Licensed under the Apache License, Version 2.0 (the "License"); 57d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * you may not use this file except in compliance with the License. 67d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * You may obtain a copy of the License at 77d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 87d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * http://www.apache.org/licenses/LICENSE-2.0 97d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Unless required by applicable law or agreed to in writing, software 117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * distributed under the License is distributed on an "AS IS" BASIS, 127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * See the License for the specific language governing permissions and 147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * limitations under the License. 157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonpackage com.android.phone; 187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.app.ActivityManager; 207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.app.AppOpsManager; 21bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepalimport android.content.ComponentName; 227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.content.Context; 237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.content.Intent; 2497ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tanimport android.content.SharedPreferences; 2560f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawalimport android.content.pm.PackageManager; 267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.net.Uri; 277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.AsyncResult; 287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Binder; 297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Bundle; 307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Handler; 317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Looper; 327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Message; 337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Process; 347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.ServiceManager; 357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.UserHandle; 36981d85874294656a51683ae6ecc6ba312d3635ceStuart Scottimport android.os.UserManager; 3797ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tanimport android.preference.PreferenceManager; 38f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awadimport android.provider.Settings; 397a1885ba88b4ca833d6dae8b352097636f242917Santos Cordonimport android.telecom.PhoneAccount; 409431b838f89399db2278c0436bd2817322a45f74Andrew Leeimport android.telecom.TelecomManager; 4112f7d80f47bdad9ed1c02b8b916f75e4f11fe873Junda Liuimport android.telephony.CarrierConfigManager; 427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.telephony.CellInfo; 43da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawalimport android.telephony.IccOpenLogicalChannelResponse; 44e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport android.telephony.NeighboringCellInfo; 455d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Savilleimport android.telephony.RadioAccessFamily; 467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.telephony.ServiceState; 470f3b5fcda1b76fbd6042f9a6f81f69d0b44bc3eeWink Savilleimport android.telephony.SubscriptionInfo; 4885190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkeyimport android.telephony.SubscriptionManager; 49f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awadimport android.telephony.TelephonyManager; 507fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadhamimport android.telephony.ModemActivityInfo; 517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.text.TextUtils; 5285190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkeyimport android.util.ArrayMap; 5385190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkeyimport android.util.ArraySet; 547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.util.Log; 55e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport android.util.Pair; 5685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkeyimport android.util.Slog; 577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 58312e8177b25ab359627685d449e0a5fdb539809fAndrew Leeimport com.android.ims.ImsManager; 59566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.CallManager; 60566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.CommandException; 617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.DefaultPhoneNotifier; 627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.ITelephony; 63e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport com.android.internal.telephony.IccCard; 641c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamathimport com.android.internal.telephony.MccTable; 657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.Phone; 6636469e74b7c79ed84148754190c38196eb9a2c49Wink Savilleimport com.android.internal.telephony.PhoneFactory; 675d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Savilleimport com.android.internal.telephony.ProxyController; 687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.PhoneConstants; 69b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganovimport com.android.internal.telephony.RILConstants; 70ac1bdfd36366426513d51bd2c4b107b00533889eWink Savilleimport com.android.internal.telephony.SubscriptionController; 71566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.uicc.IccIoResult; 72566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.uicc.IccUtils; 73eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawalimport com.android.internal.telephony.uicc.UiccCard; 74566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.uicc.UiccController; 75e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport com.android.internal.util.HexDump; 767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7736469e74b7c79ed84148754190c38196eb9a2c49Wink Savilleimport static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY; 7836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport java.util.ArrayList; 8085190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkeyimport java.util.Arrays; 81621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawalimport java.util.HashMap; 82621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawalimport java.util.Iterator; 83e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport java.util.List; 841c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamathimport java.util.Locale; 8585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkeyimport java.util.Map; 8685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkeyimport java.util.Objects; 877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon/** 897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Implementation of the ITelephony interface. 907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 91117fee7467c140dccdc66972f60031dae2d55b35Santos Cordonpublic class PhoneInterfaceManager extends ITelephony.Stub { 927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final String LOG_TAG = "PhoneInterfaceManager"; 937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2); 947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final boolean DBG_LOC = false; 9585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey private static final boolean DBG_MERGE = false; 967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Message codes used with mMainThreadHandler 987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_HANDLE_PIN_MMI = 1; 997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_HANDLE_NEIGHBORING_CELL = 2; 1007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int EVENT_NEIGHBORING_CELL_DONE = 3; 1017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_ANSWER_RINGING_CALL = 4; 1027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_END_CALL = 5; // not used yet 103da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7; 104da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8; 105566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int CMD_OPEN_CHANNEL = 9; 106566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int EVENT_OPEN_CHANNEL_DONE = 10; 107566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int CMD_CLOSE_CHANNEL = 11; 108566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int EVENT_CLOSE_CHANNEL_DONE = 12; 109e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_READ_ITEM = 13; 110e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_READ_ITEM_DONE = 14; 111e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_WRITE_ITEM = 15; 112e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_WRITE_ITEM_DONE = 16; 113e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_WRITE_CDMA_PRL = 17; 114e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18; 115e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_RESET_CONFIG = 19; 116e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_RESET_CONFIG_DONE = 20; 1177c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21; 1187c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22; 1197c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23; 1207c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24; 12135b5945231af96ad0d7ebf4cfcaafeb677d8c75cSailesh Nepal private static final int CMD_SEND_ENVELOPE = 25; 12235b5945231af96ad0d7ebf4cfcaafeb677d8c75cSailesh Nepal private static final int EVENT_SEND_ENVELOPE_DONE = 26; 1236b088eef6c47d96b9b2a0097e3b8ee8b4332f068Derek Tan private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27; 1246b088eef6c47d96b9b2a0097e3b8ee8b4332f068Derek Tan private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28; 1256b088eef6c47d96b9b2a0097e3b8ee8b4332f068Derek Tan private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29; 1266b088eef6c47d96b9b2a0097e3b8ee8b4332f068Derek Tan private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30; 1276b088eef6c47d96b9b2a0097e3b8ee8b4332f068Derek Tan private static final int CMD_EXCHANGE_SIM_IO = 31; 1286b088eef6c47d96b9b2a0097e3b8ee8b4332f068Derek Tan private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32; 12976d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal private static final int CMD_SET_VOICEMAIL_NUMBER = 33; 13076d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34; 13154788801de04c603a856596f4ae4377ab77a9821Stuart Scott private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35; 13254788801de04c603a856596f4ae4377ab77a9821Stuart Scott private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36; 1337fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37; 1347fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38; 1357fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham 1367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The singleton instance. */ 1387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static PhoneInterfaceManager sInstance; 1397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1403ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville private PhoneGlobals mApp; 1413ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville private Phone mPhone; 1423ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville private CallManager mCM; 143981d85874294656a51683ae6ecc6ba312d3635ceStuart Scott private UserManager mUserManager; 1443ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville private AppOpsManager mAppOps; 1453ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville private MainThreadHandler mMainThreadHandler; 146ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville private SubscriptionController mSubscriptionController; 1473ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville private SharedPreferences mTelephonySharedPreferences; 1487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14997ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_"; 15097ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_"; 15185190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_"; 152df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee private static final String PREF_ENABLE_VIDEO_CALLING = "enable_video_calling"; 15389e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan 15489e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan /** 155566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal * A request object to use for transmitting data to an ICC. 156566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal */ 157566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final class IccAPDUArgument { 158566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public int channel, cla, command, p1, p2, p3; 159566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public String data; 160566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 161566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public IccAPDUArgument(int channel, int cla, int command, 162566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal int p1, int p2, int p3, String data) { 163566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.channel = channel; 164566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.cla = cla; 165566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.command = command; 166566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.p1 = p1; 167566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.p2 = p2; 168566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.p3 = p3; 169566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.data = data; 170566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 171566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 172566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 173566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal /** 1747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the 1757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * request after sending. The main thread will notify the request when it is complete. 1767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 1777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final class MainThreadRequest { 1787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The argument to use for the request */ 1797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public Object argument; 1807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The result of the request that is run on the main thread */ 1817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public Object result; 18276d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal /** The subscriber id that this request applies to. Null if default. */ 18376d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal public Integer subId; 1847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public MainThreadRequest(Object argument) { 1867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon this.argument = argument; 1877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 18876d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal 18976d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal public MainThreadRequest(Object argument, Integer subId) { 19076d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal this.argument = argument; 19176d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal this.subId = subId; 19276d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal } 1937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 195cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal private static final class IncomingThirdPartyCallArgs { 196cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public final ComponentName component; 197cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public final String callId; 198cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public final String callerDisplayName; 199cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal 200cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public IncomingThirdPartyCallArgs(ComponentName component, String callId, 201cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal String callerDisplayName) { 202cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal this.component = component; 203cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal this.callId = callId; 204cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal this.callerDisplayName = callerDisplayName; 205cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal } 206cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal } 207cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal 2087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 2097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * A handler that processes messages on the main thread in the phone process. Since many 2107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * of the Phone calls are not thread safe this is needed to shuttle the requests from the 2117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * inbound binder threads to the main thread in the phone process. The Binder thread 2127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting 2137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * on, which will be notified when the operation completes and will contain the result of the 2147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * request. 2157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 2167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * <p>If a MainThreadRequest object is provided in the msg.obj field, 2177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * note that request.result must be set to something non-null for the calling thread to 2187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * unblock. 2197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 2207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private final class MainThreadHandler extends Handler { 2217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 2227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void handleMessage(Message msg) { 2237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon MainThreadRequest request; 2247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message onCompleted; 2257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AsyncResult ar; 22621409250c4001605606a37c3903dc22805410900Shishir Agrawal UiccCard uiccCard = UiccController.getInstance().getUiccCard(mPhone.getPhoneId()); 227da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccAPDUArgument iccArgument; 2287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon switch (msg.what) { 2307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_HANDLE_PIN_MMI: 2317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) msg.obj; 232584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott request.result = getPhoneFromRequest(request).handlePinMmi( 233584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott (String) request.argument); 2347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wake up the requesting thread 2357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 2367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.notifyAll(); 2377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_HANDLE_NEIGHBORING_CELL: 2417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) msg.obj; 2427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onCompleted = obtainMessage(EVENT_NEIGHBORING_CELL_DONE, 2437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request); 2447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.getNeighboringCids(onCompleted); 2457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case EVENT_NEIGHBORING_CELL_DONE: 2487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ar = (AsyncResult) msg.obj; 2497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) ar.userObj; 2507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (ar.exception == null && ar.result != null) { 2517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.result = ar.result; 2527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 2537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // create an empty list to notify the waiting thread 254e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = new ArrayList<NeighboringCellInfo>(0); 2557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wake up the requesting thread 2577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 2587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.notifyAll(); 2597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_ANSWER_RINGING_CALL: 2630887461919173015886ea69ef6c6afbe20ebf1dcWink Saville request = (MainThreadRequest) msg.obj; 264584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott int answer_subId = request.subId; 2650887461919173015886ea69ef6c6afbe20ebf1dcWink Saville answerRingingCallInternal(answer_subId); 2667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_END_CALL: 2697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) msg.obj; 270584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott int end_subId = request.subId; 2710887461919173015886ea69ef6c6afbe20ebf1dcWink Saville final boolean hungUp; 272ae4e36d0e6edc3a912e822e844ab362dd7469491Anthony Lee Phone phone = getPhone(end_subId); 273ae4e36d0e6edc3a912e822e844ab362dd7469491Anthony Lee if (phone == null) { 274ae4e36d0e6edc3a912e822e844ab362dd7469491Anthony Lee if (DBG) log("CMD_END_CALL: no phone for id: " + end_subId); 275ae4e36d0e6edc3a912e822e844ab362dd7469491Anthony Lee break; 276ae4e36d0e6edc3a912e822e844ab362dd7469491Anthony Lee } 277ae4e36d0e6edc3a912e822e844ab362dd7469491Anthony Lee int phoneType = phone.getPhoneType(); 2787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { 2797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // CDMA: If the user presses the Power button we treat it as 2807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ending the complete call session 2810887461919173015886ea69ef6c6afbe20ebf1dcWink Saville hungUp = PhoneUtils.hangupRingingAndActive(getPhone(end_subId)); 2827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) { 2837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // GSM: End the call as per the Phone state 2847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon hungUp = PhoneUtils.hangup(mCM); 2857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 2867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon throw new IllegalStateException("Unexpected phone type: " + phoneType); 2877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("CMD_END_CALL: " + (hungUp ? "hung up!" : "no call to hang up")); 2897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.result = hungUp; 2907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wake up the requesting thread 2917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 2927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.notifyAll(); 2937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 296da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL: 297566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) msg.obj; 298da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument = (IccAPDUArgument) request.argument; 299eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (uiccCard == null) { 300eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("iccTransmitApduLogicalChannel: No UICC"); 301eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 302eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal synchronized (request) { 303eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.notifyAll(); 304eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 305eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } else { 306da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE, 307da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request); 308eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal uiccCard.iccTransmitApduLogicalChannel( 309da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument.channel, iccArgument.cla, iccArgument.command, 310da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data, 311566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal onCompleted); 312eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 313566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 314566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 315da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE: 316566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal ar = (AsyncResult) msg.obj; 317566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) ar.userObj; 318566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.exception == null && ar.result != null) { 319566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.result = ar.result; 320566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 321566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 322566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.result == null) { 323566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccTransmitApduLogicalChannel: Empty response"); 324e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else if (ar.exception instanceof CommandException) { 325566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccTransmitApduLogicalChannel: CommandException: " + 326e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby ar.exception); 327566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 328566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccTransmitApduLogicalChannel: Unknown exception"); 329566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 330566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 331566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal synchronized (request) { 332566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.notifyAll(); 333566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 334566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 335566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 336da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal case CMD_TRANSMIT_APDU_BASIC_CHANNEL: 337da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request = (MainThreadRequest) msg.obj; 338da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument = (IccAPDUArgument) request.argument; 339da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (uiccCard == null) { 340da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal loge("iccTransmitApduBasicChannel: No UICC"); 341da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 342da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal synchronized (request) { 343da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.notifyAll(); 344da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 345da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else { 346da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE, 347da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request); 348da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal uiccCard.iccTransmitApduBasicChannel( 349da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2, 350da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument.p3, iccArgument.data, onCompleted); 351da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 352da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal break; 353da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 354da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE: 355da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal ar = (AsyncResult) msg.obj; 356da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request = (MainThreadRequest) ar.userObj; 357da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (ar.exception == null && ar.result != null) { 358da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.result = ar.result; 359da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else { 360da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 361da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (ar.result == null) { 362da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal loge("iccTransmitApduBasicChannel: Empty response"); 363da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else if (ar.exception instanceof CommandException) { 364da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal loge("iccTransmitApduBasicChannel: CommandException: " + 365da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal ar.exception); 366da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else { 367da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal loge("iccTransmitApduBasicChannel: Unknown exception"); 368da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 369da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 370da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal synchronized (request) { 371da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.notifyAll(); 372da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 373da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal break; 374da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 375da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal case CMD_EXCHANGE_SIM_IO: 376da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request = (MainThreadRequest) msg.obj; 377da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument = (IccAPDUArgument) request.argument; 378da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (uiccCard == null) { 379da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal loge("iccExchangeSimIO: No UICC"); 380da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 381da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal synchronized (request) { 382da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.notifyAll(); 383da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 384da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else { 385da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE, 386da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request); 387da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */ 388da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3, 389da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument.data, onCompleted); 390da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 391da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal break; 392da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 393da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal case EVENT_EXCHANGE_SIM_IO_DONE: 394da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal ar = (AsyncResult) msg.obj; 395da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request = (MainThreadRequest) ar.userObj; 396da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (ar.exception == null && ar.result != null) { 397da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.result = ar.result; 398da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else { 399da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.result = new IccIoResult(0x6f, 0, (byte[])null); 400da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 401da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal synchronized (request) { 402da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.notifyAll(); 403da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 404da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal break; 405da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 4064d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan case CMD_SEND_ENVELOPE: 4074d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan request = (MainThreadRequest) msg.obj; 408eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (uiccCard == null) { 409eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("sendEnvelopeWithStatus: No UICC"); 410eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 411eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal synchronized (request) { 412eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.notifyAll(); 413eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 414eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } else { 415eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request); 416eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted); 417eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 4184d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan break; 4194d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan 4204d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan case EVENT_SEND_ENVELOPE_DONE: 4214d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan ar = (AsyncResult) msg.obj; 4224d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan request = (MainThreadRequest) ar.userObj; 4239f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal if (ar.exception == null && ar.result != null) { 4249f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal request.result = ar.result; 4254d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan } else { 4269f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 4279f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal if (ar.result == null) { 4289f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal loge("sendEnvelopeWithStatus: Empty response"); 4299f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal } else if (ar.exception instanceof CommandException) { 4309f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal loge("sendEnvelopeWithStatus: CommandException: " + 4319f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal ar.exception); 4329f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal } else { 4339f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal loge("sendEnvelopeWithStatus: exception:" + ar.exception); 4349f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal } 4354d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan } 4364d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan synchronized (request) { 4374d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan request.notifyAll(); 4384d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan } 4394d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan break; 4404d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan 441566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case CMD_OPEN_CHANNEL: 442566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) msg.obj; 443eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (uiccCard == null) { 444eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("iccOpenLogicalChannel: No UICC"); 445eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 446eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal synchronized (request) { 447eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.notifyAll(); 448eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 449eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } else { 450eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request); 451eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal uiccCard.iccOpenLogicalChannel((String)request.argument, onCompleted); 452eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 453566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 454566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 455566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case EVENT_OPEN_CHANNEL_DONE: 456566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal ar = (AsyncResult) msg.obj; 457566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) ar.userObj; 458da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccOpenLogicalChannelResponse openChannelResp; 459566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.exception == null && ar.result != null) { 460da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal int[] result = (int[]) ar.result; 461da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal int channelId = result[0]; 462da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal byte[] selectResponse = null; 463da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (result.length > 1) { 464da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal selectResponse = new byte[result.length - 1]; 465da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal for (int i = 1; i < result.length; ++i) { 466da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal selectResponse[i - 1] = (byte) result[i]; 467da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 468da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 469da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal openChannelResp = new IccOpenLogicalChannelResponse(channelId, 470527e8bf2bd43c5bfdb2ac7ea8cf05413c1faaeb5Shishir Agrawal IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse); 471566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 472566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.result == null) { 473566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccOpenLogicalChannel: Empty response"); 474566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 475da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (ar.exception != null) { 476da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal loge("iccOpenLogicalChannel: Exception: " + ar.exception); 477da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 478da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 479527e8bf2bd43c5bfdb2ac7ea8cf05413c1faaeb5Shishir Agrawal int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR; 480a754ba14f729744f3261113d5e355b86d5c846d3Junda Liu if (ar.exception instanceof CommandException) { 481a754ba14f729744f3261113d5e355b86d5c846d3Junda Liu CommandException.Error error = 482a754ba14f729744f3261113d5e355b86d5c846d3Junda Liu ((CommandException) (ar.exception)).getCommandError(); 483a754ba14f729744f3261113d5e355b86d5c846d3Junda Liu if (error == CommandException.Error.MISSING_RESOURCE) { 484527e8bf2bd43c5bfdb2ac7ea8cf05413c1faaeb5Shishir Agrawal errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE; 485a754ba14f729744f3261113d5e355b86d5c846d3Junda Liu } else if (error == CommandException.Error.NO_SUCH_ELEMENT) { 486527e8bf2bd43c5bfdb2ac7ea8cf05413c1faaeb5Shishir Agrawal errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT; 487da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 488da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 489da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal openChannelResp = new IccOpenLogicalChannelResponse( 490da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null); 491566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 49282c8a46052629d1450320c116d14c7353bfe4ea1Shishir Agrawal request.result = openChannelResp; 493566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal synchronized (request) { 494566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.notifyAll(); 495566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 496566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 497566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 498566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case CMD_CLOSE_CHANNEL: 499566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) msg.obj; 500eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (uiccCard == null) { 501eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("iccCloseLogicalChannel: No UICC"); 502eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 503eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal synchronized (request) { 504eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.notifyAll(); 505eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 506eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } else { 507eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request); 508eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted); 509eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 510566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 511566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 512566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case EVENT_CLOSE_CHANNEL_DONE: 513e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "iccCloseLogicalChannel"); 514e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 515e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 516e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_READ_ITEM: 517e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 518e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request); 519e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvReadItem((Integer) request.argument, onCompleted); 520e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 521e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 522e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_READ_ITEM_DONE: 523566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal ar = (AsyncResult) msg.obj; 524566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) ar.userObj; 525e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.exception == null && ar.result != null) { 526e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = ar.result; // String 527566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 528e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = ""; 529e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.result == null) { 530e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge("nvReadItem: Empty response"); 531e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else if (ar.exception instanceof CommandException) { 532e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge("nvReadItem: CommandException: " + 533e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby ar.exception); 534566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 535e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge("nvReadItem: Unknown exception"); 536566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 537566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 538566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal synchronized (request) { 539566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.notifyAll(); 540566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 541566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 542566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 543e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_WRITE_ITEM: 544e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 545e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request); 546e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument; 547e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvWriteItem(idValue.first, idValue.second, onCompleted); 548e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 549e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 550e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_WRITE_ITEM_DONE: 551e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "nvWriteItem"); 552e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 553e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 554e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_WRITE_CDMA_PRL: 555e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 556e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request); 557e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted); 558e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 559e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 560e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_WRITE_CDMA_PRL_DONE: 561e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "nvWriteCdmaPrl"); 562e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 563e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 564e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_RESET_CONFIG: 565e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 566e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_RESET_CONFIG_DONE, request); 567e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvResetConfig((Integer) request.argument, onCompleted); 568e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 569e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 570e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_RESET_CONFIG_DONE: 571e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "nvResetConfig"); 572e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 573e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 5747c27be317e8757948178815426d3a329c852b9eeJake Hamby case CMD_GET_PREFERRED_NETWORK_TYPE: 5757c27be317e8757948178815426d3a329c852b9eeJake Hamby request = (MainThreadRequest) msg.obj; 5767c27be317e8757948178815426d3a329c852b9eeJake Hamby onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request); 57754788801de04c603a856596f4ae4377ab77a9821Stuart Scott getPhoneFromRequest(request).getPreferredNetworkType(onCompleted); 5787c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 5797c27be317e8757948178815426d3a329c852b9eeJake Hamby 5807c27be317e8757948178815426d3a329c852b9eeJake Hamby case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE: 5817c27be317e8757948178815426d3a329c852b9eeJake Hamby ar = (AsyncResult) msg.obj; 5827c27be317e8757948178815426d3a329c852b9eeJake Hamby request = (MainThreadRequest) ar.userObj; 5837c27be317e8757948178815426d3a329c852b9eeJake Hamby if (ar.exception == null && ar.result != null) { 5847c27be317e8757948178815426d3a329c852b9eeJake Hamby request.result = ar.result; // Integer 5857c27be317e8757948178815426d3a329c852b9eeJake Hamby } else { 5867c27be317e8757948178815426d3a329c852b9eeJake Hamby request.result = -1; 5877c27be317e8757948178815426d3a329c852b9eeJake Hamby if (ar.result == null) { 5887c27be317e8757948178815426d3a329c852b9eeJake Hamby loge("getPreferredNetworkType: Empty response"); 5897c27be317e8757948178815426d3a329c852b9eeJake Hamby } else if (ar.exception instanceof CommandException) { 5907c27be317e8757948178815426d3a329c852b9eeJake Hamby loge("getPreferredNetworkType: CommandException: " + 5917c27be317e8757948178815426d3a329c852b9eeJake Hamby ar.exception); 5927c27be317e8757948178815426d3a329c852b9eeJake Hamby } else { 5937c27be317e8757948178815426d3a329c852b9eeJake Hamby loge("getPreferredNetworkType: Unknown exception"); 5947c27be317e8757948178815426d3a329c852b9eeJake Hamby } 5957c27be317e8757948178815426d3a329c852b9eeJake Hamby } 5967c27be317e8757948178815426d3a329c852b9eeJake Hamby synchronized (request) { 5977c27be317e8757948178815426d3a329c852b9eeJake Hamby request.notifyAll(); 5987c27be317e8757948178815426d3a329c852b9eeJake Hamby } 5997c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 6007c27be317e8757948178815426d3a329c852b9eeJake Hamby 6017c27be317e8757948178815426d3a329c852b9eeJake Hamby case CMD_SET_PREFERRED_NETWORK_TYPE: 6027c27be317e8757948178815426d3a329c852b9eeJake Hamby request = (MainThreadRequest) msg.obj; 6037c27be317e8757948178815426d3a329c852b9eeJake Hamby onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request); 6047c27be317e8757948178815426d3a329c852b9eeJake Hamby int networkType = (Integer) request.argument; 60554788801de04c603a856596f4ae4377ab77a9821Stuart Scott getPhoneFromRequest(request).setPreferredNetworkType(networkType, onCompleted); 6067c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 6077c27be317e8757948178815426d3a329c852b9eeJake Hamby 6087c27be317e8757948178815426d3a329c852b9eeJake Hamby case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE: 6097c27be317e8757948178815426d3a329c852b9eeJake Hamby handleNullReturnEvent(msg, "setPreferredNetworkType"); 6107c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 6117c27be317e8757948178815426d3a329c852b9eeJake Hamby 6124bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu case CMD_INVOKE_OEM_RIL_REQUEST_RAW: 6134bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu request = (MainThreadRequest)msg.obj; 6144bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request); 6154bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu mPhone.invokeOemRilRequestRaw((byte[])request.argument, onCompleted); 6164bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu break; 6174bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu 6184bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE: 6194bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu ar = (AsyncResult)msg.obj; 6204bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu request = (MainThreadRequest)ar.userObj; 6214bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu request.result = ar; 6224bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu synchronized (request) { 6234bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu request.notifyAll(); 6244bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } 6254bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu break; 6264bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu 62776d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal case CMD_SET_VOICEMAIL_NUMBER: 62876d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal request = (MainThreadRequest) msg.obj; 62976d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request); 63076d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal Pair<String, String> tagNum = (Pair<String, String>) request.argument; 631584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second, 632584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott onCompleted); 63376d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal break; 63476d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal 63576d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal case EVENT_SET_VOICEMAIL_NUMBER_DONE: 63676d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal handleNullReturnEvent(msg, "setVoicemailNumber"); 63776d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal break; 63876d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal 63954788801de04c603a856596f4ae4377ab77a9821Stuart Scott case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC: 64054788801de04c603a856596f4ae4377ab77a9821Stuart Scott request = (MainThreadRequest) msg.obj; 64154788801de04c603a856596f4ae4377ab77a9821Stuart Scott onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE, 64254788801de04c603a856596f4ae4377ab77a9821Stuart Scott request); 64354788801de04c603a856596f4ae4377ab77a9821Stuart Scott getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted); 64454788801de04c603a856596f4ae4377ab77a9821Stuart Scott break; 64554788801de04c603a856596f4ae4377ab77a9821Stuart Scott 64654788801de04c603a856596f4ae4377ab77a9821Stuart Scott case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE: 64754788801de04c603a856596f4ae4377ab77a9821Stuart Scott handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic"); 64854788801de04c603a856596f4ae4377ab77a9821Stuart Scott break; 64954788801de04c603a856596f4ae4377ab77a9821Stuart Scott 6507fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham case CMD_GET_MODEM_ACTIVITY_INFO: 6517fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham request = (MainThreadRequest) msg.obj; 6527fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request); 65361a60ad2e6944a80944898e636c2e9d9fd7b0e70Prerepa Viswanadham mPhone.getModemActivityInfo(onCompleted); 6547fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham break; 6557fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham 6567fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham case EVENT_GET_MODEM_ACTIVITY_INFO_DONE: 6577fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham ar = (AsyncResult) msg.obj; 6587fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham request = (MainThreadRequest) ar.userObj; 6597fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham if (ar.exception == null && ar.result != null) { 6607fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham request.result = ar.result; 6617fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham } else { 6627fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham if (ar.result == null) { 6637fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham loge("queryModemActivityInfo: Empty response"); 6647fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham } else if (ar.exception instanceof CommandException) { 6657fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham loge("queryModemActivityInfo: CommandException: " + 6667fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham ar.exception); 6677fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham } else { 6687fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham loge("queryModemActivityInfo: Unknown exception"); 6697fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham } 6707fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham } 6717fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham synchronized (request) { 6727fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham request.notifyAll(); 6737fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham } 6747fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham break; 6757fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham 6767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon default: 6777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what); 6787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 6797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 681e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 682e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private void handleNullReturnEvent(Message msg, String command) { 683e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby AsyncResult ar = (AsyncResult) msg.obj; 684e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby MainThreadRequest request = (MainThreadRequest) ar.userObj; 685e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.exception == null) { 686e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = true; 687e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else { 688e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = false; 689e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.exception instanceof CommandException) { 690e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge(command + ": CommandException: " + ar.exception); 691e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else { 692e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge(command + ": Unknown exception"); 693e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 694e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 695e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby synchronized (request) { 696e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.notifyAll(); 697e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 698e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 6997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 7027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Posts the specified command to be executed on the main thread, 7037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * waits for the request to complete, and returns the result. 7047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #sendRequestAsync 7057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 7067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Object sendRequest(int command, Object argument) { 707500b0e04406d2995c1f29dea95c98cedaa669f74Santos Cordon return sendRequest(command, argument, null); 70836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 70936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 71036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 71136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Posts the specified command to be executed on the main thread, 71236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * waits for the request to complete, and returns the result. 71336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * @see #sendRequestAsync 71436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 71576d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal private Object sendRequest(int command, Object argument, Integer subId) { 7167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (Looper.myLooper() == mMainThreadHandler.getLooper()) { 7177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon throw new RuntimeException("This method will deadlock if called from the main thread."); 7187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 72076d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal MainThreadRequest request = new MainThreadRequest(argument, subId); 7217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message msg = mMainThreadHandler.obtainMessage(command, request); 7227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon msg.sendToTarget(); 7237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wait for the request to complete 7257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 7267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon while (request.result == null) { 7277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 7287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.wait(); 7297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 7307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Do nothing, go back and wait until the request is complete 7317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return request.result; 7357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 7387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Asynchronous ("fire and forget") version of sendRequest(): 7397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Posts the specified command to be executed on the main thread, and 7407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * returns immediately. 7417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #sendRequest 7427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 7437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void sendRequestAsync(int command) { 7447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mMainThreadHandler.sendEmptyMessage(command); 7457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 748bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal * Same as {@link #sendRequestAsync(int)} except it takes an argument. 749bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal * @see {@link #sendRequest(int,Object)} 750bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal */ 751bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal private void sendRequestAsync(int command, Object argument) { 752bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal MainThreadRequest request = new MainThreadRequest(argument); 753bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal Message msg = mMainThreadHandler.obtainMessage(command, request); 754bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal msg.sendToTarget(); 755bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal } 756bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal 757bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal /** 7587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Initialize the singleton PhoneInterfaceManager instance. 7597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This is only done once, at startup, from PhoneApp.onCreate(). 7607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 761194161ed3aef6bdeeecd6153403269bbd01314a5Sailesh Nepal /* package */ static PhoneInterfaceManager init(PhoneGlobals app, Phone phone) { 7627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (PhoneInterfaceManager.class) { 7637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (sInstance == null) { 764194161ed3aef6bdeeecd6153403269bbd01314a5Sailesh Nepal sInstance = new PhoneInterfaceManager(app, phone); 7657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 7667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance); 7677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return sInstance; 7697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** Private constructor; @see init() */ 773194161ed3aef6bdeeecd6153403269bbd01314a5Sailesh Nepal private PhoneInterfaceManager(PhoneGlobals app, Phone phone) { 7747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp = app; 7757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone = phone; 7767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCM = PhoneGlobals.getInstance().mCM; 777981d85874294656a51683ae6ecc6ba312d3635ceStuart Scott mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE); 7787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE); 7797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mMainThreadHandler = new MainThreadHandler(); 780df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee mTelephonySharedPreferences = 78197ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan PreferenceManager.getDefaultSharedPreferences(mPhone.getContext()); 782ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville mSubscriptionController = SubscriptionController.getInstance(); 7833ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville 7847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon publish(); 7857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void publish() { 7887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("publish: " + this); 7897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ServiceManager.addService("phone", this); 7917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 793584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott private Phone getPhoneFromRequest(MainThreadRequest request) { 794584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott return (request.subId == null) ? mPhone : getPhone(request.subId); 795584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott } 796584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott 79736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // returns phone associated with the subId. 798b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville private Phone getPhone(int subId) { 799ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId)); 80036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 8017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 8027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Implementation of the ITelephony interface. 8037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 8047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void dial(String number) { 806add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville dialForSubscriber(getPreferredVoiceSubscription(), number); 80736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 80836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 809b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public void dialForSubscriber(int subId, String number) { 8107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("dial: " + number); 8117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No permission check needed here: This is just a wrapper around the 8127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ACTION_DIAL intent, which is available to any app since it puts up 8137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the UI before it does anything. 8147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon String url = createTelUrl(number); 8167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (url == null) { 8177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 8187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // PENDING: should we just silently fail if phone is offhook or ringing? 82136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville PhoneConstants.State state = mCM.getState(subId); 8227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) { 8237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url)); 8247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.startActivity(intent); 8267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void call(String callingPackage, String number) { 830add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number); 83136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 83236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 833b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public void callForSubscriber(int subId, String callingPackage, String number) { 8347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("call: " + number); 8357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // This is just a wrapper around the ACTION_CALL intent, but we still 8377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // need to do a permission check since we're calling startActivity() 8387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // from the context of the phone app. 8397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceCallPermission(); 8407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mAppOps.noteOp(AppOpsManager.OP_CALL_PHONE, Binder.getCallingUid(), callingPackage) 8427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon != AppOpsManager.MODE_ALLOWED) { 8437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 8447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon String url = createTelUrl(number); 8477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (url == null) { 8487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 8497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8510887461919173015886ea69ef6c6afbe20ebf1dcWink Saville boolean isValid = false; 8521c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath final List<SubscriptionInfo> slist = getActiveSubscriptionInfoList(); 8533ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville if (slist != null) { 8543ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville for (SubscriptionInfo subInfoRecord : slist) { 8553ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville if (subInfoRecord.getSubscriptionId() == subId) { 8563ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville isValid = true; 8573ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville break; 8583ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville } 8590887461919173015886ea69ef6c6afbe20ebf1dcWink Saville } 8600887461919173015886ea69ef6c6afbe20ebf1dcWink Saville } 8610887461919173015886ea69ef6c6afbe20ebf1dcWink Saville if (isValid == false) { 8620887461919173015886ea69ef6c6afbe20ebf1dcWink Saville return; 8630887461919173015886ea69ef6c6afbe20ebf1dcWink Saville } 8640887461919173015886ea69ef6c6afbe20ebf1dcWink Saville 8657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url)); 86636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville intent.putExtra(SUBSCRIPTION_KEY, subId); 8677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.startActivity(intent); 8697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 8727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * End a call based on call state 8737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return true is a call was ended 8747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 8757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean endCall() { 876add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return endCallForSubscriber(getDefaultSubscription()); 87736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 87836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 87936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 88036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * End a call based on the call state of the subId 88136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * @return true is a call was ended 88236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 883b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public boolean endCallForSubscriber(int subId) { 8847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceCallPermission(); 885584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott return (Boolean) sendRequest(CMD_END_CALL, null, new Integer(subId)); 8867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void answerRingingCall() { 889add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville answerRingingCallForSubscriber(getDefaultSubscription()); 89036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 89136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 892b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public void answerRingingCallForSubscriber(int subId) { 8937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("answerRingingCall..."); 8947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: there should eventually be a separate "ANSWER_PHONE" permission, 8957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // but that can probably wait till the big TelephonyManager API overhaul. 8967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For now, protect this call with the MODIFY_PHONE_STATE permission. 8977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 898584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott sendRequest(CMD_ANSWER_RINGING_CALL, null, new Integer(subId)); 8997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 9027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make the actual telephony calls to implement answerRingingCall(). 9037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This should only be called from the main thread of the Phone app. 9047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #answerRingingCall 9057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 9067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * TODO: it would be nice to return true if we answered the call, or 9077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * false if there wasn't actually a ringing incoming call, or some 9087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * other error occurred. (In other words, pass back the return value 9097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * from PhoneUtils.answerCall() or PhoneUtils.answerAndEndActive().) 9107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * But that would require calling this method via sendRequest() rather 9117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * than sendRequestAsync(), and right now we don't actually *need* that 9127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * return value, so let's just return void for now. 9137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 914b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville private void answerRingingCallInternal(int subId) { 9150887461919173015886ea69ef6c6afbe20ebf1dcWink Saville final boolean hasRingingCall = !getPhone(subId).getRingingCall().isIdle(); 9167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (hasRingingCall) { 9170887461919173015886ea69ef6c6afbe20ebf1dcWink Saville final boolean hasActiveCall = !getPhone(subId).getForegroundCall().isIdle(); 9180887461919173015886ea69ef6c6afbe20ebf1dcWink Saville final boolean hasHoldingCall = !getPhone(subId).getBackgroundCall().isIdle(); 9197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (hasActiveCall && hasHoldingCall) { 9207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Both lines are in use! 9217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: provide a flag to let the caller specify what 9227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // policy to use if both lines are in use. (The current 9237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // behavior is hardwired to "answer incoming, end ongoing", 9247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // which is how the CALL button is specced to behave.) 9257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.answerAndEndActive(mCM, mCM.getFirstActiveRingingCall()); 9267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 9277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 9287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // answerCall() will automatically hold the current active 9297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // call, if there is one. 9307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.answerCall(mCM.getFirstActiveRingingCall()); 9317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 9327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 9347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No call was ringing. 9357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 9367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 9405422a8deb513e4466ec6cc1e640895a6b536fee0Santos Cordon * This method is no longer used and can be removed once TelephonyManager stops referring to it. 9417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 9425422a8deb513e4466ec6cc1e640895a6b536fee0Santos Cordon public void silenceRinger() { 9435422a8deb513e4466ec6cc1e640895a6b536fee0Santos Cordon Log.e(LOG_TAG, "silenseRinger not supported"); 9447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isOffhook() { 947add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return isOffhookForSubscriber(getDefaultSubscription()); 94836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 94936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 950b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public boolean isOffhookForSubscriber(int subId) { 95136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return (getPhone(subId).getState() == PhoneConstants.State.OFFHOOK); 9527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isRinging() { 955add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return (isRingingForSubscriber(getDefaultSubscription())); 95636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 95736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 958b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public boolean isRingingForSubscriber(int subId) { 95936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return (getPhone(subId).getState() == PhoneConstants.State.RINGING); 9607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isIdle() { 963add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return isIdleForSubscriber(getDefaultSubscription()); 96436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 96536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 966b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public boolean isIdleForSubscriber(int subId) { 96736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return (getPhone(subId).getState() == PhoneConstants.State.IDLE); 9687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 970b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov public boolean isSimPinEnabled(String callingPackage) { 971b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov if (!canReadPhoneState(callingPackage, "isSimPinEnabled")) { 972b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov return false; 973b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov } 974b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov 9757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return (PhoneGlobals.getInstance().isSimPinEnabled()); 9767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean supplyPin(String pin) { 979add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return supplyPinForSubscriber(getDefaultSubscription(), pin); 98036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 98136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 982b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public boolean supplyPinForSubscriber(int subId, String pin) { 983add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville int [] resultArray = supplyPinReportResultForSubscriber(subId, pin); 9849de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false; 9859de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 9869de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville 9879de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville public boolean supplyPuk(String puk, String pin) { 988add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return supplyPukForSubscriber(getDefaultSubscription(), puk, pin); 98936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 99036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 991b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public boolean supplyPukForSubscriber(int subId, String puk, String pin) { 992add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin); 9939de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false; 9949de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 9959de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville 9969de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville /** {@hide} */ 9979de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville public int[] supplyPinReportResult(String pin) { 998add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return supplyPinReportResultForSubscriber(getDefaultSubscription(), pin); 99936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 100036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1001b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public int[] supplyPinReportResultForSubscriber(int subId, String pin) { 10027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 100336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard()); 10047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon checkSimPin.start(); 10057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return checkSimPin.unlockSim(null, pin); 10067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10089de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville /** {@hide} */ 10099de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville public int[] supplyPukReportResult(String puk, String pin) { 1010add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return supplyPukReportResultForSubscriber(getDefaultSubscription(), puk, pin); 101136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 101236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1013b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) { 10147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 101536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard()); 10167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon checkSimPuk.start(); 10177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return checkSimPuk.unlockSim(puk, pin); 10187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 10219de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville * Helper thread to turn async call to SimCard#supplyPin into 10227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * a synchronous one. 10237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 10247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static class UnlockSim extends Thread { 10257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private final IccCard mSimCard; 10277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private boolean mDone = false; 10299de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville private int mResult = PhoneConstants.PIN_GENERAL_FAILURE; 10309de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville private int mRetryCount = -1; 10317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For replies from SimCard interface 10337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Handler mHandler; 10347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For async handler to identify request type 10367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int SUPPLY_PIN_COMPLETE = 100; 10377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public UnlockSim(IccCard simCard) { 10397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSimCard = simCard; 10407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 10437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void run() { 10447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Looper.prepare(); 10457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (UnlockSim.this) { 10467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mHandler = new Handler() { 10477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 10487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void handleMessage(Message msg) { 10497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AsyncResult ar = (AsyncResult) msg.obj; 10507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon switch (msg.what) { 10517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case SUPPLY_PIN_COMPLETE: 10527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE"); 10537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (UnlockSim.this) { 10549de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mRetryCount = msg.arg1; 10559de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville if (ar.exception != null) { 10569de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville if (ar.exception instanceof CommandException && 10579de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville ((CommandException)(ar.exception)).getCommandError() 10589de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville == CommandException.Error.PASSWORD_INCORRECT) { 10599de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mResult = PhoneConstants.PIN_PASSWORD_INCORRECT; 10609de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } else { 10619de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mResult = PhoneConstants.PIN_GENERAL_FAILURE; 10629de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 10639de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } else { 10649de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mResult = PhoneConstants.PIN_RESULT_SUCCESS; 10659de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 10667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mDone = true; 10677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon UnlockSim.this.notifyAll(); 10687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 10707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon }; 10737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon UnlockSim.this.notifyAll(); 10747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Looper.loop(); 10767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* 10797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Use PIN or PUK to unlock SIM card 10807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 10817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * If PUK is null, unlock SIM card with PIN 10827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 10837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * If PUK is not null, unlock SIM card with PUK and set PIN code 10847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 10859de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville synchronized int[] unlockSim(String puk, String pin) { 10867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon while (mHandler == null) { 10887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 10897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon wait(); 10907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 10917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Thread.currentThread().interrupt(); 10927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE); 10957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (puk == null) { 10977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSimCard.supplyPin(pin, callback); 10987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 10997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSimCard.supplyPuk(puk, pin, callback); 11007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon while (!mDone) { 11037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 11047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "wait for done"); 11057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon wait(); 11067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 11077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Restore the interrupted status 11087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Thread.currentThread().interrupt(); 11097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "done"); 11129de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville int[] resultArray = new int[2]; 11139de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville resultArray[0] = mResult; 11149de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville resultArray[1] = mRetryCount; 11159de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville return resultArray; 11167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void updateServiceLocation() { 1120add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville updateServiceLocationForSubscriber(getDefaultSubscription()); 112136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 112236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 112336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1124b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public void updateServiceLocationForSubscriber(int subId) { 11257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No permission check needed here: this call is harmless, and it's 11267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // needed for the ServiceState.requestStateUpdate() call (which is 11277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // already intentionally exposed to 3rd parties.) 112836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).updateServiceLocation(); 11297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isRadioOn() { 1132add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return isRadioOnForSubscriber(getDefaultSubscription()); 113336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 113436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1135b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public boolean isRadioOnForSubscriber(int subId) { 113636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getServiceState().getState() != ServiceState.STATE_POWER_OFF; 11377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void toggleRadioOnOff() { 1140add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville toggleRadioOnOffForSubscriber(getDefaultSubscription()); 114136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 114236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 114336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1144b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public void toggleRadioOnOffForSubscriber(int subId) { 11457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 1146add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville getPhone(subId).setRadioPower(!isRadioOnForSubscriber(subId)); 11477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 114836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 11497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean setRadio(boolean turnOn) { 1150add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return setRadioForSubscriber(getDefaultSubscription(), turnOn); 115136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 115236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1153b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public boolean setRadioForSubscriber(int subId, boolean turnOn) { 11547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 115536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville if ((getPhone(subId).getServiceState().getState() != 115636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville ServiceState.STATE_POWER_OFF) != turnOn) { 1157add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville toggleRadioOnOffForSubscriber(subId); 11587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 11607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 116136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 11621fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla public boolean needMobileRadioShutdown() { 11631fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla /* 11641fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla * If any of the Radios are available, it will need to be 11651fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla * shutdown. So return true if any Radio is available. 11661fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla */ 11671fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { 11681fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla Phone phone = PhoneFactory.getPhone(i); 11691fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla if (phone != null && phone.isRadioAvailable()) return true; 11701fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 11711fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown."); 11721fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla return false; 11731fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 11741fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla 11751fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla public void shutdownMobileRadios() { 11761fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { 11771fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla logv("Shutting down Phone " + i); 11781fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla shutdownRadioUsingPhoneId(i); 11791fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 11801fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 11811fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla 11821fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla private void shutdownRadioUsingPhoneId(int phoneId) { 11831fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla enforceModifyPermission(); 11841fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla Phone phone = PhoneFactory.getPhone(phoneId); 11851fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla if (phone != null && phone.isRadioAvailable()) { 11861fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla phone.shutdownRadio(); 11871fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 11881fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 11891fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla 11907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean setRadioPower(boolean turnOn) { 1191add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return setRadioPowerForSubscriber(getDefaultSubscription(), turnOn); 119236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 119336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1194b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) { 11957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 119636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).setRadioPower(turnOn); 11977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 11987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 120036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // FIXME: subId version needed 12017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean enableDataConnectivity() { 12027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 1203ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville int subId = mSubscriptionController.getDefaultDataSubId(); 120436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).setDataEnabled(true); 12057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 12067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 120836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // FIXME: subId version needed 12097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean disableDataConnectivity() { 12107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 1211ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville int subId = mSubscriptionController.getDefaultDataSubId(); 121236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).setDataEnabled(false); 12137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 12147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 121636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // FIXME: subId version needed 12177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isDataConnectivityPossible() { 1218ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville int subId = mSubscriptionController.getDefaultDataSubId(); 121936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).isDataConnectivityPossible(); 12207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean handlePinMmi(String dialString) { 1223add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return handlePinMmiForSubscriber(getDefaultSubscription(), dialString); 122436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 122536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1226b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public boolean handlePinMmiForSubscriber(int subId, String dialString) { 12277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 122836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId); 12297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getCallState() { 1232add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return getCallStateForSubscriber(getDefaultSubscription()); 123336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 123436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1235b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public int getCallStateForSubscriber(int subId) { 123636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return DefaultPhoneNotifier.convertCallState(getPhone(subId).getState()); 12377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getDataState() { 1240ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId()); 124136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return DefaultPhoneNotifier.convertDataState(phone.getDataConnectionState()); 12427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getDataActivity() { 1245ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId()); 124636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState()); 12477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 125064fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav public Bundle getCellLocation(String callingPackage) { 125164fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav enforceFineOrCoarseLocationPermission("getCellLocation"); 125264fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav 125364fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav // OP_COARSE_LOCATION controls both fine and coarse location. 125464fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav if (mAppOps.noteOp(AppOpsManager.OP_COARSE_LOCATION, Binder.getCallingUid(), 125564fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav callingPackage) != AppOpsManager.MODE_ALLOWED) { 12569acc70dcc5bab8df02211ad37a71a1a79c8d54e3Amit Mahajan log("getCellLocation: returning null; mode != allowed"); 125764fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav return null; 12587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1260e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (checkIfCallerIsSelfOrForegroundUser()) { 12617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getCellLocation: is active user"); 12627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Bundle data = new Bundle(); 12632c01cdffe4cb2bbc480f7080ef14e21f88833007Legler Wu Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId()); 12642c01cdffe4cb2bbc480f7080ef14e21f88833007Legler Wu phone.getCellLocation().fillInNotifierBundle(data); 12657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return data; 12667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 12679acc70dcc5bab8df02211ad37a71a1a79c8d54e3Amit Mahajan log("getCellLocation: suppress non-active user"); 12687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 12697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 127264fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav private void enforceFineOrCoarseLocationPermission(String message) { 127364fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav try { 127464fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav mApp.enforceCallingOrSelfPermission( 127564fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav android.Manifest.permission.ACCESS_FINE_LOCATION, null); 127664fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav } catch (SecurityException e) { 127764fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav // If we have ACCESS_FINE_LOCATION permission, skip the check for ACCESS_COARSE_LOCATION 127864fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav // A failure should throw the SecurityException from ACCESS_COARSE_LOCATION since this 127964fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav // is the weaker precondition 128064fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav mApp.enforceCallingOrSelfPermission( 128164fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav android.Manifest.permission.ACCESS_COARSE_LOCATION, message); 128264fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav } 128364fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav } 128464fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav 128564fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav 12867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 12877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void enableLocationUpdates() { 1288add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville enableLocationUpdatesForSubscriber(getDefaultSubscription()); 128936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 129036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1291b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public void enableLocationUpdatesForSubscriber(int subId) { 12927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 12937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.CONTROL_LOCATION_UPDATES, null); 129436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).enableLocationUpdates(); 12957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 12987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void disableLocationUpdates() { 1299add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville disableLocationUpdatesForSubscriber(getDefaultSubscription()); 130036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 130136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1302b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public void disableLocationUpdatesForSubscriber(int subId) { 13037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 13047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.CONTROL_LOCATION_UPDATES, null); 130536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville getPhone(subId).disableLocationUpdates(); 13067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 13097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @SuppressWarnings("unchecked") 13107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage) { 131164fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav enforceFineOrCoarseLocationPermission("getNeighboringCellInfo"); 131264fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav 131364fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav // OP_COARSE_LOCATION controls both fine and coarse location. 131464fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav if (mAppOps.noteOp(AppOpsManager.OP_COARSE_LOCATION, Binder.getCallingUid(), 131564fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav callingPackage) != AppOpsManager.MODE_ALLOWED) { 131664fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav return null; 13177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(), 13207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon callingPackage) != AppOpsManager.MODE_ALLOWED) { 13217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 13227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 132364fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav 1324e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (checkIfCallerIsSelfOrForegroundUser()) { 13257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getNeighboringCellInfo: is active user"); 13267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ArrayList<NeighboringCellInfo> cells = null; 13287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 13307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon cells = (ArrayList<NeighboringCellInfo>) sendRequest( 133136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville CMD_HANDLE_NEIGHBORING_CELL, null, null); 13327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (RuntimeException e) { 133336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville Log.e(LOG_TAG, "getNeighboringCellInfo " + e); 13347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return cells; 13367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 13377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getNeighboringCellInfo: suppress non-active user"); 13387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 13397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 134464fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav public List<CellInfo> getAllCellInfo(String callingPackage) { 134564fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav enforceFineOrCoarseLocationPermission("getAllCellInfo"); 134664fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav 134764fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav // OP_COARSE_LOCATION controls both fine and coarse location. 134864fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav if (mAppOps.noteOp(AppOpsManager.OP_COARSE_LOCATION, Binder.getCallingUid(), 134964fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav callingPackage) != AppOpsManager.MODE_ALLOWED) { 135064fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav return null; 13517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1353e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (checkIfCallerIsSelfOrForegroundUser()) { 13547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getAllCellInfo: is active user"); 13552c01cdffe4cb2bbc480f7080ef14e21f88833007Legler Wu List<CellInfo> cellInfos = new ArrayList<CellInfo>(); 13562c01cdffe4cb2bbc480f7080ef14e21f88833007Legler Wu for (Phone phone : PhoneFactory.getPhones()) { 13572c01cdffe4cb2bbc480f7080ef14e21f88833007Legler Wu cellInfos.addAll(phone.getAllCellInfo()); 13582c01cdffe4cb2bbc480f7080ef14e21f88833007Legler Wu } 13592c01cdffe4cb2bbc480f7080ef14e21f88833007Legler Wu return cellInfos; 13607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 13617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getAllCellInfo: suppress non-active user"); 13627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 13637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1366bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal @Override 13677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void setCellInfoListRate(int rateInMillis) { 13687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.setCellInfoListRate(rateInMillis); 13697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 13727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Internal helper methods. 13737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 13747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1375e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static boolean checkIfCallerIsSelfOrForegroundUser() { 13767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean ok; 13777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean self = Binder.getCallingUid() == Process.myUid(); 13797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!self) { 13807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Get the caller's user id then clear the calling identity 13817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // which will be restored in the finally clause. 13827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int callingUser = UserHandle.getCallingUserId(); 13837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon long ident = Binder.clearCallingIdentity(); 13847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 13867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // With calling identity cleared the current user is the foreground user. 13877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int foregroundUser = ActivityManager.getCurrentUser(); 13887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ok = (foregroundUser == callingUser); 13897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) { 13907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon log("checkIfCallerIsSelfOrForegoundUser: foregroundUser=" + foregroundUser 13917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon + " callingUser=" + callingUser + " ok=" + ok); 13927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (Exception ex) { 13947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) loge("checkIfCallerIsSelfOrForegoundUser: Exception ex=" + ex); 13957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ok = false; 13967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } finally { 13977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Binder.restoreCallingIdentity(ident); 13987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 14007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("checkIfCallerIsSelfOrForegoundUser: is self"); 14017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ok = true; 14027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("checkIfCallerIsSelfOrForegoundUser: ret=" + ok); 14047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return ok; 14057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 14087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make sure the caller has the MODIFY_PHONE_STATE permission. 14097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 14107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @throws SecurityException if the caller does not have the required permission 14117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 14127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void enforceModifyPermission() { 14137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null); 14147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1417a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * Make sure either system app or the caller has carrier privilege. 1418a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * 1419a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * @throws SecurityException if the caller does not have the required permission/privilege 1420a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu */ 1421a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu private void enforceModifyPermissionOrCarrierPrivilege() { 1422f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal int permission = mApp.checkCallingOrSelfPermission( 1423f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal android.Manifest.permission.MODIFY_PHONE_STATE); 1424f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal if (permission == PackageManager.PERMISSION_GRANTED) { 1425f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal return; 1426f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal } 1427f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal 1428f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal log("No modify permission, check carrier privilege next."); 14295e5becdfa352e3ad1699cce13386b20761e2fde1Shishir Agrawal if (getCarrierPrivilegeStatus() != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 1430f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal loge("No Carrier Privilege."); 1431f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal throw new SecurityException("No modify permission or carrier privilege."); 1432a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu } 1433a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu } 1434a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu 1435a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu /** 1436a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * Make sure the caller has carrier privilege. 1437a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * 1438a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * @throws SecurityException if the caller does not have the required permission 1439a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu */ 1440a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu private void enforceCarrierPrivilege() { 14415e5becdfa352e3ad1699cce13386b20761e2fde1Shishir Agrawal if (getCarrierPrivilegeStatus() != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 1442f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal loge("No Carrier Privilege."); 1443f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal throw new SecurityException("No Carrier Privilege."); 1444a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu } 1445a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu } 1446a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu 1447a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu /** 14487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make sure the caller has the CALL_PHONE permission. 14497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 14507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @throws SecurityException if the caller does not have the required permission 14517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 14527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void enforceCallPermission() { 14537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null); 14547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1456566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal /** 145736ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal * Make sure the caller has the READ_PRIVILEGED_PHONE_STATE permission. 145836ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal * 145936ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal * @throws SecurityException if the caller does not have the required permission 146036ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal */ 146136ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal private void enforcePrivilegedPhoneStatePermission() { 146236ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 146336ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal null); 146436ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal } 146536ebb0d4d04346a367b7a54b178ab4f78696e95cGabriel Peal 14668eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott private void enforceConnectivityInternalPermission() { 14678eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott mApp.enforceCallingOrSelfPermission( 14688eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott android.Manifest.permission.CONNECTIVITY_INTERNAL, 14698eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott "ConnectivityService"); 14708eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott } 14718eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott 14727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private String createTelUrl(String number) { 14737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (TextUtils.isEmpty(number)) { 14747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 14757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1477e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return "tel:" + number; 14787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1480f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad private static void log(String msg) { 14817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg); 14827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14841fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla private static void logv(String msg) { 14851fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg); 14861fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 14871fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla 1488f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad private static void loge(String msg) { 14897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg); 14907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getActivePhoneType() { 1493add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return getActivePhoneTypeForSubscriber(getDefaultSubscription()); 149436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 149536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1496b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public int getActivePhoneTypeForSubscriber(int subId) { 149736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getPhoneType(); 14987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 15017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the CDMA ERI icon index to display 15027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 15037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getCdmaEriIconIndex() { 1504add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return getCdmaEriIconIndexForSubscriber(getDefaultSubscription()); 150536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 150636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 150736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1508b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public int getCdmaEriIconIndexForSubscriber(int subId) { 150936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getCdmaEriIconIndex(); 15107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 15137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the CDMA ERI icon mode, 15147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 0 - ON 15157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 1 - FLASHING 15167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 15177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getCdmaEriIconMode() { 1518add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return getCdmaEriIconModeForSubscriber(getDefaultSubscription()); 151936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 152036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1521b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public int getCdmaEriIconModeForSubscriber(int subId) { 152236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getCdmaEriIconMode(); 15237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 15267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the CDMA ERI text, 15277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 15287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public String getCdmaEriText() { 1529add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return getCdmaEriTextForSubscriber(getDefaultSubscription()); 153036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 153136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1532b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public String getCdmaEriTextForSubscriber(int subId) { 153336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getCdmaEriText(); 15347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1537ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu * Returns the CDMA MDN. 1538ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu */ 1539b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public String getCdmaMdn(int subId) { 1540ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1541ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 1542ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu return getPhone(subId).getLine1Number(); 1543ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu } else { 1544ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu return null; 1545ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu } 1546ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu } 1547ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu 1548ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu /** 1549ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu * Returns the CDMA MIN. 1550ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu */ 1551b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public String getCdmaMin(int subId) { 1552ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1553ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 1554ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu return getPhone(subId).getCdmaMin(); 1555ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu } else { 1556ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu return null; 1557ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu } 1558ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu } 1559ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu 1560ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu /** 15617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns true if CDMA provisioning needs to run. 15627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 15637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean needsOtaServiceProvisioning() { 15647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.needsOtaServiceProvisioning(); 15657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 156876d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal * Sets the voice mail number of a given subId. 156976d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal */ 157076d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal @Override 157176d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal public boolean setVoiceMailNumber(int subId, String alphaTag, String number) { 15725e5becdfa352e3ad1699cce13386b20761e2fde1Shishir Agrawal enforceCarrierPrivilege(); 157376d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER, 157476d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal new Pair<String, String>(alphaTag, number), new Integer(subId)); 157576d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal return success; 157676d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal } 157776d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal 157876d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal /** 15797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the unread count of voicemails 15807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 15817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getVoiceMessageCount() { 1582add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return getVoiceMessageCountForSubscriber(getDefaultSubscription()); 158336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 158436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 158536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 158636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns the unread count of voicemails for a subId 158736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 1588b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public int getVoiceMessageCountForSubscriber( int subId) { 158936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getVoiceMessageCount(); 15907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 15937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the data network type 15947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 15957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @Deprecated to be removed Q3 2013 use {@link #getDataNetworkType}. 15967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 15977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 15987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getNetworkType() { 1599add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return getNetworkTypeForSubscriber(getDefaultSubscription()); 160036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 160136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 160236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 160336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns the network type for a subId 160436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 160536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville @Override 1606b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public int getNetworkTypeForSubscriber(int subId) { 160736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getServiceState().getDataNetworkType(); 16087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 16117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the data network type 16127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 16137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 16147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getDataNetworkType() { 1615add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return getDataNetworkTypeForSubscriber(getDefaultSubscription()); 161636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 161736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 161836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 161936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns the data network type for a subId 162036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 162136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville @Override 1622b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public int getDataNetworkTypeForSubscriber(int subId) { 162336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getServiceState().getDataNetworkType(); 16247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 16277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the data network type 16287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 16297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 16307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getVoiceNetworkType() { 1631add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return getVoiceNetworkTypeForSubscriber(getDefaultSubscription()); 163236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 163336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 163436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 163536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns the Voice network type for a subId 163636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 163736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville @Override 1638b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public int getVoiceNetworkTypeForSubscriber(int subId) { 163936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getServiceState().getVoiceNetworkType(); 16407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 16437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return true if a ICC card is present 16447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 16457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean hasIccCard() { 164636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // FIXME Make changes to pass defaultSimId of type int 1647a6fc2a8518c71b7a720f849bbfd4c51fe35a461dAmit Mahajan return hasIccCardUsingSlotId(mSubscriptionController.getSlotId(getDefaultSubscription())); 164836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 164936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 165036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 165136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * @return true if a ICC card is present for a slotId 165236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 1653b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public boolean hasIccCardUsingSlotId(int slotId) { 1654a6fc2a8518c71b7a720f849bbfd4c51fe35a461dAmit Mahajan int subId[] = mSubscriptionController.getSubIdUsingSlotId(slotId); 1655a6fc2a8518c71b7a720f849bbfd4c51fe35a461dAmit Mahajan if (subId != null) { 1656a6fc2a8518c71b7a720f849bbfd4c51fe35a461dAmit Mahajan return getPhone(subId[0]).getIccCard().hasIccCard(); 1657a6fc2a8518c71b7a720f849bbfd4c51fe35a461dAmit Mahajan } else { 1658a6fc2a8518c71b7a720f849bbfd4c51fe35a461dAmit Mahajan return false; 1659a6fc2a8518c71b7a720f849bbfd4c51fe35a461dAmit Mahajan } 16607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 16637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Return if the current radio is LTE on CDMA. This 16647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * is a tri-state return value as for a period of time 16657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * the mode may be unknown. 16667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 16677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE} 1668e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * or {@link Phone#LTE_ON_CDMA_TRUE} 16697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 16707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getLteOnCdmaMode() { 1671add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return getLteOnCdmaModeForSubscriber(getDefaultSubscription()); 167236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 167336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1674b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public int getLteOnCdmaModeForSubscriber(int subId) { 167536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return getPhone(subId).getLteOnCdmaMode(); 167636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 167736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 167836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void setPhone(Phone phone) { 167936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville mPhone = phone; 168036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 168136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 168236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 168336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * {@hide} 168436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns Default subId, 0 in the case of single standby. 168536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 1686b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville private int getDefaultSubscription() { 1687ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville return mSubscriptionController.getDefaultSubId(); 168836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 168936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1690b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville private int getPreferredVoiceSubscription() { 1691ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville return mSubscriptionController.getDefaultVoiceSubId(); 16927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1693f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad 1694f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad /** 1695f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad * @see android.telephony.TelephonyManager.WifiCallingChoices 1696f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad */ 1697f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad public int getWhenToMakeWifiCalls() { 1698d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal return Settings.System.getInt(mPhone.getContext().getContentResolver(), 1699d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal Settings.System.WHEN_TO_MAKE_WIFI_CALLS, getWhenToMakeWifiCallsDefaultPreference()); 1700f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad } 1701f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad 1702f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad /** 1703f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad * @see android.telephony.TelephonyManager.WifiCallingChoices 1704f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad */ 1705f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad public void setWhenToMakeWifiCalls(int preference) { 1706d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference); 1707d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal Settings.System.putInt(mPhone.getContext().getContentResolver(), 1708d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference); 1709f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad } 1710f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad 1711d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal private static int getWhenToMakeWifiCallsDefaultPreference() { 1712da120f4e3d32ca97c5b4c21d6c505d834a29ab8dSantos Cordon // TODO: Use a build property to choose this value. 17139829e880f73f76119ba76ba032db42aad042858fEvan Charlton return TelephonyManager.WifiCallingChoices.ALWAYS_USE; 1714f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad } 171569f68120b94cecb2d87fe856bc115714b4e77bcdShishir Agrawal 1716566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal @Override 1717da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal public IccOpenLogicalChannelResponse iccOpenLogicalChannel(String AID) { 1718a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1719566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1720566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccOpenLogicalChannel: " + AID); 1721da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse)sendRequest( 1722da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal CMD_OPEN_CHANNEL, AID); 1723da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (DBG) log("iccOpenLogicalChannel: " + response); 1724da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal return response; 1725566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1726566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1727566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal @Override 1728566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public boolean iccCloseLogicalChannel(int channel) { 1729a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1730566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1731566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccCloseLogicalChannel: " + channel); 1732566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (channel < 0) { 1733566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return false; 1734566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1735e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean)sendRequest(CMD_CLOSE_CHANNEL, channel); 1736566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccCloseLogicalChannel: " + success); 1737566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return success; 1738566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1739566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1740566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal @Override 1741566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public String iccTransmitApduLogicalChannel(int channel, int cla, 1742566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal int command, int p1, int p2, int p3, String data) { 1743a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1744566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1745566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) { 1746566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal log("iccTransmitApduLogicalChannel: chnl=" + channel + " cla=" + cla + 1747566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + 1748566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal " data=" + data); 1749566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1750566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1751566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (channel < 0) { 1752566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return ""; 1753566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1754566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1755da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccIoResult response = (IccIoResult)sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL, 1756566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal new IccAPDUArgument(channel, cla, command, p1, p2, p3, data)); 1757566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccTransmitApduLogicalChannel: " + response); 1758566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1759566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal // Append the returned status code to the end of the response payload. 1760566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal String s = Integer.toHexString( 1761566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 17625ec14172e42d180d7dd6110ef8eb1dedb0a0a7fbShishir Agrawal if (response.payload != null) { 17635ec14172e42d180d7dd6110ef8eb1dedb0a0a7fbShishir Agrawal s = IccUtils.bytesToHexString(response.payload) + s; 17645ec14172e42d180d7dd6110ef8eb1dedb0a0a7fbShishir Agrawal } 1765566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return s; 1766566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1767e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 1768c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton @Override 1769da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal public String iccTransmitApduBasicChannel(int cla, int command, int p1, int p2, 1770da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal int p3, String data) { 1771da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal enforceModifyPermissionOrCarrierPrivilege(); 1772da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1773da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (DBG) { 1774da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal log("iccTransmitApduBasicChannel: cla=" + cla + " cmd=" + command + " p1=" 1775da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data); 1776da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 1777da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1778da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccIoResult response = (IccIoResult)sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL, 1779da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal new IccAPDUArgument(0, cla, command, p1, p2, p3, data)); 1780da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (DBG) log("iccTransmitApduBasicChannel: " + response); 1781da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1782da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal // Append the returned status code to the end of the response payload. 1783da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal String s = Integer.toHexString( 1784da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 17855ec14172e42d180d7dd6110ef8eb1dedb0a0a7fbShishir Agrawal if (response.payload != null) { 17865ec14172e42d180d7dd6110ef8eb1dedb0a0a7fbShishir Agrawal s = IccUtils.bytesToHexString(response.payload) + s; 17875ec14172e42d180d7dd6110ef8eb1dedb0a0a7fbShishir Agrawal } 1788da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal return s; 1789da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 1790da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1791da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal @Override 1792da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal public byte[] iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3, 1793da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal String filePath) { 1794da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal enforceModifyPermissionOrCarrierPrivilege(); 1795da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1796da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (DBG) { 1797da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal log("Exchange SIM_IO " + fileID + ":" + command + " " + 1798da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal p1 + " " + p2 + " " + p3 + ":" + filePath); 1799da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 1800da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1801da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccIoResult response = 1802da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal (IccIoResult)sendRequest(CMD_EXCHANGE_SIM_IO, 18033edf3789a6e8b6b9ac28b7dfb24d6d7b00b3b554Yong Jiang new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath)); 1804da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1805da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (DBG) { 1806da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal log("Exchange SIM_IO [R]" + response); 1807da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 1808da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1809da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal byte[] result = null; 1810da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal int length = 2; 1811da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (response.payload != null) { 1812da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal length = 2 + response.payload.length; 1813da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal result = new byte[length]; 1814da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal System.arraycopy(response.payload, 0, result, 0, response.payload.length); 1815da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else { 1816da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal result = new byte[length]; 1817da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 1818da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1819da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal result[length - 1] = (byte) response.sw2; 1820da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal result[length - 2] = (byte) response.sw1; 1821da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal return result; 1822da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 1823da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 1824da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal @Override 1825c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton public String sendEnvelopeWithStatus(String content) { 1826a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1827c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton 1828c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton IccIoResult response = (IccIoResult)sendRequest(CMD_SEND_ENVELOPE, content); 1829c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton if (response.payload == null) { 1830c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton return ""; 1831c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton } 1832c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton 1833c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton // Append the returned status code to the end of the response payload. 1834c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton String s = Integer.toHexString( 1835c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 1836c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton s = IccUtils.bytesToHexString(response.payload) + s; 1837c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton return s; 1838c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton } 1839c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton 1840e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 1841e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems} 1842e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators. 1843e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 1844e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param itemID the ID of the item to read 1845e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return the NV item as a String, or null on error. 1846e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 1847e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 1848e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public String nvReadItem(int itemID) { 1849a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1850e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvReadItem: item " + itemID); 1851e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID); 1852e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"'); 1853e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return value; 1854e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 1855e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 1856e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 1857e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems} 1858e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators. 1859e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 1860e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param itemID the ID of the item to read 1861e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param itemValue the value to write, as a String 1862e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return true on success; false on any failure 1863e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 1864e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 1865e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public boolean nvWriteItem(int itemID, String itemValue) { 1866a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1867e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"'); 1868e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM, 1869e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby new Pair<Integer, String>(itemID, itemValue)); 1870e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail")); 1871e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return success; 1872e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 1873e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 1874e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 1875e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage. 1876e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Used for device configuration by some CDMA operators. 1877e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 1878e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param preferredRoamingList byte array containing the new PRL 1879e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return true on success; false on any failure 1880e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 1881e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 1882e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) { 1883a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1884e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList)); 1885e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList); 1886e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail")); 1887e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return success; 1888e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 1889e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 1890e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 1891e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Perform the specified type of NV config reset. 1892e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Used for device configuration by some CDMA operators. 1893e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 1894e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset) 1895e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return true on success; false on any failure 1896e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 1897e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 1898e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public boolean nvResetConfig(int resetType) { 1899a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1900e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvResetConfig: type " + resetType); 1901e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean) sendRequest(CMD_NV_RESET_CONFIG, resetType); 1902e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvResetConfig: type " + resetType + ' ' + (success ? "ok" : "fail")); 1903e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return success; 1904e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 19057c27be317e8757948178815426d3a329c852b9eeJake Hamby 19067c27be317e8757948178815426d3a329c852b9eeJake Hamby /** 190736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * {@hide} 190836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns Default sim, 0 in the case of single standby. 190936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 191036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getDefaultSim() { 191136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville //TODO Need to get it from Telephony Devcontroller 191236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return 0; 191336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 191436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1915b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov public String[] getPcscfAddress(String apnType, String callingPackage) { 1916b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov if (!canReadPhoneState(callingPackage, "getPcscfAddress")) { 1917b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov return new String[0]; 1918b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov } 1919b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov 1920b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov 192187fca6f34c10e43e4dcfdd3f4e35bd4050e19582ram return mPhone.getPcscfAddress(apnType); 192236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 192336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 192436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void setImsRegistrationState(boolean registered) { 192536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville enforceModifyPermission(); 192636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville mPhone.setImsRegistrationState(registered); 192736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 192836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 192936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 193054788801de04c603a856596f4ae4377ab77a9821Stuart Scott * Set the network selection mode to automatic. 193154788801de04c603a856596f4ae4377ab77a9821Stuart Scott * 193254788801de04c603a856596f4ae4377ab77a9821Stuart Scott */ 193354788801de04c603a856596f4ae4377ab77a9821Stuart Scott @Override 193454788801de04c603a856596f4ae4377ab77a9821Stuart Scott public void setNetworkSelectionModeAutomatic(int subId) { 193554788801de04c603a856596f4ae4377ab77a9821Stuart Scott enforceModifyPermissionOrCarrierPrivilege(); 193654788801de04c603a856596f4ae4377ab77a9821Stuart Scott if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId); 193754788801de04c603a856596f4ae4377ab77a9821Stuart Scott sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId); 193854788801de04c603a856596f4ae4377ab77a9821Stuart Scott } 193954788801de04c603a856596f4ae4377ab77a9821Stuart Scott 194054788801de04c603a856596f4ae4377ab77a9821Stuart Scott /** 194184d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu * Get the calculated preferred network type. 194284d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu * Used for debugging incorrect network type. 194384d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu * 194484d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu * @return the preferred network type, defined in RILConstants.java. 194584d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu */ 194684d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu @Override 1947b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov public int getCalculatedPreferredNetworkType(String callingPackage) { 1948b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov if (!canReadPhoneState(callingPackage, "getCalculatedPreferredNetworkType")) { 1949b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov return RILConstants.PREFERRED_NETWORK_MODE; 1950b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov } 1951b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov 195243330e02af9431ac18a9b9d6c09610f910b8c0f2Amit Mahajan return PhoneFactory.calculatePreferredNetworkType(mPhone.getContext(), 0); // wink FIXME: need to get SubId from somewhere. 195384d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu } 195484d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu 195584d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu /** 19567c27be317e8757948178815426d3a329c852b9eeJake Hamby * Get the preferred network type. 19577c27be317e8757948178815426d3a329c852b9eeJake Hamby * Used for device configuration by some CDMA operators. 19587c27be317e8757948178815426d3a329c852b9eeJake Hamby * 19597c27be317e8757948178815426d3a329c852b9eeJake Hamby * @return the preferred network type, defined in RILConstants.java. 19607c27be317e8757948178815426d3a329c852b9eeJake Hamby */ 19617c27be317e8757948178815426d3a329c852b9eeJake Hamby @Override 196254788801de04c603a856596f4ae4377ab77a9821Stuart Scott public int getPreferredNetworkType(int subId) { 1963a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 19647c27be317e8757948178815426d3a329c852b9eeJake Hamby if (DBG) log("getPreferredNetworkType"); 196554788801de04c603a856596f4ae4377ab77a9821Stuart Scott int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId); 19667c27be317e8757948178815426d3a329c852b9eeJake Hamby int networkType = (result != null ? result[0] : -1); 19677c27be317e8757948178815426d3a329c852b9eeJake Hamby if (DBG) log("getPreferredNetworkType: " + networkType); 19687c27be317e8757948178815426d3a329c852b9eeJake Hamby return networkType; 19697c27be317e8757948178815426d3a329c852b9eeJake Hamby } 19707c27be317e8757948178815426d3a329c852b9eeJake Hamby 19717c27be317e8757948178815426d3a329c852b9eeJake Hamby /** 19727c27be317e8757948178815426d3a329c852b9eeJake Hamby * Set the preferred network type. 19737c27be317e8757948178815426d3a329c852b9eeJake Hamby * Used for device configuration by some CDMA operators. 19747c27be317e8757948178815426d3a329c852b9eeJake Hamby * 19757c27be317e8757948178815426d3a329c852b9eeJake Hamby * @param networkType the preferred network type, defined in RILConstants.java. 19767c27be317e8757948178815426d3a329c852b9eeJake Hamby * @return true on success; false on any failure. 19777c27be317e8757948178815426d3a329c852b9eeJake Hamby */ 19787c27be317e8757948178815426d3a329c852b9eeJake Hamby @Override 197954788801de04c603a856596f4ae4377ab77a9821Stuart Scott public boolean setPreferredNetworkType(int subId, int networkType) { 1980a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 198154788801de04c603a856596f4ae4377ab77a9821Stuart Scott if (DBG) log("setPreferredNetworkType: subId " + subId + " type " + networkType); 198254788801de04c603a856596f4ae4377ab77a9821Stuart Scott Boolean success = (Boolean) sendRequest(CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId); 19837c27be317e8757948178815426d3a329c852b9eeJake Hamby if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail")); 198480bc0d1614b46c89fa7a2c1d68fdb3ccb018625dJunda Liu if (success) { 198580bc0d1614b46c89fa7a2c1d68fdb3ccb018625dJunda Liu Settings.Global.putInt(mPhone.getContext().getContentResolver(), 198654788801de04c603a856596f4ae4377ab77a9821Stuart Scott Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType); 198780bc0d1614b46c89fa7a2c1d68fdb3ccb018625dJunda Liu } 19887c27be317e8757948178815426d3a329c852b9eeJake Hamby return success; 19897c27be317e8757948178815426d3a329c852b9eeJake Hamby } 1990ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt 1991ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt /** 1992475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu * Check TETHER_DUN_REQUIRED and TETHER_DUN_APN settings, net.tethering.noprovisioning 1993475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu * SystemProperty, and config_tether_apndata to decide whether DUN APN is required for 1994475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu * tethering. 1995475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu * 1996475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu * @return 0: Not required. 1: required. 2: Not set. 1997475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu * @hide 1998475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu */ 1999475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu @Override 2000475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu public int getTetherApnRequired() { 2001475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 2002475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu int dunRequired = Settings.Global.getInt(mPhone.getContext().getContentResolver(), 2003475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu Settings.Global.TETHER_DUN_REQUIRED, 2); 2004475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu // If not set, check net.tethering.noprovisioning, TETHER_DUN_APN setting and 2005475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu // config_tether_apndata. 2006475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu if (dunRequired == 2 && mPhone.hasMatchedTetherApnSetting()) { 2007475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu dunRequired = 1; 2008475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu } 2009475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu return dunRequired; 2010475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu } 2011475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu 2012475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu /** 2013ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * Set mobile data enabled 2014ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * Used by the user through settings etc to turn on/off mobile data 2015ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * 2016ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * @param enable {@code true} turn turn data on, else {@code false} 2017ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt */ 2018ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt @Override 2019e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville public void setDataEnabled(int subId, boolean enable) { 2020ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt enforceModifyPermission(); 2021e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville int phoneId = mSubscriptionController.getPhoneId(subId); 2022e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville log("getDataEnabled: subId=" + subId + " phoneId=" + phoneId); 2023e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville Phone phone = PhoneFactory.getPhone(phoneId); 2024e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville if (phone != null) { 2025e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville log("setDataEnabled: subId=" + subId + " enable=" + enable); 2026e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville phone.setDataEnabled(enable); 2027e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville } else { 2028e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville loge("setDataEnabled: no phone for subId=" + subId); 2029e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville } 2030ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt } 2031ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt 2032ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt /** 2033646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * Get whether mobile data is enabled. 2034646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * 2035646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * Note that this used to be available from ConnectivityService, gated by 2036646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * ACCESS_NETWORK_STATE permission, so this will accept either that or 2037646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * our MODIFY_PHONE_STATE. 2038ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * 2039ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * @return {@code true} if data is enabled else {@code false} 2040ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt */ 2041ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt @Override 2042e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville public boolean getDataEnabled(int subId) { 2043646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt try { 2044646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE, 2045646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt null); 2046646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt } catch (Exception e) { 2047646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, 2048646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt null); 2049646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt } 2050e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville int phoneId = mSubscriptionController.getPhoneId(subId); 2051e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville log("getDataEnabled: subId=" + subId + " phoneId=" + phoneId); 2052e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville Phone phone = PhoneFactory.getPhone(phoneId); 2053e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville if (phone != null) { 2054e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville boolean retVal = phone.getDataEnabled(); 2055e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville log("getDataEnabled: subId=" + subId + " retVal=" + retVal); 2056e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville return retVal; 2057e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville } else { 2058e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville loge("getDataEnabled: no phone subId=" + subId + " retVal=false"); 2059e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville return false; 2060e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville } 2061ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt } 206260f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawal 206360f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawal @Override 20645e5becdfa352e3ad1699cce13386b20761e2fde1Shishir Agrawal public int getCarrierPrivilegeStatus() { 206521409250c4001605606a37c3903dc22805410900Shishir Agrawal UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId()); 2066eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (card == null) { 20675e5becdfa352e3ad1699cce13386b20761e2fde1Shishir Agrawal loge("getCarrierPrivilegeStatus: No UICC"); 2068eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 2069eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 2070eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal return card.getCarrierPrivilegeStatusForCurrentTransaction( 2071f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal mPhone.getContext().getPackageManager()); 207260f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawal } 20732934034e04c5ca7839de41d0cc8f8bab89b1e336Junda Liu 20742934034e04c5ca7839de41d0cc8f8bab89b1e336Junda Liu @Override 207550ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson public int checkCarrierPrivilegesForPackage(String pkgName) { 207621409250c4001605606a37c3903dc22805410900Shishir Agrawal UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId()); 2077eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (card == null) { 2078eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("checkCarrierPrivilegesForPackage: No UICC"); 2079eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 2080eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 208150ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson return card.getCarrierPrivilegeStatus(mPhone.getContext().getPackageManager(), pkgName); 208250ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson } 208350ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson 208450ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson @Override 208550ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) { 208650ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 208750ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { 208850ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson UiccCard card = UiccController.getInstance().getUiccCard(i); 208950ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson if (card == null) { 209050ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson loge("checkCarrierPrivilegesForPackageAnyPhones: No UICC"); 209150ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson continue; 209250ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson } 209350ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson 209450ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson result = card.getCarrierPrivilegeStatus( 209550ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson mPhone.getContext().getPackageManager(), pkgName); 209650ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 209750ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson break; 209850ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson } 209950ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson } 210050ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson 210150ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson return result; 21022934034e04c5ca7839de41d0cc8f8bab89b1e336Junda Liu } 210389e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan 210489e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan @Override 2105e64de7820475d67ef0882a1b37f3bd188ca68e25Junda Liu public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) { 2106e64de7820475d67ef0882a1b37f3bd188ca68e25Junda Liu if (!SubscriptionManager.isValidPhoneId(phoneId)) { 2107e64de7820475d67ef0882a1b37f3bd188ca68e25Junda Liu loge("phoneId " + phoneId + " is not valid."); 2108e64de7820475d67ef0882a1b37f3bd188ca68e25Junda Liu return null; 2109e64de7820475d67ef0882a1b37f3bd188ca68e25Junda Liu } 2110e64de7820475d67ef0882a1b37f3bd188ca68e25Junda Liu UiccCard card = UiccController.getInstance().getUiccCard(phoneId); 2111eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal if (card == null) { 2112af74c86463b193100a48a0a2b83d0096863bf110Diego Pontoriero loge("getCarrierPackageNamesForIntent: No UICC"); 2113eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal return null ; 2114eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal } 2115af74c86463b193100a48a0a2b83d0096863bf110Diego Pontoriero return card.getCarrierPackageNamesForIntent( 2116483aff78d6bada4c2f4d28f804935d24c8173fceSvetoslav mPhone.getContext().getPackageManager(), intent); 2117eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal } 2118eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal 2119b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville private String getIccId(int subId) { 212097ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan UiccCard card = getPhone(subId).getUiccCard(); 212197ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan if (card == null) { 212297ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan loge("getIccId: No UICC"); 212397ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return null; 212497ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } 212597ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String iccId = card.getIccId(); 212697ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan if (TextUtils.isEmpty(iccId)) { 212797ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan loge("getIccId: ICC ID is null or empty."); 212897ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return null; 212997ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } 213097ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return iccId; 213197ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } 213297ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan 2133eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal @Override 213485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag, 213585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey String number) { 21365e5becdfa352e3ad1699cce13386b20761e2fde1Shishir Agrawal enforceCarrierPrivilege(); 213797ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan 213885190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String iccId = getIccId(subId); 213985190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String subscriberId = getPhone(subId).getSubscriberId(); 214085190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 214185190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (DBG_MERGE) { 214285190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey Slog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId=" 214385190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey + subscriberId + " to " + number); 214485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 214585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 2146495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal if (TextUtils.isEmpty(iccId)) { 2147495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal return false; 2148495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal } 214997ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan 215085190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit(); 215185190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 215285190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId; 2153495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal if (alphaTag == null) { 2154495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal editor.remove(alphaTagPrefKey); 2155495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal } else { 2156495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal editor.putString(alphaTagPrefKey, alphaTag); 215797ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } 2158495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal 215985190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey // Record both the line number and IMSI for this ICCID, since we need to 216085190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey // track all merged IMSIs based on line number 216185190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId; 216285190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId; 2163495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal if (number == null) { 2164495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal editor.remove(numberPrefKey); 216585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey editor.remove(subscriberPrefKey); 2166495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal } else { 2167495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal editor.putString(numberPrefKey, number); 216885190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey editor.putString(subscriberPrefKey, subscriberId); 2169495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal } 217085190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 2171495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal editor.commit(); 2172495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal return true; 21737226c84acb402f96e527650347391fa025294350Derek Tan } 21747226c84acb402f96e527650347391fa025294350Derek Tan 21757226c84acb402f96e527650347391fa025294350Derek Tan @Override 2176b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov public String getLine1NumberForDisplay(int subId, String callingPackage) { 2177b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov if (!canReadPhoneState(callingPackage, "getLine1NumberForDisplay")) { 2178b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov return null; 2179b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov } 218097ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan 218197ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String iccId = getIccId(subId); 218297ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan if (iccId != null) { 218397ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId; 2184df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee return mTelephonySharedPreferences.getString(numberPrefKey, null); 21857226c84acb402f96e527650347391fa025294350Derek Tan } 218697ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return null; 21877226c84acb402f96e527650347391fa025294350Derek Tan } 21887226c84acb402f96e527650347391fa025294350Derek Tan 21897226c84acb402f96e527650347391fa025294350Derek Tan @Override 2190b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov public String getLine1AlphaTagForDisplay(int subId, String callingPackage) { 2191b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov if (!canReadPhoneState(callingPackage, "getLine1AlphaTagForDisplay")) { 2192b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov return null; 2193b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov } 219497ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan 219597ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String iccId = getIccId(subId); 219697ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan if (iccId != null) { 219797ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId; 2198df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee return mTelephonySharedPreferences.getString(alphaTagPrefKey, null); 21997226c84acb402f96e527650347391fa025294350Derek Tan } 220097ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return null; 22017226c84acb402f96e527650347391fa025294350Derek Tan } 2202b1ebf8c3755b7e1cb207cbd49f6c8bdfa3566668Shishir Agrawal 2203b1ebf8c3755b7e1cb207cbd49f6c8bdfa3566668Shishir Agrawal @Override 220485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey public String[] getMergedSubscriberIds() { 220585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final Context context = mPhone.getContext(); 220685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final TelephonyManager tele = TelephonyManager.from(context); 220785190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final SubscriptionManager sub = SubscriptionManager.from(context); 220885190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 220985190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey // Figure out what subscribers are currently active 221085190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final ArraySet<String> activeSubscriberIds = new ArraySet<>(); 221185190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final int[] subIds = sub.getActiveSubscriptionIdList(); 221285190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey for (int subId : subIds) { 221385190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey activeSubscriberIds.add(tele.getSubscriberId(subId)); 221485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 221585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 221685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey // First pass, find a number override for an active subscriber 221785190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey String mergeNumber = null; 221885190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final Map<String, ?> prefs = mTelephonySharedPreferences.getAll(); 221985190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey for (String key : prefs.keySet()) { 222085190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) { 222185190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String subscriberId = (String) prefs.get(key); 222285190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (activeSubscriberIds.contains(subscriberId)) { 222385190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String iccId = key.substring(PREF_CARRIERS_SUBSCRIBER_PREFIX.length()); 222485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId; 222585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey mergeNumber = (String) prefs.get(numberKey); 222685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (DBG_MERGE) { 222785190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey Slog.d(LOG_TAG, "Found line number " + mergeNumber 222885190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey + " for active subscriber " + subscriberId); 222985190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 223085190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (!TextUtils.isEmpty(mergeNumber)) { 223185190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey break; 223285190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 223385190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 223485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 223585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 223685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 223785190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey // Shortcut when no active merged subscribers 223885190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (TextUtils.isEmpty(mergeNumber)) { 223985190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey return null; 224085190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 224185190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 224285190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey // Second pass, find all subscribers under that line override 224385190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final ArraySet<String> result = new ArraySet<>(); 224485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey for (String key : prefs.keySet()) { 224585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) { 224685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String number = (String) prefs.get(key); 224785190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (mergeNumber.equals(number)) { 224885190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length()); 224985190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId; 225085190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String subscriberId = (String) prefs.get(subscriberKey); 225185190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (!TextUtils.isEmpty(subscriberId)) { 225285190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey result.add(subscriberId); 225385190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 225485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 225585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 225685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 225785190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 225885190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String[] resultArray = result.toArray(new String[result.size()]); 225985190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey Arrays.sort(resultArray); 226085190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (DBG_MERGE) { 226185190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey Slog.d(LOG_TAG, "Found subscribers " + Arrays.toString(resultArray) + " after merge"); 226285190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 226385190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey return resultArray; 226485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 226585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 226685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey @Override 2267a3dfd75141d37ae7e170eeb200374f62235b092eShishir Agrawal public boolean setOperatorBrandOverride(String brand) { 22685e5becdfa352e3ad1699cce13386b20761e2fde1Shishir Agrawal enforceCarrierPrivilege(); 2269a3dfd75141d37ae7e170eeb200374f62235b092eShishir Agrawal return mPhone.setOperatorBrandOverride(brand); 2270b1ebf8c3755b7e1cb207cbd49f6c8bdfa3566668Shishir Agrawal } 22714bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu 22724bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu @Override 2273621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawal public boolean setRoamingOverride(List<String> gsmRoamingList, 2274621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawal List<String> gsmNonRoamingList, List<String> cdmaRoamingList, 2275621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawal List<String> cdmaNonRoamingList) { 2276621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawal enforceCarrierPrivilege(); 2277621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawal return mPhone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList, 2278621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawal cdmaNonRoamingList); 2279621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawal } 2280621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawal 2281621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawal @Override 22824bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) { 22834bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu enforceModifyPermission(); 22844bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu 22854bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu int returnValue = 0; 22864bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu try { 22874bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu AsyncResult result = (AsyncResult)sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq); 22884bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu if(result.exception == null) { 22894bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu if (result.result != null) { 22904bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu byte[] responseData = (byte[])(result.result); 22914bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu if(responseData.length > oemResp.length) { 22924bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " + 22934bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu responseData.length + "bytes. Buffer Size is " + 22944bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu oemResp.length + "bytes."); 22954bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } 22964bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu System.arraycopy(responseData, 0, oemResp, 0, responseData.length); 22974bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu returnValue = responseData.length; 22984bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } 22994bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } else { 23004bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu CommandException ex = (CommandException) result.exception; 23014bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu returnValue = ex.getCommandError().ordinal(); 23024bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu if(returnValue > 0) returnValue *= -1; 23034bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } 23044bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } catch (RuntimeException e) { 23054bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception"); 23064bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal()); 23074bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu if(returnValue > 0) returnValue *= -1; 23084bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } 23094bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu 23104bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu return returnValue; 23114bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } 23125d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville 23135d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville @Override 23145d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville public void setRadioCapability(RadioAccessFamily[] rafs) { 23155d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville try { 23165d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville ProxyController.getInstance().setRadioCapability(rafs); 23175d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville } catch (RuntimeException e) { 23185d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville Log.w(LOG_TAG, "setRadioCapability: Runtime Exception"); 23195d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville } 23205d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville } 23215d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville 23225d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville @Override 23235d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville public int getRadioAccessFamily(int phoneId) { 23245d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville return ProxyController.getInstance().getRadioAccessFamily(phoneId); 23255d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville } 2326df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee 2327df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee @Override 2328df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee public void enableVideoCalling(boolean enable) { 2329df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee enforceModifyPermission(); 2330df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee SharedPreferences.Editor editor = mTelephonySharedPreferences.edit(); 2331df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee editor.putBoolean(PREF_ENABLE_VIDEO_CALLING, enable); 2332df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee editor.commit(); 2333df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee } 2334df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee 2335df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee @Override 2336b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov public boolean isVideoCallingEnabled(String callingPackage) { 2337b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov if (!canReadPhoneState(callingPackage, "isVideoCallingEnabled")) { 2338b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov return false; 2339b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov } 2340b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov 234177527ac0cdad089f51530066f5248cb7925dd365Andrew Lee // Check the user preference and the system-level IMS setting. Even if the user has 234277527ac0cdad089f51530066f5248cb7925dd365Andrew Lee // enabled video calling, if IMS is disabled we aren't able to support video calling. 234377527ac0cdad089f51530066f5248cb7925dd365Andrew Lee // In the long run, we may instead need to check if there exists a connection service 234477527ac0cdad089f51530066f5248cb7925dd365Andrew Lee // which can support video calling. 2345312e8177b25ab359627685d449e0a5fdb539809fAndrew Lee return ImsManager.isVtEnabledByPlatform(mPhone.getContext()) 2346312e8177b25ab359627685d449e0a5fdb539809fAndrew Lee && ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mPhone.getContext()) 2347312e8177b25ab359627685d449e0a5fdb539809fAndrew Lee && mTelephonySharedPreferences.getBoolean(PREF_ENABLE_VIDEO_CALLING, true); 2348df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee } 2349afe8264bd1241982c39c86f40d0fd08f0888c824Libin.Tang@motorola.com 2350a1239f2604b7fed20970aadf7496d6e12ba7ceaeAndrew Lee @Override 2351a1239f2604b7fed20970aadf7496d6e12ba7ceaeAndrew Lee public boolean canChangeDtmfToneLength() { 23529504c6b5c5c7072f72d8a9e6df59dbda8a6ccbe4Jonathan Basseri return mApp.getCarrierConfig().getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL); 2353a1239f2604b7fed20970aadf7496d6e12ba7ceaeAndrew Lee } 2354a1239f2604b7fed20970aadf7496d6e12ba7ceaeAndrew Lee 2355a1239f2604b7fed20970aadf7496d6e12ba7ceaeAndrew Lee @Override 2356a1239f2604b7fed20970aadf7496d6e12ba7ceaeAndrew Lee public boolean isWorldPhone() { 23579504c6b5c5c7072f72d8a9e6df59dbda8a6ccbe4Jonathan Basseri return mApp.getCarrierConfig().getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL); 2358a1239f2604b7fed20970aadf7496d6e12ba7ceaeAndrew Lee } 2359a1239f2604b7fed20970aadf7496d6e12ba7ceaeAndrew Lee 23609431b838f89399db2278c0436bd2817322a45f74Andrew Lee @Override 23619431b838f89399db2278c0436bd2817322a45f74Andrew Lee public boolean isTtyModeSupported() { 23629431b838f89399db2278c0436bd2817322a45f74Andrew Lee TelecomManager telecomManager = TelecomManager.from(mPhone.getContext()); 23639431b838f89399db2278c0436bd2817322a45f74Andrew Lee TelephonyManager telephonyManager = 23649431b838f89399db2278c0436bd2817322a45f74Andrew Lee (TelephonyManager) mPhone.getContext().getSystemService(Context.TELEPHONY_SERVICE); 23659431b838f89399db2278c0436bd2817322a45f74Andrew Lee return !telephonyManager.isMultiSimEnabled() && telecomManager.isTtySupported(); 23669431b838f89399db2278c0436bd2817322a45f74Andrew Lee } 23679431b838f89399db2278c0436bd2817322a45f74Andrew Lee 23689431b838f89399db2278c0436bd2817322a45f74Andrew Lee @Override 23699431b838f89399db2278c0436bd2817322a45f74Andrew Lee public boolean isHearingAidCompatibilitySupported() { 23709431b838f89399db2278c0436bd2817322a45f74Andrew Lee return mPhone.getContext().getResources().getBoolean(R.bool.hac_enabled); 23719431b838f89399db2278c0436bd2817322a45f74Andrew Lee } 23729431b838f89399db2278c0436bd2817322a45f74Andrew Lee 23737310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe /** 23747310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe * Returns the unique device ID of phone, for example, the IMEI for 23757310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe * GSM and the MEID for CDMA phones. Return null if device ID is not available. 23767310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe * 23777310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe * <p>Requires Permission: 23787310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} 23797310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe */ 23807310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe @Override 2381b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov public String getDeviceId(String callingPackage) { 2382b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov if (!canReadPhoneState(callingPackage, "getDeviceId")) { 2383b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov return null; 2384b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov } 2385b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov 23867310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe final Phone phone = PhoneFactory.getPhone(0); 23877310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe if (phone != null) { 23887310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe return phone.getDeviceId(); 23897310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe } else { 23907310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe return null; 23917310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe } 23927310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe } 23937310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe 2394afe8264bd1241982c39c86f40d0fd08f0888c824Libin.Tang@motorola.com /* 2395afe8264bd1241982c39c86f40d0fd08f0888c824Libin.Tang@motorola.com * {@hide} 2396afe8264bd1241982c39c86f40d0fd08f0888c824Libin.Tang@motorola.com * Returns the IMS Registration Status 2397afe8264bd1241982c39c86f40d0fd08f0888c824Libin.Tang@motorola.com */ 23987a1885ba88b4ca833d6dae8b352097636f242917Santos Cordon @Override 2399afe8264bd1241982c39c86f40d0fd08f0888c824Libin.Tang@motorola.com public boolean isImsRegistered() { 2400afe8264bd1241982c39c86f40d0fd08f0888c824Libin.Tang@motorola.com return mPhone.isImsRegistered(); 2401afe8264bd1241982c39c86f40d0fd08f0888c824Libin.Tang@motorola.com } 24027a1885ba88b4ca833d6dae8b352097636f242917Santos Cordon 24037a1885ba88b4ca833d6dae8b352097636f242917Santos Cordon @Override 24047a1885ba88b4ca833d6dae8b352097636f242917Santos Cordon public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) { 24057a1885ba88b4ca833d6dae8b352097636f242917Santos Cordon return PhoneUtils.getSubIdForPhoneAccount(phoneAccount); 24067a1885ba88b4ca833d6dae8b352097636f242917Santos Cordon } 2407dcfc793ddff32e3fd5ab49db2647d7b08fc4d29cNathan Harold 2408c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold /* 2409c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold * {@hide} 2410c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold * Returns the IMS Registration Status 2411c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold */ 2412c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold public boolean isWifiCallingEnabled() { 2413c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold return mPhone.isWifiCallingEnabled(); 2414c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold } 2415c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold 2416c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold /* 2417c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold * {@hide} 2418c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold * Returns the IMS Registration Status 2419c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold */ 2420c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold public boolean isVolteEnabled() { 2421c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold return mPhone.isVolteEnabled(); 2422c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold } 2423b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov 2424b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov private boolean canReadPhoneState(String callingPackage, String message) { 2425b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov mApp.enforceCallingOrSelfPermission( 2426b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov android.Manifest.permission.READ_PHONE_STATE, message); 2427b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov 2428b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(), 2429b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov callingPackage) != AppOpsManager.MODE_ALLOWED) { 2430b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov return false; 2431b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov } 2432b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov 2433b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov return true; 2434b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov } 24358eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott 24368eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott @Override 24378eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott public void factoryReset(int subId) { 24388eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott enforceConnectivityInternalPermission(); 2439981d85874294656a51683ae6ecc6ba312d3635ceStuart Scott if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) { 2440981d85874294656a51683ae6ecc6ba312d3635ceStuart Scott return; 2441981d85874294656a51683ae6ecc6ba312d3635ceStuart Scott } 2442981d85874294656a51683ae6ecc6ba312d3635ceStuart Scott 2443cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov final long identity = Binder.clearCallingIdentity(); 2444cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov try { 2445981d85874294656a51683ae6ecc6ba312d3635ceStuart Scott if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction( 2446981d85874294656a51683ae6ecc6ba312d3635ceStuart Scott UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) { 2447cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov // Enable data 2448cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov setDataEnabled(subId, true); 2449cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov // Set network selection mode to automatic 2450cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov setNetworkSelectionModeAutomatic(subId); 2451cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov // Set preferred mobile network type to the best available 2452cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov setPreferredNetworkType(subId, Phone.PREFERRED_NT_MODE); 2453cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov // Turn off roaming 2454cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov SubscriptionManager.from(mApp).setDataRoaming(0, subId); 2455cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov } 2456cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov } finally { 2457cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov Binder.restoreCallingIdentity(identity); 24588eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott } 24598eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott } 24601c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath 24611c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath @Override 24621c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath public String getLocaleFromDefaultSim() { 24631c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath // We query all subscriptions instead of just the active ones, because 24641c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath // this might be called early on in the provisioning flow when the 24651c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath // subscriptions potentially aren't active yet. 24661c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath final List<SubscriptionInfo> slist = getAllSubscriptionInfoList(); 24671c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath if (slist == null || slist.isEmpty()) { 24681c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath return null; 24691c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 24701c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath 24711c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath // This function may be called very early, say, from the setup wizard, at 24721c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath // which point we won't have a default subscription set. If that's the case 24731c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath // we just choose the first, which will be valid in "most cases". 24741c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath final int defaultSubId = getDefaultSubscription(); 24751c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath SubscriptionInfo info = null; 24761c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath if (defaultSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 24771c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath info = slist.get(0); 24781c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } else { 24791c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath for (SubscriptionInfo item : slist) { 24801c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath if (item.getSubscriptionId() == defaultSubId) { 24811c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath info = item; 24821c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath break; 24831c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 24841c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 24851c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath 24861c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath if (info == null) { 24871c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath return null; 24881c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 24891c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 24901c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath 24911c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath // Try and fetch the locale from the carrier properties or from the SIM language 24921c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath // preferences (EF-PL and EF-LI)... 24931c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath final Phone defaultPhone = getPhone(info.getSubscriptionId()); 24941c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath if (defaultPhone != null) { 24951c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath final Locale localeFromDefaultSim = defaultPhone.getLocaleFromSimAndCarrierPrefs(); 24961c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath if (localeFromDefaultSim != null) { 24971c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath return localeFromDefaultSim.toLanguageTag(); 24981c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 24991c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 25001c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath 25011c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath // .. if that doesn't work, try and guess the language from the sim MCC. 25021c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath final int mcc = info.getMcc(); 25031c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath final Locale locale = MccTable.getLocaleFromMcc(mPhone.getContext(), mcc); 25041c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath if (locale != null) { 25051c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath return locale.toLanguageTag(); 25061c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 25071c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath 25081c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath return null; 25091c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 25101c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath 25111c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath private List<SubscriptionInfo> getAllSubscriptionInfoList() { 25121c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath final long identity = Binder.clearCallingIdentity(); 25131c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath try { 25141c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath return mSubscriptionController.getAllSubInfoList( 25151c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath mPhone.getContext().getOpPackageName()); 25161c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } finally { 25171c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath Binder.restoreCallingIdentity(identity); 25181c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 25191c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 25201c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath 25211c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath private List<SubscriptionInfo> getActiveSubscriptionInfoList() { 25221c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath final long identity = Binder.clearCallingIdentity(); 25231c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath try { 25241c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath return mSubscriptionController.getActiveSubscriptionInfoList( 25251c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath mPhone.getContext().getOpPackageName()); 25261c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } finally { 25271c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath Binder.restoreCallingIdentity(identity); 25281c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 25291c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 25307fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham 25317fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham /** 25327fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham * {@hide} 25337fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham * Returns the modem stats 25347fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham */ 25357fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham @Override 25367fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham public ModemActivityInfo getModemActivityInfo() { 25377fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham return (ModemActivityInfo) sendRequest(CMD_GET_MODEM_ACTIVITY_INFO, null); 25387fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham } 25397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon} 2540