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; 60302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawalimport com.android.internal.telephony.CellNetworkScanResult; 61566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.CommandException; 627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.DefaultPhoneNotifier; 637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.ITelephony; 64e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport com.android.internal.telephony.IccCard; 651c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamathimport com.android.internal.telephony.MccTable; 66302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawalimport com.android.internal.telephony.OperatorInfo; 677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.Phone; 6836469e74b7c79ed84148754190c38196eb9a2c49Wink Savilleimport com.android.internal.telephony.PhoneFactory; 695d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Savilleimport com.android.internal.telephony.ProxyController; 707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.PhoneConstants; 71b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganovimport com.android.internal.telephony.RILConstants; 72ac1bdfd36366426513d51bd2c4b107b00533889eWink Savilleimport com.android.internal.telephony.SubscriptionController; 73566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.uicc.IccIoResult; 74566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.uicc.IccUtils; 75eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawalimport com.android.internal.telephony.uicc.UiccCard; 76566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawalimport com.android.internal.telephony.uicc.UiccController; 77e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport com.android.internal.util.HexDump; 787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7936469e74b7c79ed84148754190c38196eb9a2c49Wink Savilleimport static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY; 8036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport java.util.ArrayList; 8285190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkeyimport java.util.Arrays; 83621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawalimport java.util.HashMap; 84621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawalimport java.util.Iterator; 85e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hambyimport java.util.List; 861c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamathimport java.util.Locale; 8785190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkeyimport java.util.Map; 8885190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkeyimport java.util.Objects; 897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon/** 917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Implementation of the ITelephony interface. 927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 93117fee7467c140dccdc66972f60031dae2d55b35Santos Cordonpublic class PhoneInterfaceManager extends ITelephony.Stub { 947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final String LOG_TAG = "PhoneInterfaceManager"; 957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2); 967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final boolean DBG_LOC = false; 9785190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey private static final boolean DBG_MERGE = false; 987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Message codes used with mMainThreadHandler 1007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_HANDLE_PIN_MMI = 1; 1017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_HANDLE_NEIGHBORING_CELL = 2; 1027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int EVENT_NEIGHBORING_CELL_DONE = 3; 1037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_ANSWER_RINGING_CALL = 4; 1047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_END_CALL = 5; // not used yet 105da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7; 106da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8; 107566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int CMD_OPEN_CHANNEL = 9; 108566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int EVENT_OPEN_CHANNEL_DONE = 10; 109566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int CMD_CLOSE_CHANNEL = 11; 110566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final int EVENT_CLOSE_CHANNEL_DONE = 12; 111e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_READ_ITEM = 13; 112e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_READ_ITEM_DONE = 14; 113e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_WRITE_ITEM = 15; 114e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_WRITE_ITEM_DONE = 16; 115e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_WRITE_CDMA_PRL = 17; 116e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18; 117e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int CMD_NV_RESET_CONFIG = 19; 118e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static final int EVENT_NV_RESET_CONFIG_DONE = 20; 1197c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21; 1207c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22; 1217c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23; 1227c27be317e8757948178815426d3a329c852b9eeJake Hamby private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24; 12335b5945231af96ad0d7ebf4cfcaafeb677d8c75cSailesh Nepal private static final int CMD_SEND_ENVELOPE = 25; 12435b5945231af96ad0d7ebf4cfcaafeb677d8c75cSailesh Nepal private static final int EVENT_SEND_ENVELOPE_DONE = 26; 1256b088eef6c47d96b9b2a0097e3b8ee8b4332f068Derek Tan private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27; 1266b088eef6c47d96b9b2a0097e3b8ee8b4332f068Derek Tan private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28; 1276b088eef6c47d96b9b2a0097e3b8ee8b4332f068Derek Tan private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29; 1286b088eef6c47d96b9b2a0097e3b8ee8b4332f068Derek Tan private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30; 1296b088eef6c47d96b9b2a0097e3b8ee8b4332f068Derek Tan private static final int CMD_EXCHANGE_SIM_IO = 31; 1306b088eef6c47d96b9b2a0097e3b8ee8b4332f068Derek Tan private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32; 13176d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal private static final int CMD_SET_VOICEMAIL_NUMBER = 33; 13276d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34; 13354788801de04c603a856596f4ae4377ab77a9821Stuart Scott private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35; 13454788801de04c603a856596f4ae4377ab77a9821Stuart Scott private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36; 1357fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37; 1367fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38; 137302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal private static final int CMD_PERFORM_NETWORK_SCAN = 39; 138302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40; 139302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41; 140302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42; 1417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The singleton instance. */ 1437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static PhoneInterfaceManager sInstance; 1447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1453ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville private PhoneGlobals mApp; 1463ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville private Phone mPhone; 1473ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville private CallManager mCM; 148981d85874294656a51683ae6ecc6ba312d3635ceStuart Scott private UserManager mUserManager; 1493ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville private AppOpsManager mAppOps; 1503ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville private MainThreadHandler mMainThreadHandler; 151ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville private SubscriptionController mSubscriptionController; 1523ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville private SharedPreferences mTelephonySharedPreferences; 1537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15497ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_"; 15597ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_"; 15685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_"; 157df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee private static final String PREF_ENABLE_VIDEO_CALLING = "enable_video_calling"; 15889e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan 15989e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan /** 160566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal * A request object to use for transmitting data to an ICC. 161566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal */ 162566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal private static final class IccAPDUArgument { 163566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public int channel, cla, command, p1, p2, p3; 164566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public String data; 165566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 166566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public IccAPDUArgument(int channel, int cla, int command, 167566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal int p1, int p2, int p3, String data) { 168566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.channel = channel; 169566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.cla = cla; 170566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.command = command; 171566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.p1 = p1; 172566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.p2 = p2; 173566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.p3 = p3; 174566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal this.data = data; 175566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 176566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 177566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 178566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal /** 17977ba317277863812508869705308373b42364e0aShishir Agrawal * A request object to use for transmitting data to an ICC. 18077ba317277863812508869705308373b42364e0aShishir Agrawal */ 18177ba317277863812508869705308373b42364e0aShishir Agrawal private static final class ManualNetworkSelectionArgument { 18277ba317277863812508869705308373b42364e0aShishir Agrawal public OperatorInfo operatorInfo; 18377ba317277863812508869705308373b42364e0aShishir Agrawal public boolean persistSelection; 18477ba317277863812508869705308373b42364e0aShishir Agrawal 18577ba317277863812508869705308373b42364e0aShishir Agrawal public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) { 18677ba317277863812508869705308373b42364e0aShishir Agrawal this.operatorInfo = operatorInfo; 18777ba317277863812508869705308373b42364e0aShishir Agrawal this.persistSelection = persistSelection; 18877ba317277863812508869705308373b42364e0aShishir Agrawal } 18977ba317277863812508869705308373b42364e0aShishir Agrawal } 19077ba317277863812508869705308373b42364e0aShishir Agrawal 19177ba317277863812508869705308373b42364e0aShishir Agrawal /** 1927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the 1937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * request after sending. The main thread will notify the request when it is complete. 1947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 1957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final class MainThreadRequest { 1967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The argument to use for the request */ 1977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public Object argument; 1987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The result of the request that is run on the main thread */ 1997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public Object result; 20076d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal /** The subscriber id that this request applies to. Null if default. */ 20176d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal public Integer subId; 2027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public MainThreadRequest(Object argument) { 2047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon this.argument = argument; 2057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 20676d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal 20776d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal public MainThreadRequest(Object argument, Integer subId) { 20876d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal this.argument = argument; 20976d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal this.subId = subId; 21076d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal } 2117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 213cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal private static final class IncomingThirdPartyCallArgs { 214cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public final ComponentName component; 215cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public final String callId; 216cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public final String callerDisplayName; 217cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal 218cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal public IncomingThirdPartyCallArgs(ComponentName component, String callId, 219cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal String callerDisplayName) { 220cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal this.component = component; 221cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal this.callId = callId; 222cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal this.callerDisplayName = callerDisplayName; 223cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal } 224cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal } 225cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal 2267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 2277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * A handler that processes messages on the main thread in the phone process. Since many 2287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * of the Phone calls are not thread safe this is needed to shuttle the requests from the 2297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * inbound binder threads to the main thread in the phone process. The Binder thread 2307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting 2317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * on, which will be notified when the operation completes and will contain the result of the 2327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * request. 2337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 2347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * <p>If a MainThreadRequest object is provided in the msg.obj field, 2357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * note that request.result must be set to something non-null for the calling thread to 2367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * unblock. 2377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 2387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private final class MainThreadHandler extends Handler { 2397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 2407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void handleMessage(Message msg) { 2417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon MainThreadRequest request; 2427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message onCompleted; 2437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AsyncResult ar; 24421409250c4001605606a37c3903dc22805410900Shishir Agrawal UiccCard uiccCard = UiccController.getInstance().getUiccCard(mPhone.getPhoneId()); 245da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccAPDUArgument iccArgument; 2467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon switch (msg.what) { 248716f67e149e8defd72262b7e7f875ea2aef57652Yorke Lee case CMD_HANDLE_PIN_MMI: { 2497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) msg.obj; 250716f67e149e8defd72262b7e7f875ea2aef57652Yorke Lee final Phone phone = getPhoneFromRequest(request); 251716f67e149e8defd72262b7e7f875ea2aef57652Yorke Lee request.result = phone != null ? 252716f67e149e8defd72262b7e7f875ea2aef57652Yorke Lee getPhoneFromRequest(request).handlePinMmi((String) request.argument) 253716f67e149e8defd72262b7e7f875ea2aef57652Yorke Lee : false; 2547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wake up the requesting thread 2557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 2567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.notifyAll(); 2577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 259716f67e149e8defd72262b7e7f875ea2aef57652Yorke Lee } 2607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_HANDLE_NEIGHBORING_CELL: 2627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) msg.obj; 2637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onCompleted = obtainMessage(EVENT_NEIGHBORING_CELL_DONE, 2647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request); 2657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.getNeighboringCids(onCompleted); 2667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case EVENT_NEIGHBORING_CELL_DONE: 2697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ar = (AsyncResult) msg.obj; 2707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) ar.userObj; 2717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (ar.exception == null && ar.result != null) { 2727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.result = ar.result; 2737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 2747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // create an empty list to notify the waiting thread 275e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = new ArrayList<NeighboringCellInfo>(0); 2767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wake up the requesting thread 2787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 2797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.notifyAll(); 2807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_ANSWER_RINGING_CALL: 2840887461919173015886ea69ef6c6afbe20ebf1dcWink Saville request = (MainThreadRequest) msg.obj; 285584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott int answer_subId = request.subId; 2860887461919173015886ea69ef6c6afbe20ebf1dcWink Saville answerRingingCallInternal(answer_subId); 2877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_END_CALL: 2907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) msg.obj; 291584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott int end_subId = request.subId; 2920887461919173015886ea69ef6c6afbe20ebf1dcWink Saville final boolean hungUp; 293ae4e36d0e6edc3a912e822e844ab362dd7469491Anthony Lee Phone phone = getPhone(end_subId); 294ae4e36d0e6edc3a912e822e844ab362dd7469491Anthony Lee if (phone == null) { 295ae4e36d0e6edc3a912e822e844ab362dd7469491Anthony Lee if (DBG) log("CMD_END_CALL: no phone for id: " + end_subId); 296ae4e36d0e6edc3a912e822e844ab362dd7469491Anthony Lee break; 297ae4e36d0e6edc3a912e822e844ab362dd7469491Anthony Lee } 298ae4e36d0e6edc3a912e822e844ab362dd7469491Anthony Lee int phoneType = phone.getPhoneType(); 2997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { 3007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // CDMA: If the user presses the Power button we treat it as 3017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ending the complete call session 3020887461919173015886ea69ef6c6afbe20ebf1dcWink Saville hungUp = PhoneUtils.hangupRingingAndActive(getPhone(end_subId)); 3037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) { 3047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // GSM: End the call as per the Phone state 3057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon hungUp = PhoneUtils.hangup(mCM); 3067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 3077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon throw new IllegalStateException("Unexpected phone type: " + phoneType); 3087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("CMD_END_CALL: " + (hungUp ? "hung up!" : "no call to hang up")); 3107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.result = hungUp; 3117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wake up the requesting thread 3127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 3137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.notifyAll(); 3147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 3167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 317da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL: 318566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) msg.obj; 319da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument = (IccAPDUArgument) request.argument; 320eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (uiccCard == null) { 321eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("iccTransmitApduLogicalChannel: No UICC"); 322eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 323eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal synchronized (request) { 324eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.notifyAll(); 325eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 326eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } else { 327da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE, 328da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request); 329eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal uiccCard.iccTransmitApduLogicalChannel( 330da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument.channel, iccArgument.cla, iccArgument.command, 331da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data, 332566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal onCompleted); 333eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 334566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 335566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 336da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE: 337566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal ar = (AsyncResult) msg.obj; 338566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) ar.userObj; 339566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.exception == null && ar.result != null) { 340566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.result = ar.result; 341566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 342566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 343566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.result == null) { 344566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccTransmitApduLogicalChannel: Empty response"); 345e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else if (ar.exception instanceof CommandException) { 346566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccTransmitApduLogicalChannel: CommandException: " + 347e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby ar.exception); 348566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 349566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccTransmitApduLogicalChannel: Unknown exception"); 350566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 351566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 352566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal synchronized (request) { 353566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.notifyAll(); 354566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 355566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 356566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 357da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal case CMD_TRANSMIT_APDU_BASIC_CHANNEL: 358da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request = (MainThreadRequest) msg.obj; 359da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument = (IccAPDUArgument) request.argument; 360da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (uiccCard == null) { 361da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal loge("iccTransmitApduBasicChannel: No UICC"); 362da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 363da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal synchronized (request) { 364da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.notifyAll(); 365da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 366da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else { 367da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE, 368da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request); 369da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal uiccCard.iccTransmitApduBasicChannel( 370da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2, 371da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument.p3, iccArgument.data, onCompleted); 372da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 373da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal break; 374da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 375da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE: 376da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal ar = (AsyncResult) msg.obj; 377da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request = (MainThreadRequest) ar.userObj; 378da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (ar.exception == null && ar.result != null) { 379da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.result = ar.result; 380da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else { 381da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 382da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (ar.result == null) { 383da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal loge("iccTransmitApduBasicChannel: Empty response"); 384da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else if (ar.exception instanceof CommandException) { 385da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal loge("iccTransmitApduBasicChannel: CommandException: " + 386da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal ar.exception); 387da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else { 388da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal loge("iccTransmitApduBasicChannel: Unknown exception"); 389da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 390da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 391da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal synchronized (request) { 392da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.notifyAll(); 393da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 394da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal break; 395da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 396da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal case CMD_EXCHANGE_SIM_IO: 397da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request = (MainThreadRequest) msg.obj; 398da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument = (IccAPDUArgument) request.argument; 399da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (uiccCard == null) { 400da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal loge("iccExchangeSimIO: No UICC"); 401da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 402da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal synchronized (request) { 403da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.notifyAll(); 404da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 405da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else { 406da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE, 407da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request); 408da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */ 409da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3, 410da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal iccArgument.data, onCompleted); 411da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 412da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal break; 413da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 414da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal case EVENT_EXCHANGE_SIM_IO_DONE: 415da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal ar = (AsyncResult) msg.obj; 416da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request = (MainThreadRequest) ar.userObj; 417da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (ar.exception == null && ar.result != null) { 418da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.result = ar.result; 419da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else { 420da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.result = new IccIoResult(0x6f, 0, (byte[])null); 421da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 422da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal synchronized (request) { 423da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal request.notifyAll(); 424da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 425da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal break; 426da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 4274d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan case CMD_SEND_ENVELOPE: 4284d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan request = (MainThreadRequest) msg.obj; 429eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (uiccCard == null) { 430eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("sendEnvelopeWithStatus: No UICC"); 431eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 432eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal synchronized (request) { 433eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.notifyAll(); 434eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 435eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } else { 436eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request); 437eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted); 438eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 4394d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan break; 4404d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan 4414d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan case EVENT_SEND_ENVELOPE_DONE: 4424d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan ar = (AsyncResult) msg.obj; 4434d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan request = (MainThreadRequest) ar.userObj; 4449f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal if (ar.exception == null && ar.result != null) { 4459f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal request.result = ar.result; 4464d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan } else { 4479f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 4489f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal if (ar.result == null) { 4499f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal loge("sendEnvelopeWithStatus: Empty response"); 4509f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal } else if (ar.exception instanceof CommandException) { 4519f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal loge("sendEnvelopeWithStatus: CommandException: " + 4529f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal ar.exception); 4539f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal } else { 4549f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal loge("sendEnvelopeWithStatus: exception:" + ar.exception); 4559f9877db9261aac66cfabf85b745440cfd970b9cShishir Agrawal } 4564d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan } 4574d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan synchronized (request) { 4584d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan request.notifyAll(); 4594d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan } 4604d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan break; 4614d5e5c1b4742ed532fd2963e3d08b913ac565d16Derek Tan 462566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case CMD_OPEN_CHANNEL: 463566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) msg.obj; 464eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (uiccCard == null) { 465eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("iccOpenLogicalChannel: No UICC"); 466eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 467eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal synchronized (request) { 468eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.notifyAll(); 469eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 470eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } else { 471eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request); 472eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal uiccCard.iccOpenLogicalChannel((String)request.argument, onCompleted); 473eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 474566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 475566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 476566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case EVENT_OPEN_CHANNEL_DONE: 477566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal ar = (AsyncResult) msg.obj; 478566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) ar.userObj; 479da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccOpenLogicalChannelResponse openChannelResp; 480566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.exception == null && ar.result != null) { 481da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal int[] result = (int[]) ar.result; 482da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal int channelId = result[0]; 483da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal byte[] selectResponse = null; 484da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (result.length > 1) { 485da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal selectResponse = new byte[result.length - 1]; 486da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal for (int i = 1; i < result.length; ++i) { 487da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal selectResponse[i - 1] = (byte) result[i]; 488da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 489da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 490da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal openChannelResp = new IccOpenLogicalChannelResponse(channelId, 491527e8bf2bd43c5bfdb2ac7ea8cf05413c1faaeb5Shishir Agrawal IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse); 492566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 493566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (ar.result == null) { 494566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal loge("iccOpenLogicalChannel: Empty response"); 495566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 496da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (ar.exception != null) { 497da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal loge("iccOpenLogicalChannel: Exception: " + ar.exception); 498da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 499da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 500527e8bf2bd43c5bfdb2ac7ea8cf05413c1faaeb5Shishir Agrawal int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR; 501a754ba14f729744f3261113d5e355b86d5c846d3Junda Liu if (ar.exception instanceof CommandException) { 502a754ba14f729744f3261113d5e355b86d5c846d3Junda Liu CommandException.Error error = 503a754ba14f729744f3261113d5e355b86d5c846d3Junda Liu ((CommandException) (ar.exception)).getCommandError(); 504a754ba14f729744f3261113d5e355b86d5c846d3Junda Liu if (error == CommandException.Error.MISSING_RESOURCE) { 505527e8bf2bd43c5bfdb2ac7ea8cf05413c1faaeb5Shishir Agrawal errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE; 506a754ba14f729744f3261113d5e355b86d5c846d3Junda Liu } else if (error == CommandException.Error.NO_SUCH_ELEMENT) { 507527e8bf2bd43c5bfdb2ac7ea8cf05413c1faaeb5Shishir Agrawal errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT; 508da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 509da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 510da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal openChannelResp = new IccOpenLogicalChannelResponse( 511da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null); 512566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 51382c8a46052629d1450320c116d14c7353bfe4ea1Shishir Agrawal request.result = openChannelResp; 514566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal synchronized (request) { 515566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.notifyAll(); 516566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 517566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 518566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 519566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case CMD_CLOSE_CHANNEL: 520566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) msg.obj; 521eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (uiccCard == null) { 522eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("iccCloseLogicalChannel: No UICC"); 523eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.result = new IccIoResult(0x6F, 0, (byte[])null); 524eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal synchronized (request) { 525eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal request.notifyAll(); 526eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 527eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } else { 528eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request); 529eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted); 530eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 531566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 532566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 533566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal case EVENT_CLOSE_CHANNEL_DONE: 534e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "iccCloseLogicalChannel"); 535e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 536e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 537e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_READ_ITEM: 538e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 539e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request); 540e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvReadItem((Integer) request.argument, onCompleted); 541e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 542e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 543e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_READ_ITEM_DONE: 544566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal ar = (AsyncResult) msg.obj; 545566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request = (MainThreadRequest) ar.userObj; 546e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.exception == null && ar.result != null) { 547e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = ar.result; // String 548566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 549e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = ""; 550e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.result == null) { 551e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge("nvReadItem: Empty response"); 552e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else if (ar.exception instanceof CommandException) { 553e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge("nvReadItem: CommandException: " + 554e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby ar.exception); 555566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } else { 556e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge("nvReadItem: Unknown exception"); 557566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 558566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 559566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal synchronized (request) { 560566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal request.notifyAll(); 561566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 562566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal break; 563566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 564e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_WRITE_ITEM: 565e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 566e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request); 567e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument; 568e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvWriteItem(idValue.first, idValue.second, onCompleted); 569e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 570e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 571e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_WRITE_ITEM_DONE: 572e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "nvWriteItem"); 573e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 574e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 575e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_WRITE_CDMA_PRL: 576e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 577e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request); 578e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted); 579e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 580e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 581e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_WRITE_CDMA_PRL_DONE: 582e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "nvWriteCdmaPrl"); 583e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 584e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 585e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case CMD_NV_RESET_CONFIG: 586e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request = (MainThreadRequest) msg.obj; 587e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby onCompleted = obtainMessage(EVENT_NV_RESET_CONFIG_DONE, request); 588e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby mPhone.nvResetConfig((Integer) request.argument, onCompleted); 589e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 590e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 591e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby case EVENT_NV_RESET_CONFIG_DONE: 592e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby handleNullReturnEvent(msg, "nvResetConfig"); 593e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby break; 594e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 5957c27be317e8757948178815426d3a329c852b9eeJake Hamby case CMD_GET_PREFERRED_NETWORK_TYPE: 5967c27be317e8757948178815426d3a329c852b9eeJake Hamby request = (MainThreadRequest) msg.obj; 5977c27be317e8757948178815426d3a329c852b9eeJake Hamby onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request); 59854788801de04c603a856596f4ae4377ab77a9821Stuart Scott getPhoneFromRequest(request).getPreferredNetworkType(onCompleted); 5997c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 6007c27be317e8757948178815426d3a329c852b9eeJake Hamby 6017c27be317e8757948178815426d3a329c852b9eeJake Hamby case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE: 6027c27be317e8757948178815426d3a329c852b9eeJake Hamby ar = (AsyncResult) msg.obj; 6037c27be317e8757948178815426d3a329c852b9eeJake Hamby request = (MainThreadRequest) ar.userObj; 6047c27be317e8757948178815426d3a329c852b9eeJake Hamby if (ar.exception == null && ar.result != null) { 6057c27be317e8757948178815426d3a329c852b9eeJake Hamby request.result = ar.result; // Integer 6067c27be317e8757948178815426d3a329c852b9eeJake Hamby } else { 6077c27be317e8757948178815426d3a329c852b9eeJake Hamby request.result = -1; 6087c27be317e8757948178815426d3a329c852b9eeJake Hamby if (ar.result == null) { 6097c27be317e8757948178815426d3a329c852b9eeJake Hamby loge("getPreferredNetworkType: Empty response"); 6107c27be317e8757948178815426d3a329c852b9eeJake Hamby } else if (ar.exception instanceof CommandException) { 6117c27be317e8757948178815426d3a329c852b9eeJake Hamby loge("getPreferredNetworkType: CommandException: " + 6127c27be317e8757948178815426d3a329c852b9eeJake Hamby ar.exception); 6137c27be317e8757948178815426d3a329c852b9eeJake Hamby } else { 6147c27be317e8757948178815426d3a329c852b9eeJake Hamby loge("getPreferredNetworkType: Unknown exception"); 6157c27be317e8757948178815426d3a329c852b9eeJake Hamby } 6167c27be317e8757948178815426d3a329c852b9eeJake Hamby } 6177c27be317e8757948178815426d3a329c852b9eeJake Hamby synchronized (request) { 6187c27be317e8757948178815426d3a329c852b9eeJake Hamby request.notifyAll(); 6197c27be317e8757948178815426d3a329c852b9eeJake Hamby } 6207c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 6217c27be317e8757948178815426d3a329c852b9eeJake Hamby 6227c27be317e8757948178815426d3a329c852b9eeJake Hamby case CMD_SET_PREFERRED_NETWORK_TYPE: 6237c27be317e8757948178815426d3a329c852b9eeJake Hamby request = (MainThreadRequest) msg.obj; 6247c27be317e8757948178815426d3a329c852b9eeJake Hamby onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request); 6257c27be317e8757948178815426d3a329c852b9eeJake Hamby int networkType = (Integer) request.argument; 62654788801de04c603a856596f4ae4377ab77a9821Stuart Scott getPhoneFromRequest(request).setPreferredNetworkType(networkType, onCompleted); 6277c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 6287c27be317e8757948178815426d3a329c852b9eeJake Hamby 6297c27be317e8757948178815426d3a329c852b9eeJake Hamby case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE: 6307c27be317e8757948178815426d3a329c852b9eeJake Hamby handleNullReturnEvent(msg, "setPreferredNetworkType"); 6317c27be317e8757948178815426d3a329c852b9eeJake Hamby break; 6327c27be317e8757948178815426d3a329c852b9eeJake Hamby 6334bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu case CMD_INVOKE_OEM_RIL_REQUEST_RAW: 6344bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu request = (MainThreadRequest)msg.obj; 6354bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request); 6364bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu mPhone.invokeOemRilRequestRaw((byte[])request.argument, onCompleted); 6374bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu break; 6384bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu 6394bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE: 6404bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu ar = (AsyncResult)msg.obj; 6414bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu request = (MainThreadRequest)ar.userObj; 6424bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu request.result = ar; 6434bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu synchronized (request) { 6444bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu request.notifyAll(); 6454bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } 6464bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu break; 6474bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu 64876d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal case CMD_SET_VOICEMAIL_NUMBER: 64976d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal request = (MainThreadRequest) msg.obj; 65076d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request); 65176d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal Pair<String, String> tagNum = (Pair<String, String>) request.argument; 652584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second, 653584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott onCompleted); 65476d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal break; 65576d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal 65676d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal case EVENT_SET_VOICEMAIL_NUMBER_DONE: 65776d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal handleNullReturnEvent(msg, "setVoicemailNumber"); 65876d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal break; 65976d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal 66054788801de04c603a856596f4ae4377ab77a9821Stuart Scott case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC: 66154788801de04c603a856596f4ae4377ab77a9821Stuart Scott request = (MainThreadRequest) msg.obj; 66254788801de04c603a856596f4ae4377ab77a9821Stuart Scott onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE, 66354788801de04c603a856596f4ae4377ab77a9821Stuart Scott request); 66454788801de04c603a856596f4ae4377ab77a9821Stuart Scott getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted); 66554788801de04c603a856596f4ae4377ab77a9821Stuart Scott break; 66654788801de04c603a856596f4ae4377ab77a9821Stuart Scott 66754788801de04c603a856596f4ae4377ab77a9821Stuart Scott case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE: 66854788801de04c603a856596f4ae4377ab77a9821Stuart Scott handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic"); 66954788801de04c603a856596f4ae4377ab77a9821Stuart Scott break; 67054788801de04c603a856596f4ae4377ab77a9821Stuart Scott 671302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal case CMD_PERFORM_NETWORK_SCAN: 672302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal request = (MainThreadRequest) msg.obj; 673302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request); 674302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal getPhoneFromRequest(request).getAvailableNetworks(onCompleted); 675302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal break; 676302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal 677302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal case EVENT_PERFORM_NETWORK_SCAN_DONE: 678302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal ar = (AsyncResult) msg.obj; 679302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal request = (MainThreadRequest) ar.userObj; 680302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal CellNetworkScanResult cellScanResult; 681302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal if (ar.exception == null && ar.result != null) { 682302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal cellScanResult = new CellNetworkScanResult( 683302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal CellNetworkScanResult.STATUS_SUCCESS, 684302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal (List<OperatorInfo>) ar.result); 685302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal } else { 686302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal if (ar.result == null) { 687302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal loge("getCellNetworkScanResults: Empty response"); 688302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal } 689302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal if (ar.exception != null) { 690302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal loge("getCellNetworkScanResults: Exception: " + ar.exception); 691302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal } 692302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR; 693302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal if (ar.exception instanceof CommandException) { 694302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal CommandException.Error error = 695302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal ((CommandException) (ar.exception)).getCommandError(); 696302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal if (error == CommandException.Error.RADIO_NOT_AVAILABLE) { 697302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE; 698302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal } else if (error == CommandException.Error.GENERIC_FAILURE) { 699302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE; 700302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal } 701302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal } 702302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal cellScanResult = new CellNetworkScanResult(errorCode, null); 703302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal } 704302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal request.result = cellScanResult; 705302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal synchronized (request) { 706302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal request.notifyAll(); 707302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal } 708302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal break; 709302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal 710302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal case CMD_SET_NETWORK_SELECTION_MODE_MANUAL: 711302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal request = (MainThreadRequest) msg.obj; 71277ba317277863812508869705308373b42364e0aShishir Agrawal ManualNetworkSelectionArgument selArg = 71377ba317277863812508869705308373b42364e0aShishir Agrawal (ManualNetworkSelectionArgument) request.argument; 714302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE, 715302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal request); 71677ba317277863812508869705308373b42364e0aShishir Agrawal getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo, 71777ba317277863812508869705308373b42364e0aShishir Agrawal selArg.persistSelection, onCompleted); 718302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal break; 719302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal 720302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE: 721302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal handleNullReturnEvent(msg, "setNetworkSelectionModeManual"); 722302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal break; 723302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal 7247fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham case CMD_GET_MODEM_ACTIVITY_INFO: 7257fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham request = (MainThreadRequest) msg.obj; 7267fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request); 72761a60ad2e6944a80944898e636c2e9d9fd7b0e70Prerepa Viswanadham mPhone.getModemActivityInfo(onCompleted); 7287fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham break; 7297fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham 7307fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham case EVENT_GET_MODEM_ACTIVITY_INFO_DONE: 7317fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham ar = (AsyncResult) msg.obj; 7327fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham request = (MainThreadRequest) ar.userObj; 7337fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham if (ar.exception == null && ar.result != null) { 7347fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham request.result = ar.result; 7357fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham } else { 7367fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham if (ar.result == null) { 7377fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham loge("queryModemActivityInfo: Empty response"); 7387fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham } else if (ar.exception instanceof CommandException) { 7397fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham loge("queryModemActivityInfo: CommandException: " + 7407fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham ar.exception); 7417fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham } else { 7427fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham loge("queryModemActivityInfo: Unknown exception"); 7437fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham } 7447fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham } 7457fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham synchronized (request) { 7467fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham request.notifyAll(); 7477fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham } 7487fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham break; 7497fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham 7507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon default: 7517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what); 7527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 7537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 755e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 756e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private void handleNullReturnEvent(Message msg, String command) { 757e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby AsyncResult ar = (AsyncResult) msg.obj; 758e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby MainThreadRequest request = (MainThreadRequest) ar.userObj; 759e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.exception == null) { 760e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = true; 761e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else { 762e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.result = false; 763e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (ar.exception instanceof CommandException) { 764e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge(command + ": CommandException: " + ar.exception); 765e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } else { 766e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby loge(command + ": Unknown exception"); 767e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 768e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 769e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby synchronized (request) { 770e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby request.notifyAll(); 771e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 772e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 7737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 7767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Posts the specified command to be executed on the main thread, 7777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * waits for the request to complete, and returns the result. 7787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #sendRequestAsync 7797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 7807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Object sendRequest(int command, Object argument) { 781500b0e04406d2995c1f29dea95c98cedaa669f74Santos Cordon return sendRequest(command, argument, null); 78236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 78336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 78436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 78536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Posts the specified command to be executed on the main thread, 78636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * waits for the request to complete, and returns the result. 78736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * @see #sendRequestAsync 78836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 78976d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal private Object sendRequest(int command, Object argument, Integer subId) { 7907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (Looper.myLooper() == mMainThreadHandler.getLooper()) { 7917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon throw new RuntimeException("This method will deadlock if called from the main thread."); 7927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 79476d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal MainThreadRequest request = new MainThreadRequest(argument, subId); 7957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message msg = mMainThreadHandler.obtainMessage(command, request); 7967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon msg.sendToTarget(); 7977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wait for the request to complete 7997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 8007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon while (request.result == null) { 8017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 8027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.wait(); 8037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 8047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Do nothing, go back and wait until the request is complete 8057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return request.result; 8097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 8127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Asynchronous ("fire and forget") version of sendRequest(): 8137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Posts the specified command to be executed on the main thread, and 8147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * returns immediately. 8157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #sendRequest 8167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 8177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void sendRequestAsync(int command) { 8187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mMainThreadHandler.sendEmptyMessage(command); 8197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 822bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal * Same as {@link #sendRequestAsync(int)} except it takes an argument. 823bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal * @see {@link #sendRequest(int,Object)} 824bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal */ 825bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal private void sendRequestAsync(int command, Object argument) { 826bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal MainThreadRequest request = new MainThreadRequest(argument); 827bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal Message msg = mMainThreadHandler.obtainMessage(command, request); 828bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal msg.sendToTarget(); 829bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal } 830bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal 831bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal /** 8327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Initialize the singleton PhoneInterfaceManager instance. 8337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This is only done once, at startup, from PhoneApp.onCreate(). 8347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 835194161ed3aef6bdeeecd6153403269bbd01314a5Sailesh Nepal /* package */ static PhoneInterfaceManager init(PhoneGlobals app, Phone phone) { 8367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (PhoneInterfaceManager.class) { 8377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (sInstance == null) { 838194161ed3aef6bdeeecd6153403269bbd01314a5Sailesh Nepal sInstance = new PhoneInterfaceManager(app, phone); 8397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 8407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance); 8417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return sInstance; 8437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** Private constructor; @see init() */ 847194161ed3aef6bdeeecd6153403269bbd01314a5Sailesh Nepal private PhoneInterfaceManager(PhoneGlobals app, Phone phone) { 8487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp = app; 8497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone = phone; 8507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCM = PhoneGlobals.getInstance().mCM; 851981d85874294656a51683ae6ecc6ba312d3635ceStuart Scott mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE); 8527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE); 8537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mMainThreadHandler = new MainThreadHandler(); 854df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee mTelephonySharedPreferences = 85597ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan PreferenceManager.getDefaultSharedPreferences(mPhone.getContext()); 856ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville mSubscriptionController = SubscriptionController.getInstance(); 8573ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville 8587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon publish(); 8597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void publish() { 8627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("publish: " + this); 8637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ServiceManager.addService("phone", this); 8657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 867584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott private Phone getPhoneFromRequest(MainThreadRequest request) { 868584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott return (request.subId == null) ? mPhone : getPhone(request.subId); 869584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott } 870584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott 87136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // returns phone associated with the subId. 872b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville private Phone getPhone(int subId) { 873ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId)); 87436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 8757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 8767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Implementation of the ITelephony interface. 8777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 8787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void dial(String number) { 880add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville dialForSubscriber(getPreferredVoiceSubscription(), number); 88136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 88236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 883b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public void dialForSubscriber(int subId, String number) { 8847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("dial: " + number); 8857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No permission check needed here: This is just a wrapper around the 8867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ACTION_DIAL intent, which is available to any app since it puts up 8877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the UI before it does anything. 8887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon String url = createTelUrl(number); 8907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (url == null) { 8917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 8927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // PENDING: should we just silently fail if phone is offhook or ringing? 89536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville PhoneConstants.State state = mCM.getState(subId); 8967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) { 8977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url)); 8987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.startActivity(intent); 9007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void call(String callingPackage, String number) { 904add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number); 90536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 90636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 907b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public void callForSubscriber(int subId, String callingPackage, String number) { 9087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("call: " + number); 9097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // This is just a wrapper around the ACTION_CALL intent, but we still 9117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // need to do a permission check since we're calling startActivity() 9127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // from the context of the phone app. 9137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceCallPermission(); 9147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mAppOps.noteOp(AppOpsManager.OP_CALL_PHONE, Binder.getCallingUid(), callingPackage) 9167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon != AppOpsManager.MODE_ALLOWED) { 9177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 9187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon String url = createTelUrl(number); 9217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (url == null) { 9227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 9237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9250887461919173015886ea69ef6c6afbe20ebf1dcWink Saville boolean isValid = false; 9261c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath final List<SubscriptionInfo> slist = getActiveSubscriptionInfoList(); 9273ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville if (slist != null) { 9283ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville for (SubscriptionInfo subInfoRecord : slist) { 9293ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville if (subInfoRecord.getSubscriptionId() == subId) { 9303ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville isValid = true; 9313ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville break; 9323ab207e3711ebd717f9cfe7412018c51ae1c8131Wink Saville } 9330887461919173015886ea69ef6c6afbe20ebf1dcWink Saville } 9340887461919173015886ea69ef6c6afbe20ebf1dcWink Saville } 9350887461919173015886ea69ef6c6afbe20ebf1dcWink Saville if (isValid == false) { 9360887461919173015886ea69ef6c6afbe20ebf1dcWink Saville return; 9370887461919173015886ea69ef6c6afbe20ebf1dcWink Saville } 9380887461919173015886ea69ef6c6afbe20ebf1dcWink Saville 9397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url)); 94036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville intent.putExtra(SUBSCRIPTION_KEY, subId); 9417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 9427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.startActivity(intent); 9437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 9467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * End a call based on call state 9477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return true is a call was ended 9487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 9497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean endCall() { 950add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return endCallForSubscriber(getDefaultSubscription()); 95136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 95236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 95336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 95436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * End a call based on the call state of the subId 95536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * @return true is a call was ended 95636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 957b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public boolean endCallForSubscriber(int subId) { 9587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceCallPermission(); 959584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott return (Boolean) sendRequest(CMD_END_CALL, null, new Integer(subId)); 9607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void answerRingingCall() { 963add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville answerRingingCallForSubscriber(getDefaultSubscription()); 96436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 96536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 966b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public void answerRingingCallForSubscriber(int subId) { 9677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("answerRingingCall..."); 9687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: there should eventually be a separate "ANSWER_PHONE" permission, 9697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // but that can probably wait till the big TelephonyManager API overhaul. 9707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For now, protect this call with the MODIFY_PHONE_STATE permission. 9717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 972584921cffac3dc8e7fa3bdeb5a87d764cc0cd77dStuart Scott sendRequest(CMD_ANSWER_RINGING_CALL, null, new Integer(subId)); 9737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 9767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make the actual telephony calls to implement answerRingingCall(). 9777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This should only be called from the main thread of the Phone app. 9787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #answerRingingCall 9797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 9807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * TODO: it would be nice to return true if we answered the call, or 9817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * false if there wasn't actually a ringing incoming call, or some 9827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * other error occurred. (In other words, pass back the return value 9837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * from PhoneUtils.answerCall() or PhoneUtils.answerAndEndActive().) 9847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * But that would require calling this method via sendRequest() rather 9857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * than sendRequestAsync(), and right now we don't actually *need* that 9867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * return value, so let's just return void for now. 9877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 988b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville private void answerRingingCallInternal(int subId) { 9890887461919173015886ea69ef6c6afbe20ebf1dcWink Saville final boolean hasRingingCall = !getPhone(subId).getRingingCall().isIdle(); 9907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (hasRingingCall) { 9910887461919173015886ea69ef6c6afbe20ebf1dcWink Saville final boolean hasActiveCall = !getPhone(subId).getForegroundCall().isIdle(); 9920887461919173015886ea69ef6c6afbe20ebf1dcWink Saville final boolean hasHoldingCall = !getPhone(subId).getBackgroundCall().isIdle(); 9937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (hasActiveCall && hasHoldingCall) { 9947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Both lines are in use! 9957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: provide a flag to let the caller specify what 9967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // policy to use if both lines are in use. (The current 9977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // behavior is hardwired to "answer incoming, end ongoing", 9987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // which is how the CALL button is specced to behave.) 9997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.answerAndEndActive(mCM, mCM.getFirstActiveRingingCall()); 10007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 10017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 10027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // answerCall() will automatically hold the current active 10037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // call, if there is one. 10047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.answerCall(mCM.getFirstActiveRingingCall()); 10057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 10067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 10087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No call was ringing. 10097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 10107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 10145422a8deb513e4466ec6cc1e640895a6b536fee0Santos Cordon * This method is no longer used and can be removed once TelephonyManager stops referring to it. 10157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 10165422a8deb513e4466ec6cc1e640895a6b536fee0Santos Cordon public void silenceRinger() { 10175422a8deb513e4466ec6cc1e640895a6b536fee0Santos Cordon Log.e(LOG_TAG, "silenseRinger not supported"); 10187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 102036b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt @Override 102136b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public boolean isOffhook(String callingPackage) { 102236b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return isOffhookForSubscriber(getDefaultSubscription(), callingPackage); 102336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 102436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 102536b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt @Override 102636b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public boolean isOffhookForSubscriber(int subId, String callingPackage) { 102736b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt if (!canReadPhoneState(callingPackage, "isOffhookForSubscriber")) { 102836b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return false; 102936b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt } 103036b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt 1031356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1032356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1033356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return (phone.getState() == PhoneConstants.State.OFFHOOK); 1034356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1035356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return false; 1036356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 10377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 103936b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt @Override 104036b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public boolean isRinging(String callingPackage) { 104136b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return (isRingingForSubscriber(getDefaultSubscription(), callingPackage)); 104236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 104336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 104436b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt @Override 104536b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public boolean isRingingForSubscriber(int subId, String callingPackage) { 104636b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt if (!canReadPhoneState(callingPackage, "isRingingForSubscriber")) { 104736b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return false; 104836b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt } 104936b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt 1050356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1051356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1052356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return (phone.getState() == PhoneConstants.State.RINGING); 1053356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1054356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return false; 1055356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 10567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 105836b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt @Override 105936b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public boolean isIdle(String callingPackage) { 106036b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return isIdleForSubscriber(getDefaultSubscription(), callingPackage); 106136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 106236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 106336b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt @Override 106436b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public boolean isIdleForSubscriber(int subId, String callingPackage) { 106536b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt if (!canReadPhoneState(callingPackage, "isIdleForSubscriber")) { 106636b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return false; 106736b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt } 106836b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt 1069356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1070356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1071356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return (phone.getState() == PhoneConstants.State.IDLE); 1072356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1073356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return false; 1074356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 10757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1077b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov public boolean isSimPinEnabled(String callingPackage) { 1078b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov if (!canReadPhoneState(callingPackage, "isSimPinEnabled")) { 1079b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov return false; 1080b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov } 1081b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov 10827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return (PhoneGlobals.getInstance().isSimPinEnabled()); 10837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean supplyPin(String pin) { 1086add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return supplyPinForSubscriber(getDefaultSubscription(), pin); 108736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 108836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1089b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public boolean supplyPinForSubscriber(int subId, String pin) { 1090add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville int [] resultArray = supplyPinReportResultForSubscriber(subId, pin); 10919de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false; 10929de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 10939de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville 10949de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville public boolean supplyPuk(String puk, String pin) { 1095add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return supplyPukForSubscriber(getDefaultSubscription(), puk, pin); 109636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 109736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1098b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public boolean supplyPukForSubscriber(int subId, String puk, String pin) { 1099add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin); 11009de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false; 11019de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 11029de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville 11039de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville /** {@hide} */ 11049de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville public int[] supplyPinReportResult(String pin) { 1105add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return supplyPinReportResultForSubscriber(getDefaultSubscription(), pin); 110636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 110736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1108b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public int[] supplyPinReportResultForSubscriber(int subId, String pin) { 11097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 111036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard()); 11117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon checkSimPin.start(); 11127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return checkSimPin.unlockSim(null, pin); 11137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11159de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville /** {@hide} */ 11169de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville public int[] supplyPukReportResult(String puk, String pin) { 1117add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return supplyPukReportResultForSubscriber(getDefaultSubscription(), puk, pin); 111836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 111936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1120b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) { 11217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 112236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard()); 11237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon checkSimPuk.start(); 11247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return checkSimPuk.unlockSim(puk, pin); 11257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 11289de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville * Helper thread to turn async call to SimCard#supplyPin into 11297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * a synchronous one. 11307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 11317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static class UnlockSim extends Thread { 11327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private final IccCard mSimCard; 11347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private boolean mDone = false; 11369de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville private int mResult = PhoneConstants.PIN_GENERAL_FAILURE; 11379de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville private int mRetryCount = -1; 11387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For replies from SimCard interface 11407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Handler mHandler; 11417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For async handler to identify request type 11437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int SUPPLY_PIN_COMPLETE = 100; 11447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public UnlockSim(IccCard simCard) { 11467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSimCard = simCard; 11477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 11507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void run() { 11517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Looper.prepare(); 11527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (UnlockSim.this) { 11537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mHandler = new Handler() { 11547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 11557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void handleMessage(Message msg) { 11567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AsyncResult ar = (AsyncResult) msg.obj; 11577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon switch (msg.what) { 11587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case SUPPLY_PIN_COMPLETE: 11597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE"); 11607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (UnlockSim.this) { 11619de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mRetryCount = msg.arg1; 11629de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville if (ar.exception != null) { 11639de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville if (ar.exception instanceof CommandException && 11649de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville ((CommandException)(ar.exception)).getCommandError() 11659de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville == CommandException.Error.PASSWORD_INCORRECT) { 11669de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mResult = PhoneConstants.PIN_PASSWORD_INCORRECT; 11679de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } else { 11689de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mResult = PhoneConstants.PIN_GENERAL_FAILURE; 11699de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 11709de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } else { 11719de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mResult = PhoneConstants.PIN_RESULT_SUCCESS; 11729de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 11737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mDone = true; 11747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon UnlockSim.this.notifyAll(); 11757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 11777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon }; 11807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon UnlockSim.this.notifyAll(); 11817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Looper.loop(); 11837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* 11867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Use PIN or PUK to unlock SIM card 11877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 11887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * If PUK is null, unlock SIM card with PIN 11897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 11907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * If PUK is not null, unlock SIM card with PUK and set PIN code 11917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 11929de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville synchronized int[] unlockSim(String puk, String pin) { 11937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon while (mHandler == null) { 11957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 11967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon wait(); 11977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 11987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Thread.currentThread().interrupt(); 11997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE); 12027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (puk == null) { 12047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSimCard.supplyPin(pin, callback); 12057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 12067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSimCard.supplyPuk(puk, pin, callback); 12077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon while (!mDone) { 12107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 12117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "wait for done"); 12127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon wait(); 12137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 12147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Restore the interrupted status 12157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Thread.currentThread().interrupt(); 12167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "done"); 12199de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville int[] resultArray = new int[2]; 12209de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville resultArray[0] = mResult; 12219de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville resultArray[1] = mRetryCount; 12229de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville return resultArray; 12237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void updateServiceLocation() { 1227add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville updateServiceLocationForSubscriber(getDefaultSubscription()); 122836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 122936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 123036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1231b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public void updateServiceLocationForSubscriber(int subId) { 12327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No permission check needed here: this call is harmless, and it's 12337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // needed for the ServiceState.requestStateUpdate() call (which is 12347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // already intentionally exposed to 3rd parties.) 1235356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1236356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1237356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe phone.updateServiceLocation(); 1238356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 12397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 124136b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt @Override 124236b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public boolean isRadioOn(String callingPackage) { 124336b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return isRadioOnForSubscriber(getDefaultSubscription(), callingPackage); 124436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 124536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 124636b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt @Override 124736b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public boolean isRadioOnForSubscriber(int subId, String callingPackage) { 124836b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt if (!canReadPhoneState(callingPackage, "isRadioOnForSubscriber")) { 124936b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return false; 125036b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt } 125136b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return isRadioOnForSubscriber(subId); 125236b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt } 125336b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt 125436b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt private boolean isRadioOnForSubscriber(int subId) { 1255356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1256356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1257356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF; 1258356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1259356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return false; 1260356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 12617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void toggleRadioOnOff() { 1264add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville toggleRadioOnOffForSubscriber(getDefaultSubscription()); 126536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 126636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 126736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1268b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public void toggleRadioOnOffForSubscriber(int subId) { 12697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 1270356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1271356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1272356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe phone.setRadioPower(!isRadioOnForSubscriber(subId)); 1273356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 12747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 127536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 12767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean setRadio(boolean turnOn) { 1277add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return setRadioForSubscriber(getDefaultSubscription(), turnOn); 127836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 127936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1280b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public boolean setRadioForSubscriber(int subId, boolean turnOn) { 12817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 1282356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1283356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone == null) { 1284356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return false; 1285356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 1286356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if ((phone.getServiceState().getState() != 128736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville ServiceState.STATE_POWER_OFF) != turnOn) { 1288add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville toggleRadioOnOffForSubscriber(subId); 12897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 12917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 129236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 12931fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla public boolean needMobileRadioShutdown() { 12941fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla /* 12951fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla * If any of the Radios are available, it will need to be 12961fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla * shutdown. So return true if any Radio is available. 12971fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla */ 12981fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { 12991fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla Phone phone = PhoneFactory.getPhone(i); 13001fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla if (phone != null && phone.isRadioAvailable()) return true; 13011fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 13021fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown."); 13031fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla return false; 13041fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 13051fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla 13061fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla public void shutdownMobileRadios() { 13071fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { 13081fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla logv("Shutting down Phone " + i); 13091fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla shutdownRadioUsingPhoneId(i); 13101fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 13111fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 13121fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla 13131fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla private void shutdownRadioUsingPhoneId(int phoneId) { 13141fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla enforceModifyPermission(); 13151fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla Phone phone = PhoneFactory.getPhone(phoneId); 13161fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla if (phone != null && phone.isRadioAvailable()) { 13171fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla phone.shutdownRadio(); 13181fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 13191fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 13201fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla 13217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean setRadioPower(boolean turnOn) { 1322add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return setRadioPowerForSubscriber(getDefaultSubscription(), turnOn); 132336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 132436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1325b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) { 13267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 1327356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1328356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1329356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe phone.setRadioPower(turnOn); 1330356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return true; 1331356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1332356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return false; 1333356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 13347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 133636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // FIXME: subId version needed 1337356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe @Override 13387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean enableDataConnectivity() { 13397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 1340ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville int subId = mSubscriptionController.getDefaultDataSubId(); 1341356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1342356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1343356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe phone.setDataEnabled(true); 1344356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return true; 1345356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1346356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return false; 1347356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 13487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 135036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // FIXME: subId version needed 1351356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe @Override 13527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean disableDataConnectivity() { 13537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 1354ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville int subId = mSubscriptionController.getDefaultDataSubId(); 1355356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1356356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1357356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe phone.setDataEnabled(false); 1358356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return true; 1359356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1360356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return false; 1361356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 13627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 136436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // FIXME: subId version needed 1365356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe @Override 13667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isDataConnectivityPossible() { 1367ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville int subId = mSubscriptionController.getDefaultDataSubId(); 1368356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1369356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1370356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return phone.isDataConnectivityPossible(); 1371356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1372356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return false; 1373356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 13747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean handlePinMmi(String dialString) { 1377add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return handlePinMmiForSubscriber(getDefaultSubscription(), dialString); 137836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 137936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1380b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public boolean handlePinMmiForSubscriber(int subId, String dialString) { 13817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 1382356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (!SubscriptionManager.isValidSubscriptionId(subId)) { 1383356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return false; 1384356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 138536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId); 13867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getCallState() { 1389add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return getCallStateForSubscriber(getDefaultSubscription()); 139036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 139136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1392b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public int getCallStateForSubscriber(int subId) { 139336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return DefaultPhoneNotifier.convertCallState(getPhone(subId).getState()); 13947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1396356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe @Override 13977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getDataState() { 1398ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId()); 1399356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1400356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return DefaultPhoneNotifier.convertDataState(phone.getDataConnectionState()); 1401356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1402356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return DefaultPhoneNotifier.convertDataState(PhoneConstants.DataState.DISCONNECTED); 1403356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 14047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1406356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe @Override 14077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getDataActivity() { 1408ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId()); 1409356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1410356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState()); 1411356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1412356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return TelephonyManager.DATA_ACTIVITY_NONE; 1413356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 14147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 141764fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav public Bundle getCellLocation(String callingPackage) { 141864fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav enforceFineOrCoarseLocationPermission("getCellLocation"); 141964fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav 142064fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav // OP_COARSE_LOCATION controls both fine and coarse location. 142164fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav if (mAppOps.noteOp(AppOpsManager.OP_COARSE_LOCATION, Binder.getCallingUid(), 142264fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav callingPackage) != AppOpsManager.MODE_ALLOWED) { 14239acc70dcc5bab8df02211ad37a71a1a79c8d54e3Amit Mahajan log("getCellLocation: returning null; mode != allowed"); 142464fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav return null; 14257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1427e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (checkIfCallerIsSelfOrForegroundUser()) { 14287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getCellLocation: is active user"); 14297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Bundle data = new Bundle(); 14302c01cdffe4cb2bbc480f7080ef14e21f88833007Legler Wu Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId()); 1431356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone == null) { 1432356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return null; 1433356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 14342c01cdffe4cb2bbc480f7080ef14e21f88833007Legler Wu phone.getCellLocation().fillInNotifierBundle(data); 14357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return data; 14367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 14379acc70dcc5bab8df02211ad37a71a1a79c8d54e3Amit Mahajan log("getCellLocation: suppress non-active user"); 14387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 14397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 144264fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav private void enforceFineOrCoarseLocationPermission(String message) { 144364fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav try { 144464fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav mApp.enforceCallingOrSelfPermission( 144564fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav android.Manifest.permission.ACCESS_FINE_LOCATION, null); 144664fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav } catch (SecurityException e) { 144764fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav // If we have ACCESS_FINE_LOCATION permission, skip the check for ACCESS_COARSE_LOCATION 144864fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav // A failure should throw the SecurityException from ACCESS_COARSE_LOCATION since this 144964fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav // is the weaker precondition 145064fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav mApp.enforceCallingOrSelfPermission( 145164fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav android.Manifest.permission.ACCESS_COARSE_LOCATION, message); 145264fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav } 145364fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav } 145464fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav 145564fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav 14567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 14577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void enableLocationUpdates() { 1458add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville enableLocationUpdatesForSubscriber(getDefaultSubscription()); 145936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 146036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1461356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe @Override 1462b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public void enableLocationUpdatesForSubscriber(int subId) { 14637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 14647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.CONTROL_LOCATION_UPDATES, null); 1465356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1466356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1467356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe phone.enableLocationUpdates(); 1468356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 14697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 14727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void disableLocationUpdates() { 1473add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville disableLocationUpdatesForSubscriber(getDefaultSubscription()); 147436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 147536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1476356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe @Override 1477b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public void disableLocationUpdatesForSubscriber(int subId) { 14787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 14797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.CONTROL_LOCATION_UPDATES, null); 1480356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1481356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1482356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe phone.disableLocationUpdates(); 1483356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 14847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 14877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @SuppressWarnings("unchecked") 14887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage) { 148964fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav enforceFineOrCoarseLocationPermission("getNeighboringCellInfo"); 149064fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav 149164fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav // OP_COARSE_LOCATION controls both fine and coarse location. 149264fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav if (mAppOps.noteOp(AppOpsManager.OP_COARSE_LOCATION, Binder.getCallingUid(), 149364fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav callingPackage) != AppOpsManager.MODE_ALLOWED) { 149464fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav return null; 14957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(), 14987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon callingPackage) != AppOpsManager.MODE_ALLOWED) { 14997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 15007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 150164fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav 1502e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (checkIfCallerIsSelfOrForegroundUser()) { 15037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getNeighboringCellInfo: is active user"); 15047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ArrayList<NeighboringCellInfo> cells = null; 15067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 15087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon cells = (ArrayList<NeighboringCellInfo>) sendRequest( 150936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville CMD_HANDLE_NEIGHBORING_CELL, null, null); 15107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (RuntimeException e) { 151136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville Log.e(LOG_TAG, "getNeighboringCellInfo " + e); 15127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return cells; 15147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 15157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getNeighboringCellInfo: suppress non-active user"); 15167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 15177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 152264fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav public List<CellInfo> getAllCellInfo(String callingPackage) { 152364fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav enforceFineOrCoarseLocationPermission("getAllCellInfo"); 152464fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav 152564fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav // OP_COARSE_LOCATION controls both fine and coarse location. 152664fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav if (mAppOps.noteOp(AppOpsManager.OP_COARSE_LOCATION, Binder.getCallingUid(), 152764fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav callingPackage) != AppOpsManager.MODE_ALLOWED) { 152864fad26f22ed5d382533b3c07271cd1c7b81dd0bSvetoslav return null; 15297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1531e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (checkIfCallerIsSelfOrForegroundUser()) { 15327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getAllCellInfo: is active user"); 15332c01cdffe4cb2bbc480f7080ef14e21f88833007Legler Wu List<CellInfo> cellInfos = new ArrayList<CellInfo>(); 15342c01cdffe4cb2bbc480f7080ef14e21f88833007Legler Wu for (Phone phone : PhoneFactory.getPhones()) { 1535d9eb7da8777390662732098edae8930fda567953Robert Greenwalt final List<CellInfo> info = phone.getAllCellInfo(); 1536d9eb7da8777390662732098edae8930fda567953Robert Greenwalt if (info != null) cellInfos.addAll(phone.getAllCellInfo()); 15372c01cdffe4cb2bbc480f7080ef14e21f88833007Legler Wu } 15382c01cdffe4cb2bbc480f7080ef14e21f88833007Legler Wu return cellInfos; 15397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 15407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getAllCellInfo: suppress non-active user"); 15417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 15427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1545bd76e4e0407f75c4e6a6961cf943d36fc75a0e1aSailesh Nepal @Override 15467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void setCellInfoListRate(int rateInMillis) { 15477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.setCellInfoListRate(rateInMillis); 15487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 15517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Internal helper methods. 15527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 15537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1554e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby private static boolean checkIfCallerIsSelfOrForegroundUser() { 15557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean ok; 15567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean self = Binder.getCallingUid() == Process.myUid(); 15587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!self) { 15597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Get the caller's user id then clear the calling identity 15607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // which will be restored in the finally clause. 15617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int callingUser = UserHandle.getCallingUserId(); 15627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon long ident = Binder.clearCallingIdentity(); 15637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 15657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // With calling identity cleared the current user is the foreground user. 15667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int foregroundUser = ActivityManager.getCurrentUser(); 15677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ok = (foregroundUser == callingUser); 15687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) { 15697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon log("checkIfCallerIsSelfOrForegoundUser: foregroundUser=" + foregroundUser 15707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon + " callingUser=" + callingUser + " ok=" + ok); 15717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (Exception ex) { 15737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) loge("checkIfCallerIsSelfOrForegoundUser: Exception ex=" + ex); 15747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ok = false; 15757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } finally { 15767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Binder.restoreCallingIdentity(ident); 15777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 15797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("checkIfCallerIsSelfOrForegoundUser: is self"); 15807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ok = true; 15817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("checkIfCallerIsSelfOrForegoundUser: ret=" + ok); 15837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return ok; 15847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 15877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make sure the caller has the MODIFY_PHONE_STATE permission. 15887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 15897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @throws SecurityException if the caller does not have the required permission 15907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 15917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void enforceModifyPermission() { 15927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null); 15937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1596a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * Make sure either system app or the caller has carrier privilege. 1597a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * 1598a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * @throws SecurityException if the caller does not have the required permission/privilege 1599a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu */ 1600a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu private void enforceModifyPermissionOrCarrierPrivilege() { 1601f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal int permission = mApp.checkCallingOrSelfPermission( 1602f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal android.Manifest.permission.MODIFY_PHONE_STATE); 1603f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal if (permission == PackageManager.PERMISSION_GRANTED) { 1604f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal return; 1605f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal } 1606f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal 1607f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal log("No modify permission, check carrier privilege next."); 16085e5becdfa352e3ad1699cce13386b20761e2fde1Shishir Agrawal if (getCarrierPrivilegeStatus() != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 1609f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal loge("No Carrier Privilege."); 1610f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal throw new SecurityException("No modify permission or carrier privilege."); 1611a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu } 1612a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu } 1613a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu 1614a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu /** 1615a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * Make sure the caller has carrier privilege. 1616a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * 1617a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu * @throws SecurityException if the caller does not have the required permission 1618a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu */ 1619a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu private void enforceCarrierPrivilege() { 16205e5becdfa352e3ad1699cce13386b20761e2fde1Shishir Agrawal if (getCarrierPrivilegeStatus() != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 1621f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal loge("No Carrier Privilege."); 1622f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal throw new SecurityException("No Carrier Privilege."); 1623a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu } 1624a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu } 1625a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu 1626a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu /** 16277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make sure the caller has the CALL_PHONE permission. 16287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 16297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @throws SecurityException if the caller does not have the required permission 16307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 16317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void enforceCallPermission() { 16327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null); 16337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16358eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott private void enforceConnectivityInternalPermission() { 16368eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott mApp.enforceCallingOrSelfPermission( 16378eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott android.Manifest.permission.CONNECTIVITY_INTERNAL, 16388eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott "ConnectivityService"); 16398eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott } 16408eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott 16417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private String createTelUrl(String number) { 16427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (TextUtils.isEmpty(number)) { 16437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 16447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1646e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return "tel:" + number; 16477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1649f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad private static void log(String msg) { 16507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg); 16517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16531fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla private static void logv(String msg) { 16541fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg); 16551fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla } 16561fd79bd442bda04a7e5e467c9ae6ab22e2a83f05Naveen Kalla 1657f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad private static void loge(String msg) { 16587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg); 16597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 166136b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt @Override 16627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getActivePhoneType() { 1663add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return getActivePhoneTypeForSubscriber(getDefaultSubscription()); 166436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 166536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1666356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe @Override 1667b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public int getActivePhoneTypeForSubscriber(int subId) { 1668356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1669356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone == null) { 1670356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return PhoneConstants.PHONE_TYPE_NONE; 1671356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1672356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return getPhone(subId).getPhoneType(); 1673356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 16747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 16777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the CDMA ERI icon index to display 16787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 167936b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt @Override 168036b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public int getCdmaEriIconIndex(String callingPackage) { 168136b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage); 168236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 168336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1684356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe @Override 168536b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage) { 168636b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt if (!canReadPhoneState(callingPackage, "getCdmaEriIconIndexForSubscriber")) { 168736b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return -1; 168836b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt } 1689356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1690356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1691356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return phone.getCdmaEriIconIndex(); 1692356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1693356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return -1; 1694356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 16957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 16987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the CDMA ERI icon mode, 16997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 0 - ON 17007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 1 - FLASHING 17017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 170236b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt @Override 170336b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public int getCdmaEriIconMode(String callingPackage) { 170436b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage); 170536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 170636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1707356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe @Override 170836b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage) { 170936b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt if (!canReadPhoneState(callingPackage, "getCdmaEriIconModeForSubscriber")) { 171036b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return -1; 171136b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt } 1712356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1713356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1714356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return phone.getCdmaEriIconMode(); 1715356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1716356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return -1; 1717356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 17187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 17197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 17207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 17217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the CDMA ERI text, 17227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 172336b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt @Override 172436b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public String getCdmaEriText(String callingPackage) { 172536b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage); 172636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 172736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1728356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe @Override 172936b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public String getCdmaEriTextForSubscriber(int subId, String callingPackage) { 173036b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt if (!canReadPhoneState(callingPackage, "getCdmaEriIconTextForSubscriber")) { 173136b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return null; 173236b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt } 1733356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1734356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1735356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return phone.getCdmaEriText(); 1736356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1737356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return null; 1738356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 17397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 17407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 17417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1742ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu * Returns the CDMA MDN. 1743ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu */ 1744356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe @Override 1745b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public String getCdmaMdn(int subId) { 1746ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1747356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1748356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA && phone != null) { 1749356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return phone.getLine1Number(); 1750ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu } else { 1751ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu return null; 1752ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu } 1753ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu } 1754ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu 1755ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu /** 1756ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu * Returns the CDMA MIN. 1757ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu */ 1758356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe @Override 1759b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public String getCdmaMin(int subId) { 1760ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1761356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1762356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 1763356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return phone.getCdmaMin(); 1764ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu } else { 1765ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu return null; 1766ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu } 1767ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu } 1768ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu 1769ca05d5dad142516de2cc78dead550472a9cc5ee0Junda Liu /** 17707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns true if CDMA provisioning needs to run. 17717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 17727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean needsOtaServiceProvisioning() { 17737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.needsOtaServiceProvisioning(); 17747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 17757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 17767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 177776d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal * Sets the voice mail number of a given subId. 177876d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal */ 177976d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal @Override 178076d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal public boolean setVoiceMailNumber(int subId, String alphaTag, String number) { 17815e5becdfa352e3ad1699cce13386b20761e2fde1Shishir Agrawal enforceCarrierPrivilege(); 178276d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER, 178376d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal new Pair<String, String>(alphaTag, number), new Integer(subId)); 178476d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal return success; 178576d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal } 178676d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal 178776d5da9d705eba24aea9e5ef8d9ff2071b7819e2Shishir Agrawal /** 17887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the unread count of voicemails 17897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 17907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getVoiceMessageCount() { 1791add7cc5326c1daf6b51a608e143eccef893bbedbWink Saville return getVoiceMessageCountForSubscriber(getDefaultSubscription()); 179236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 179336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 179436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 179536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns the unread count of voicemails for a subId 179636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 1797356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe @Override 1798b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public int getVoiceMessageCountForSubscriber( int subId) { 1799356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1800356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1801356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return phone.getVoiceMessageCount(); 1802356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1803356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return 0; 1804356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 18057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 18067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 18077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1808a5dcfcb1c18056def5df69b0ac963fee0a5be98cRobert Greenwalt * Returns the data network type. 1809a5dcfcb1c18056def5df69b0ac963fee0a5be98cRobert Greenwalt * Legacy call, permission-free. 18107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 18117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @Deprecated to be removed Q3 2013 use {@link #getDataNetworkType}. 18127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 18137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 1814a5dcfcb1c18056def5df69b0ac963fee0a5be98cRobert Greenwalt public int getNetworkType() { 1815a5dcfcb1c18056def5df69b0ac963fee0a5be98cRobert Greenwalt final Phone phone = getPhone(getDefaultSubscription()); 1816a5dcfcb1c18056def5df69b0ac963fee0a5be98cRobert Greenwalt if (phone != null) { 1817a5dcfcb1c18056def5df69b0ac963fee0a5be98cRobert Greenwalt return phone.getServiceState().getDataNetworkType(); 1818a5dcfcb1c18056def5df69b0ac963fee0a5be98cRobert Greenwalt } else { 1819a5dcfcb1c18056def5df69b0ac963fee0a5be98cRobert Greenwalt return TelephonyManager.NETWORK_TYPE_UNKNOWN; 1820a5dcfcb1c18056def5df69b0ac963fee0a5be98cRobert Greenwalt } 182136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 182236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 182336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 182436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns the network type for a subId 182536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 182636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville @Override 182736b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public int getNetworkTypeForSubscriber(int subId, String callingPackage) { 182836b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt if (!canReadPhoneState(callingPackage, "getNetworkTypeForSubscriber")) { 182936b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return TelephonyManager.NETWORK_TYPE_UNKNOWN; 183036b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt } 1831a5dcfcb1c18056def5df69b0ac963fee0a5be98cRobert Greenwalt 1832356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 183336b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt if (phone != null) { 1834356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return phone.getServiceState().getDataNetworkType(); 1835356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1836356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return TelephonyManager.NETWORK_TYPE_UNKNOWN; 1837356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 18387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 18397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 18407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 18417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the data network type 18427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 18437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 184436b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public int getDataNetworkType(String callingPackage) { 184536b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage); 184636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 184736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 184836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 184936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns the data network type for a subId 185036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 185136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville @Override 185236b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) { 185336b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt if (!canReadPhoneState(callingPackage, "getDataNetworkTypeForSubscriber")) { 185436b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return TelephonyManager.NETWORK_TYPE_UNKNOWN; 185536b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt } 185636b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt 1857356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1858356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1859356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return phone.getServiceState().getDataNetworkType(); 1860356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1861356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return TelephonyManager.NETWORK_TYPE_UNKNOWN; 1862356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 18637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 18647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 18657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 186636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns the Voice network type for a subId 186736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 186836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville @Override 1869a5dcfcb1c18056def5df69b0ac963fee0a5be98cRobert Greenwalt public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage) { 1870a5dcfcb1c18056def5df69b0ac963fee0a5be98cRobert Greenwalt if (!canReadPhoneState(callingPackage, "getDataNetworkTypeForSubscriber")) { 1871a5dcfcb1c18056def5df69b0ac963fee0a5be98cRobert Greenwalt return TelephonyManager.NETWORK_TYPE_UNKNOWN; 1872a5dcfcb1c18056def5df69b0ac963fee0a5be98cRobert Greenwalt } 1873a5dcfcb1c18056def5df69b0ac963fee0a5be98cRobert Greenwalt 1874356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1875356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone != null) { 1876356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return phone.getServiceState().getVoiceNetworkType(); 1877356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1878356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return TelephonyManager.NETWORK_TYPE_UNKNOWN; 1879356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 18807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 18817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 18827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 18837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return true if a ICC card is present 18847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 18857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean hasIccCard() { 188636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville // FIXME Make changes to pass defaultSimId of type int 1887a6fc2a8518c71b7a720f849bbfd4c51fe35a461dAmit Mahajan return hasIccCardUsingSlotId(mSubscriptionController.getSlotId(getDefaultSubscription())); 188836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 188936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 189036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 189136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * @return true if a ICC card is present for a slotId 189236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 1893356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe @Override 1894b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville public boolean hasIccCardUsingSlotId(int slotId) { 1895a6fc2a8518c71b7a720f849bbfd4c51fe35a461dAmit Mahajan int subId[] = mSubscriptionController.getSubIdUsingSlotId(slotId); 1896356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId[0]); 1897356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (subId != null && phone != null) { 1898356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return phone.getIccCard().hasIccCard(); 1899a6fc2a8518c71b7a720f849bbfd4c51fe35a461dAmit Mahajan } else { 1900a6fc2a8518c71b7a720f849bbfd4c51fe35a461dAmit Mahajan return false; 1901a6fc2a8518c71b7a720f849bbfd4c51fe35a461dAmit Mahajan } 19027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 19037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 19047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 19057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Return if the current radio is LTE on CDMA. This 19067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * is a tri-state return value as for a period of time 19077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * the mode may be unknown. 19087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 190936b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt * @param callingPackage the name of the package making the call. 19107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE} 1911e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * or {@link Phone#LTE_ON_CDMA_TRUE} 19127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 191336b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt @Override 191436b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public int getLteOnCdmaMode(String callingPackage) { 191536b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage); 191636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 191736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1918356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe @Override 191936b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage) { 192036b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt if (!canReadPhoneState(callingPackage, "getLteOnCdmaModeForSubscriber")) { 192136b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return PhoneConstants.LTE_ON_CDMA_UNKNOWN; 192236b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt } 192336b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt 1924356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 1925356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone == null) { 1926356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return PhoneConstants.LTE_ON_CDMA_UNKNOWN; 1927356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } else { 1928356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return phone.getLteOnCdmaMode(); 1929356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 193036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 193136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 193236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void setPhone(Phone phone) { 193336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville mPhone = phone; 193436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 193536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 193636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 193736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * {@hide} 193836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns Default subId, 0 in the case of single standby. 193936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 1940b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville private int getDefaultSubscription() { 1941ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville return mSubscriptionController.getDefaultSubId(); 194236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 194336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 1944b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville private int getPreferredVoiceSubscription() { 1945ac1bdfd36366426513d51bd2c4b107b00533889eWink Saville return mSubscriptionController.getDefaultVoiceSubId(); 19467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1947f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad 1948f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad /** 1949f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad * @see android.telephony.TelephonyManager.WifiCallingChoices 1950f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad */ 1951f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad public int getWhenToMakeWifiCalls() { 1952d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal return Settings.System.getInt(mPhone.getContext().getContentResolver(), 1953d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal Settings.System.WHEN_TO_MAKE_WIFI_CALLS, getWhenToMakeWifiCallsDefaultPreference()); 1954f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad } 1955f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad 1956f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad /** 1957f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad * @see android.telephony.TelephonyManager.WifiCallingChoices 1958f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad */ 1959f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad public void setWhenToMakeWifiCalls(int preference) { 1960d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference); 1961d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal Settings.System.putInt(mPhone.getContext().getContentResolver(), 1962d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference); 1963f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad } 1964f9e92733e130dc37ce2c592b36deab86008f5706Ihab Awad 1965d1e681513fb108d5902a1c76eedca7b83034c056Sailesh Nepal private static int getWhenToMakeWifiCallsDefaultPreference() { 1966da120f4e3d32ca97c5b4c21d6c505d834a29ab8dSantos Cordon // TODO: Use a build property to choose this value. 19679829e880f73f76119ba76ba032db42aad042858fEvan Charlton return TelephonyManager.WifiCallingChoices.ALWAYS_USE; 1968f2177b7ec0fd9efcb8299e8272a494e869dcf16fIhab Awad } 196969f68120b94cecb2d87fe856bc115714b4e77bcdShishir Agrawal 1970566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal @Override 1971da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal public IccOpenLogicalChannelResponse iccOpenLogicalChannel(String AID) { 1972a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1973566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1974566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccOpenLogicalChannel: " + AID); 1975da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse)sendRequest( 1976da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal CMD_OPEN_CHANNEL, AID); 1977da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (DBG) log("iccOpenLogicalChannel: " + response); 1978da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal return response; 1979566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1980566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1981566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal @Override 1982566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public boolean iccCloseLogicalChannel(int channel) { 1983a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1984566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1985566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccCloseLogicalChannel: " + channel); 1986566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (channel < 0) { 1987566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return false; 1988566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1989e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean)sendRequest(CMD_CLOSE_CHANNEL, channel); 1990566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccCloseLogicalChannel: " + success); 1991566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return success; 1992566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 1993566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1994566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal @Override 1995566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal public String iccTransmitApduLogicalChannel(int channel, int cla, 1996566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal int command, int p1, int p2, int p3, String data) { 1997a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 1998566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 1999566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) { 2000566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal log("iccTransmitApduLogicalChannel: chnl=" + channel + " cla=" + cla + 2001566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + 2002566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal " data=" + data); 2003566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 2004566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 2005566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (channel < 0) { 2006566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return ""; 2007566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 2008566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 2009da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccIoResult response = (IccIoResult)sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL, 2010566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal new IccAPDUArgument(channel, cla, command, p1, p2, p3, data)); 2011566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal if (DBG) log("iccTransmitApduLogicalChannel: " + response); 2012566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal 2013566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal // Append the returned status code to the end of the response payload. 2014566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal String s = Integer.toHexString( 2015566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 20165ec14172e42d180d7dd6110ef8eb1dedb0a0a7fbShishir Agrawal if (response.payload != null) { 20175ec14172e42d180d7dd6110ef8eb1dedb0a0a7fbShishir Agrawal s = IccUtils.bytesToHexString(response.payload) + s; 20185ec14172e42d180d7dd6110ef8eb1dedb0a0a7fbShishir Agrawal } 2019566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal return s; 2020566b761b610e7e5e1ade9ab0906a2a7e816dad63Shishir Agrawal } 2021e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 2022c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton @Override 2023da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal public String iccTransmitApduBasicChannel(int cla, int command, int p1, int p2, 2024da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal int p3, String data) { 2025da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal enforceModifyPermissionOrCarrierPrivilege(); 2026da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 2027da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (DBG) { 2028da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal log("iccTransmitApduBasicChannel: cla=" + cla + " cmd=" + command + " p1=" 2029da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data); 2030da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 2031da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 2032da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccIoResult response = (IccIoResult)sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL, 2033da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal new IccAPDUArgument(0, cla, command, p1, p2, p3, data)); 2034da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (DBG) log("iccTransmitApduBasicChannel: " + response); 2035da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 2036da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal // Append the returned status code to the end of the response payload. 2037da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal String s = Integer.toHexString( 2038da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 20395ec14172e42d180d7dd6110ef8eb1dedb0a0a7fbShishir Agrawal if (response.payload != null) { 20405ec14172e42d180d7dd6110ef8eb1dedb0a0a7fbShishir Agrawal s = IccUtils.bytesToHexString(response.payload) + s; 20415ec14172e42d180d7dd6110ef8eb1dedb0a0a7fbShishir Agrawal } 2042da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal return s; 2043da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 2044da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 2045da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal @Override 2046da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal public byte[] iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3, 2047da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal String filePath) { 2048da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal enforceModifyPermissionOrCarrierPrivilege(); 2049da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 2050da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (DBG) { 2051da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal log("Exchange SIM_IO " + fileID + ":" + command + " " + 2052da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal p1 + " " + p2 + " " + p3 + ":" + filePath); 2053da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 2054da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 2055da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal IccIoResult response = 2056da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal (IccIoResult)sendRequest(CMD_EXCHANGE_SIM_IO, 20573edf3789a6e8b6b9ac28b7dfb24d6d7b00b3b554Yong Jiang new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath)); 2058da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 2059da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (DBG) { 2060da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal log("Exchange SIM_IO [R]" + response); 2061da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 2062da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 2063da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal byte[] result = null; 2064da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal int length = 2; 2065da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal if (response.payload != null) { 2066da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal length = 2 + response.payload.length; 2067da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal result = new byte[length]; 2068da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal System.arraycopy(response.payload, 0, result, 0, response.payload.length); 2069da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } else { 2070da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal result = new byte[length]; 2071da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 2072da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 2073da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal result[length - 1] = (byte) response.sw2; 2074da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal result[length - 2] = (byte) response.sw1; 2075da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal return result; 2076da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal } 2077da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal 2078da0bb0d7aff7b4a445370dc0709e94b874031178Shishir Agrawal @Override 2079c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton public String sendEnvelopeWithStatus(String content) { 2080a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 2081c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton 2082c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton IccIoResult response = (IccIoResult)sendRequest(CMD_SEND_ENVELOPE, content); 2083c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton if (response.payload == null) { 2084c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton return ""; 2085c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton } 2086c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton 2087c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton // Append the returned status code to the end of the response payload. 2088c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton String s = Integer.toHexString( 2089c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 2090c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton s = IccUtils.bytesToHexString(response.payload) + s; 2091c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton return s; 2092c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton } 2093c66da36833b835a9a122f6b0a3e4ecef27be266bEvan Charlton 2094e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 2095e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems} 2096e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators. 2097e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 2098e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param itemID the ID of the item to read 2099e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return the NV item as a String, or null on error. 2100e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 2101e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 2102e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public String nvReadItem(int itemID) { 2103a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 2104e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvReadItem: item " + itemID); 2105e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID); 2106e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"'); 2107e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return value; 2108e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 2109e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 2110e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 2111e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems} 2112e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators. 2113e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 2114e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param itemID the ID of the item to read 2115e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param itemValue the value to write, as a String 2116e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return true on success; false on any failure 2117e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 2118e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 2119e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public boolean nvWriteItem(int itemID, String itemValue) { 2120a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 2121e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"'); 2122e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM, 2123e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby new Pair<Integer, String>(itemID, itemValue)); 2124e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail")); 2125e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return success; 2126e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 2127e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 2128e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 2129e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage. 2130e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Used for device configuration by some CDMA operators. 2131e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 2132e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param preferredRoamingList byte array containing the new PRL 2133e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return true on success; false on any failure 2134e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 2135e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 2136e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) { 2137a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 2138e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList)); 2139e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList); 2140e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail")); 2141e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return success; 2142e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 2143e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby 2144e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby /** 2145e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Perform the specified type of NV config reset. 2146e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * Used for device configuration by some CDMA operators. 2147e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * 2148e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset) 2149e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby * @return true on success; false on any failure 2150e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby */ 2151e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby @Override 2152e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby public boolean nvResetConfig(int resetType) { 2153a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 2154e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvResetConfig: type " + resetType); 2155e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby Boolean success = (Boolean) sendRequest(CMD_NV_RESET_CONFIG, resetType); 2156e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby if (DBG) log("nvResetConfig: type " + resetType + ' ' + (success ? "ok" : "fail")); 2157e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby return success; 2158e994d46a1f951b496441a42d1eabd2a0e026ceaeJake Hamby } 21597c27be317e8757948178815426d3a329c852b9eeJake Hamby 21607c27be317e8757948178815426d3a329c852b9eeJake Hamby /** 216136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * {@hide} 216236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville * Returns Default sim, 0 in the case of single standby. 216336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville */ 216436469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public int getDefaultSim() { 216536469e74b7c79ed84148754190c38196eb9a2c49Wink Saville //TODO Need to get it from Telephony Devcontroller 216636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville return 0; 216736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 216836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 2169b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov public String[] getPcscfAddress(String apnType, String callingPackage) { 2170b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov if (!canReadPhoneState(callingPackage, "getPcscfAddress")) { 2171b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov return new String[0]; 2172b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov } 2173b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov 2174b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov 217587fca6f34c10e43e4dcfdd3f4e35bd4050e19582ram return mPhone.getPcscfAddress(apnType); 217636469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 217736469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 217836469e74b7c79ed84148754190c38196eb9a2c49Wink Saville public void setImsRegistrationState(boolean registered) { 217936469e74b7c79ed84148754190c38196eb9a2c49Wink Saville enforceModifyPermission(); 218036469e74b7c79ed84148754190c38196eb9a2c49Wink Saville mPhone.setImsRegistrationState(registered); 218136469e74b7c79ed84148754190c38196eb9a2c49Wink Saville } 218236469e74b7c79ed84148754190c38196eb9a2c49Wink Saville 218336469e74b7c79ed84148754190c38196eb9a2c49Wink Saville /** 218454788801de04c603a856596f4ae4377ab77a9821Stuart Scott * Set the network selection mode to automatic. 218554788801de04c603a856596f4ae4377ab77a9821Stuart Scott * 218654788801de04c603a856596f4ae4377ab77a9821Stuart Scott */ 218754788801de04c603a856596f4ae4377ab77a9821Stuart Scott @Override 218854788801de04c603a856596f4ae4377ab77a9821Stuart Scott public void setNetworkSelectionModeAutomatic(int subId) { 218954788801de04c603a856596f4ae4377ab77a9821Stuart Scott enforceModifyPermissionOrCarrierPrivilege(); 219054788801de04c603a856596f4ae4377ab77a9821Stuart Scott if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId); 219154788801de04c603a856596f4ae4377ab77a9821Stuart Scott sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId); 219254788801de04c603a856596f4ae4377ab77a9821Stuart Scott } 219354788801de04c603a856596f4ae4377ab77a9821Stuart Scott 219454788801de04c603a856596f4ae4377ab77a9821Stuart Scott /** 2195302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal * Set the network selection mode to manual with the selected carrier. 2196302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal */ 2197302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal @Override 219877ba317277863812508869705308373b42364e0aShishir Agrawal public boolean setNetworkSelectionModeManual(int subId, OperatorInfo operator, 219977ba317277863812508869705308373b42364e0aShishir Agrawal boolean persistSelection) { 2200302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal enforceModifyPermissionOrCarrierPrivilege(); 2201302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal if (DBG) log("setNetworkSelectionModeManual: subId:" + subId + " operator:" + operator); 220277ba317277863812508869705308373b42364e0aShishir Agrawal ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operator, 220377ba317277863812508869705308373b42364e0aShishir Agrawal persistSelection); 220477ba317277863812508869705308373b42364e0aShishir Agrawal return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId); 2205302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal } 2206302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal 2207302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal /** 2208302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal * Scans for available networks. 2209302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal */ 2210302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal @Override 2211302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal public CellNetworkScanResult getCellNetworkScanResults(int subId) { 2212302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal enforceModifyPermissionOrCarrierPrivilege(); 2213302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal if (DBG) log("getCellNetworkScanResults: subId " + subId); 2214302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal CellNetworkScanResult result = (CellNetworkScanResult) sendRequest( 2215302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal CMD_PERFORM_NETWORK_SCAN, null, subId); 2216302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal return result; 2217302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal } 2218302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal 2219302c8699cd4389dbb3ec9b2d23748f3f0d51a8daShishir Agrawal /** 222084d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu * Get the calculated preferred network type. 222184d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu * Used for debugging incorrect network type. 222284d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu * 222384d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu * @return the preferred network type, defined in RILConstants.java. 222484d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu */ 222584d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu @Override 2226b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov public int getCalculatedPreferredNetworkType(String callingPackage) { 2227b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov if (!canReadPhoneState(callingPackage, "getCalculatedPreferredNetworkType")) { 2228b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov return RILConstants.PREFERRED_NETWORK_MODE; 2229b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov } 2230b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov 223143330e02af9431ac18a9b9d6c09610f910b8c0f2Amit Mahajan return PhoneFactory.calculatePreferredNetworkType(mPhone.getContext(), 0); // wink FIXME: need to get SubId from somewhere. 223284d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu } 223384d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu 223484d15a2e84fa528f111abf05d17fc2280b182b7cJunda Liu /** 22357c27be317e8757948178815426d3a329c852b9eeJake Hamby * Get the preferred network type. 22367c27be317e8757948178815426d3a329c852b9eeJake Hamby * Used for device configuration by some CDMA operators. 22377c27be317e8757948178815426d3a329c852b9eeJake Hamby * 22387c27be317e8757948178815426d3a329c852b9eeJake Hamby * @return the preferred network type, defined in RILConstants.java. 22397c27be317e8757948178815426d3a329c852b9eeJake Hamby */ 22407c27be317e8757948178815426d3a329c852b9eeJake Hamby @Override 224154788801de04c603a856596f4ae4377ab77a9821Stuart Scott public int getPreferredNetworkType(int subId) { 2242a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 22437c27be317e8757948178815426d3a329c852b9eeJake Hamby if (DBG) log("getPreferredNetworkType"); 224454788801de04c603a856596f4ae4377ab77a9821Stuart Scott int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId); 22457c27be317e8757948178815426d3a329c852b9eeJake Hamby int networkType = (result != null ? result[0] : -1); 22467c27be317e8757948178815426d3a329c852b9eeJake Hamby if (DBG) log("getPreferredNetworkType: " + networkType); 22477c27be317e8757948178815426d3a329c852b9eeJake Hamby return networkType; 22487c27be317e8757948178815426d3a329c852b9eeJake Hamby } 22497c27be317e8757948178815426d3a329c852b9eeJake Hamby 22507c27be317e8757948178815426d3a329c852b9eeJake Hamby /** 22517c27be317e8757948178815426d3a329c852b9eeJake Hamby * Set the preferred network type. 22527c27be317e8757948178815426d3a329c852b9eeJake Hamby * Used for device configuration by some CDMA operators. 22537c27be317e8757948178815426d3a329c852b9eeJake Hamby * 22547c27be317e8757948178815426d3a329c852b9eeJake Hamby * @param networkType the preferred network type, defined in RILConstants.java. 22557c27be317e8757948178815426d3a329c852b9eeJake Hamby * @return true on success; false on any failure. 22567c27be317e8757948178815426d3a329c852b9eeJake Hamby */ 22577c27be317e8757948178815426d3a329c852b9eeJake Hamby @Override 225854788801de04c603a856596f4ae4377ab77a9821Stuart Scott public boolean setPreferredNetworkType(int subId, int networkType) { 2259a2e3601f8c198e7880ff407e1cea9ef2b8ce8505Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 226054788801de04c603a856596f4ae4377ab77a9821Stuart Scott if (DBG) log("setPreferredNetworkType: subId " + subId + " type " + networkType); 226154788801de04c603a856596f4ae4377ab77a9821Stuart Scott Boolean success = (Boolean) sendRequest(CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId); 22627c27be317e8757948178815426d3a329c852b9eeJake Hamby if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail")); 226380bc0d1614b46c89fa7a2c1d68fdb3ccb018625dJunda Liu if (success) { 226480bc0d1614b46c89fa7a2c1d68fdb3ccb018625dJunda Liu Settings.Global.putInt(mPhone.getContext().getContentResolver(), 226554788801de04c603a856596f4ae4377ab77a9821Stuart Scott Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType); 226680bc0d1614b46c89fa7a2c1d68fdb3ccb018625dJunda Liu } 22677c27be317e8757948178815426d3a329c852b9eeJake Hamby return success; 22687c27be317e8757948178815426d3a329c852b9eeJake Hamby } 2269ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt 2270ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt /** 2271475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu * Check TETHER_DUN_REQUIRED and TETHER_DUN_APN settings, net.tethering.noprovisioning 2272475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu * SystemProperty, and config_tether_apndata to decide whether DUN APN is required for 2273475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu * tethering. 2274475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu * 2275475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu * @return 0: Not required. 1: required. 2: Not set. 2276475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu * @hide 2277475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu */ 2278475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu @Override 2279475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu public int getTetherApnRequired() { 2280475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu enforceModifyPermissionOrCarrierPrivilege(); 2281475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu int dunRequired = Settings.Global.getInt(mPhone.getContext().getContentResolver(), 2282475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu Settings.Global.TETHER_DUN_REQUIRED, 2); 2283475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu // If not set, check net.tethering.noprovisioning, TETHER_DUN_APN setting and 2284475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu // config_tether_apndata. 2285475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu if (dunRequired == 2 && mPhone.hasMatchedTetherApnSetting()) { 2286475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu dunRequired = 1; 2287475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu } 2288475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu return dunRequired; 2289475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu } 2290475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu 2291475951f7b5c5831cbe015869c69b6916d4ab7053Junda Liu /** 2292ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * Set mobile data enabled 2293ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * Used by the user through settings etc to turn on/off mobile data 2294ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * 2295ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * @param enable {@code true} turn turn data on, else {@code false} 2296ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt */ 2297ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt @Override 2298e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville public void setDataEnabled(int subId, boolean enable) { 2299ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt enforceModifyPermission(); 2300e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville int phoneId = mSubscriptionController.getPhoneId(subId); 2301e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville log("getDataEnabled: subId=" + subId + " phoneId=" + phoneId); 2302e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville Phone phone = PhoneFactory.getPhone(phoneId); 2303e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville if (phone != null) { 2304e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville log("setDataEnabled: subId=" + subId + " enable=" + enable); 2305e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville phone.setDataEnabled(enable); 2306e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville } else { 2307e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville loge("setDataEnabled: no phone for subId=" + subId); 2308e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville } 2309ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt } 2310ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt 2311ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt /** 2312646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * Get whether mobile data is enabled. 2313646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * 2314646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * Note that this used to be available from ConnectivityService, gated by 2315646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * ACCESS_NETWORK_STATE permission, so this will accept either that or 2316646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt * our MODIFY_PHONE_STATE. 2317ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * 2318ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt * @return {@code true} if data is enabled else {@code false} 2319ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt */ 2320ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt @Override 2321e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville public boolean getDataEnabled(int subId) { 2322646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt try { 2323646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE, 2324646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt null); 2325646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt } catch (Exception e) { 2326646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, 2327646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt null); 2328646120a5b2c016a4528dab5372db94e027233fb3Robert Greenwalt } 2329e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville int phoneId = mSubscriptionController.getPhoneId(subId); 2330e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville log("getDataEnabled: subId=" + subId + " phoneId=" + phoneId); 2331e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville Phone phone = PhoneFactory.getPhone(phoneId); 2332e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville if (phone != null) { 2333e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville boolean retVal = phone.getDataEnabled(); 2334e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville log("getDataEnabled: subId=" + subId + " retVal=" + retVal); 2335e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville return retVal; 2336e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville } else { 2337e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville loge("getDataEnabled: no phone subId=" + subId + " retVal=false"); 2338e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville return false; 2339e7353bb9c6321b0858f9d981835b1bbc52b3e517Wink Saville } 2340ed86e5837b426bcba625b57e466b8d04ddbd8008Robert Greenwalt } 234160f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawal 234260f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawal @Override 23435e5becdfa352e3ad1699cce13386b20761e2fde1Shishir Agrawal public int getCarrierPrivilegeStatus() { 234421409250c4001605606a37c3903dc22805410900Shishir Agrawal UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId()); 2345eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (card == null) { 23465e5becdfa352e3ad1699cce13386b20761e2fde1Shishir Agrawal loge("getCarrierPrivilegeStatus: No UICC"); 2347eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 2348eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 2349eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal return card.getCarrierPrivilegeStatusForCurrentTransaction( 2350f1ac4c93f1b87b7db0836882ed72935a86ed3898Shishir Agrawal mPhone.getContext().getPackageManager()); 235160f9c952a11be2a34460b4cc8e0f9b31e38f5f30Shishir Agrawal } 23522934034e04c5ca7839de41d0cc8f8bab89b1e336Junda Liu 23532934034e04c5ca7839de41d0cc8f8bab89b1e336Junda Liu @Override 235450ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson public int checkCarrierPrivilegesForPackage(String pkgName) { 235521409250c4001605606a37c3903dc22805410900Shishir Agrawal UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId()); 2356eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal if (card == null) { 2357eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal loge("checkCarrierPrivilegesForPackage: No UICC"); 2358eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 2359eb8771e9b44fcc885c17d3ff4a3358fcd0b21c6eShishir Agrawal } 236050ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson return card.getCarrierPrivilegeStatus(mPhone.getContext().getPackageManager(), pkgName); 236150ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson } 236250ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson 236350ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson @Override 236450ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) { 236550ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 236650ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { 236750ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson UiccCard card = UiccController.getInstance().getUiccCard(i); 236850ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson if (card == null) { 23697d320dff9d5b30b7b8a2dc9ef7574dc9bb8571b8Jonathan Basseri // No UICC in that slot. 237050ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson continue; 237150ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson } 237250ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson 237350ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson result = card.getCarrierPrivilegeStatus( 237450ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson mPhone.getContext().getPackageManager(), pkgName); 237550ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 237650ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson break; 237750ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson } 237850ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson } 237950ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson 238050ecba360335a12252c30c95c309ef3ff5560fbfZach Johnson return result; 23812934034e04c5ca7839de41d0cc8f8bab89b1e336Junda Liu } 238289e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan 238389e89d47f249a1e910d6d726dbfcbedfc193cb83Derek Tan @Override 2384e64de7820475d67ef0882a1b37f3bd188ca68e25Junda Liu public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) { 2385e64de7820475d67ef0882a1b37f3bd188ca68e25Junda Liu if (!SubscriptionManager.isValidPhoneId(phoneId)) { 2386e64de7820475d67ef0882a1b37f3bd188ca68e25Junda Liu loge("phoneId " + phoneId + " is not valid."); 2387e64de7820475d67ef0882a1b37f3bd188ca68e25Junda Liu return null; 2388e64de7820475d67ef0882a1b37f3bd188ca68e25Junda Liu } 2389e64de7820475d67ef0882a1b37f3bd188ca68e25Junda Liu UiccCard card = UiccController.getInstance().getUiccCard(phoneId); 2390eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal if (card == null) { 2391af74c86463b193100a48a0a2b83d0096863bf110Diego Pontoriero loge("getCarrierPackageNamesForIntent: No UICC"); 2392eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal return null ; 2393eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal } 2394af74c86463b193100a48a0a2b83d0096863bf110Diego Pontoriero return card.getCarrierPackageNamesForIntent( 2395483aff78d6bada4c2f4d28f804935d24c8173fceSvetoslav mPhone.getContext().getPackageManager(), intent); 2396eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal } 2397eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal 2398b564aaeff3b6c4b20c899b8c254e4622b691d0cfWink Saville private String getIccId(int subId) { 2399356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 2400356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe UiccCard card = phone == null ? null : phone.getUiccCard(); 240197ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan if (card == null) { 240297ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan loge("getIccId: No UICC"); 240397ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return null; 240497ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } 240597ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String iccId = card.getIccId(); 240697ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan if (TextUtils.isEmpty(iccId)) { 240797ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan loge("getIccId: ICC ID is null or empty."); 240897ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return null; 240997ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } 241097ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return iccId; 241197ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } 241297ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan 2413eb6439a7bd453313f7ed7972d30e2478243801ffShishir Agrawal @Override 241485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag, 241585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey String number) { 24165e5becdfa352e3ad1699cce13386b20761e2fde1Shishir Agrawal enforceCarrierPrivilege(); 241797ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan 241885190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String iccId = getIccId(subId); 2419356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final Phone phone = getPhone(subId); 2420356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe if (phone == null) { 2421356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe return false; 2422356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe } 2423356d76380ebed2bdb3b2abac40e55c073ceefb83Sanket Padawe final String subscriberId = phone.getSubscriberId(); 242485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 242585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (DBG_MERGE) { 242685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey Slog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId=" 242785190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey + subscriberId + " to " + number); 242885190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 242985190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 2430495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal if (TextUtils.isEmpty(iccId)) { 2431495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal return false; 2432495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal } 243397ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan 243485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit(); 243585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 243685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId; 2437495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal if (alphaTag == null) { 2438495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal editor.remove(alphaTagPrefKey); 2439495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal } else { 2440495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal editor.putString(alphaTagPrefKey, alphaTag); 244197ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan } 2442495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal 244385190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey // Record both the line number and IMSI for this ICCID, since we need to 244485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey // track all merged IMSIs based on line number 244585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId; 244685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId; 2447495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal if (number == null) { 2448495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal editor.remove(numberPrefKey); 244985190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey editor.remove(subscriberPrefKey); 2450495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal } else { 2451495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal editor.putString(numberPrefKey, number); 245285190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey editor.putString(subscriberPrefKey, subscriberId); 2453495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal } 245485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 2455495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal editor.commit(); 2456495d7e1f6af536095cf90d7299b64e47c8323dfcShishir Agrawal return true; 24577226c84acb402f96e527650347391fa025294350Derek Tan } 24587226c84acb402f96e527650347391fa025294350Derek Tan 24597226c84acb402f96e527650347391fa025294350Derek Tan @Override 2460b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov public String getLine1NumberForDisplay(int subId, String callingPackage) { 2461fee69345c86d13b46e9e1d1e36178ebef17538eeMakoto Onuki // This is open to apps with WRITE_SMS. 2462fee69345c86d13b46e9e1d1e36178ebef17538eeMakoto Onuki if (!canReadPhoneNumber(callingPackage, "getLine1NumberForDisplay")) { 2463b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov return null; 2464b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov } 246597ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan 246697ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String iccId = getIccId(subId); 246797ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan if (iccId != null) { 246897ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId; 2469df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee return mTelephonySharedPreferences.getString(numberPrefKey, null); 24707226c84acb402f96e527650347391fa025294350Derek Tan } 247197ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return null; 24727226c84acb402f96e527650347391fa025294350Derek Tan } 24737226c84acb402f96e527650347391fa025294350Derek Tan 24747226c84acb402f96e527650347391fa025294350Derek Tan @Override 2475b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov public String getLine1AlphaTagForDisplay(int subId, String callingPackage) { 2476b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov if (!canReadPhoneState(callingPackage, "getLine1AlphaTagForDisplay")) { 2477b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov return null; 2478b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov } 247997ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan 248097ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String iccId = getIccId(subId); 248197ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan if (iccId != null) { 248297ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId; 2483df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee return mTelephonySharedPreferences.getString(alphaTagPrefKey, null); 24847226c84acb402f96e527650347391fa025294350Derek Tan } 248597ebb427fc22f1f14eab7c79745dfcbf2eb2ff7aDerek Tan return null; 24867226c84acb402f96e527650347391fa025294350Derek Tan } 2487b1ebf8c3755b7e1cb207cbd49f6c8bdfa3566668Shishir Agrawal 2488b1ebf8c3755b7e1cb207cbd49f6c8bdfa3566668Shishir Agrawal @Override 24898e53b0bd5f402210bd0187da70a6b2ecc14a296bFyodor Kupolov public String[] getMergedSubscriberIds(String callingPackage) { 24908e53b0bd5f402210bd0187da70a6b2ecc14a296bFyodor Kupolov if (!canReadPhoneState(callingPackage, "getMergedSubscriberIds")) { 24918e53b0bd5f402210bd0187da70a6b2ecc14a296bFyodor Kupolov return null; 24928e53b0bd5f402210bd0187da70a6b2ecc14a296bFyodor Kupolov } 249385190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final Context context = mPhone.getContext(); 249485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final TelephonyManager tele = TelephonyManager.from(context); 249585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final SubscriptionManager sub = SubscriptionManager.from(context); 249685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 249785190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey // Figure out what subscribers are currently active 249885190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final ArraySet<String> activeSubscriberIds = new ArraySet<>(); 24998e53b0bd5f402210bd0187da70a6b2ecc14a296bFyodor Kupolov // Clear calling identity, when calling TelephonyManager, because callerUid must be 25008e53b0bd5f402210bd0187da70a6b2ecc14a296bFyodor Kupolov // the process, where TelephonyManager was instantiated. Otherwise AppOps check will fail. 25018e53b0bd5f402210bd0187da70a6b2ecc14a296bFyodor Kupolov final long identity = Binder.clearCallingIdentity(); 25028e53b0bd5f402210bd0187da70a6b2ecc14a296bFyodor Kupolov try { 25038e53b0bd5f402210bd0187da70a6b2ecc14a296bFyodor Kupolov final int[] subIds = sub.getActiveSubscriptionIdList(); 25048e53b0bd5f402210bd0187da70a6b2ecc14a296bFyodor Kupolov for (int subId : subIds) { 25058e53b0bd5f402210bd0187da70a6b2ecc14a296bFyodor Kupolov activeSubscriberIds.add(tele.getSubscriberId(subId)); 25068e53b0bd5f402210bd0187da70a6b2ecc14a296bFyodor Kupolov } 25078e53b0bd5f402210bd0187da70a6b2ecc14a296bFyodor Kupolov } finally { 25088e53b0bd5f402210bd0187da70a6b2ecc14a296bFyodor Kupolov Binder.restoreCallingIdentity(identity); 250985190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 251085190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 251185190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey // First pass, find a number override for an active subscriber 251285190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey String mergeNumber = null; 251385190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final Map<String, ?> prefs = mTelephonySharedPreferences.getAll(); 251485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey for (String key : prefs.keySet()) { 251585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) { 251685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String subscriberId = (String) prefs.get(key); 251785190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (activeSubscriberIds.contains(subscriberId)) { 251885190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String iccId = key.substring(PREF_CARRIERS_SUBSCRIBER_PREFIX.length()); 251985190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId; 252085190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey mergeNumber = (String) prefs.get(numberKey); 252185190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (DBG_MERGE) { 252285190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey Slog.d(LOG_TAG, "Found line number " + mergeNumber 252385190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey + " for active subscriber " + subscriberId); 252485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 252585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (!TextUtils.isEmpty(mergeNumber)) { 252685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey break; 252785190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 252885190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 252985190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 253085190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 253185190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 253285190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey // Shortcut when no active merged subscribers 253385190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (TextUtils.isEmpty(mergeNumber)) { 253485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey return null; 253585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 253685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 253785190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey // Second pass, find all subscribers under that line override 253885190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final ArraySet<String> result = new ArraySet<>(); 253985190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey for (String key : prefs.keySet()) { 254085190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) { 254185190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String number = (String) prefs.get(key); 254285190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (mergeNumber.equals(number)) { 254385190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length()); 254485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId; 254585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String subscriberId = (String) prefs.get(subscriberKey); 254685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (!TextUtils.isEmpty(subscriberId)) { 254785190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey result.add(subscriberId); 254885190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 254985190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 255085190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 255185190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 255285190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 255385190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey final String[] resultArray = result.toArray(new String[result.size()]); 255485190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey Arrays.sort(resultArray); 255585190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey if (DBG_MERGE) { 255685190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey Slog.d(LOG_TAG, "Found subscribers " + Arrays.toString(resultArray) + " after merge"); 255785190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 255885190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey return resultArray; 255985190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey } 256085190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey 256185190e62b6d44db4454891cd98c7e5ead04e8e1bJeff Sharkey @Override 2562a3dfd75141d37ae7e170eeb200374f62235b092eShishir Agrawal public boolean setOperatorBrandOverride(String brand) { 25635e5becdfa352e3ad1699cce13386b20761e2fde1Shishir Agrawal enforceCarrierPrivilege(); 2564a3dfd75141d37ae7e170eeb200374f62235b092eShishir Agrawal return mPhone.setOperatorBrandOverride(brand); 2565b1ebf8c3755b7e1cb207cbd49f6c8bdfa3566668Shishir Agrawal } 25664bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu 25674bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu @Override 2568621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawal public boolean setRoamingOverride(List<String> gsmRoamingList, 2569621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawal List<String> gsmNonRoamingList, List<String> cdmaRoamingList, 2570621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawal List<String> cdmaNonRoamingList) { 2571621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawal enforceCarrierPrivilege(); 2572621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawal return mPhone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList, 2573621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawal cdmaNonRoamingList); 2574621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawal } 2575621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawal 2576621a47c9ff058ac6a735ee5347c45ec30b0236baShishir Agrawal @Override 25774bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) { 25784bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu enforceModifyPermission(); 25794bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu 25804bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu int returnValue = 0; 25814bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu try { 25824bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu AsyncResult result = (AsyncResult)sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq); 25834bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu if(result.exception == null) { 25844bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu if (result.result != null) { 25854bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu byte[] responseData = (byte[])(result.result); 25864bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu if(responseData.length > oemResp.length) { 25874bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " + 25884bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu responseData.length + "bytes. Buffer Size is " + 25894bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu oemResp.length + "bytes."); 25904bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } 25914bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu System.arraycopy(responseData, 0, oemResp, 0, responseData.length); 25924bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu returnValue = responseData.length; 25934bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } 25944bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } else { 25954bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu CommandException ex = (CommandException) result.exception; 25964bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu returnValue = ex.getCommandError().ordinal(); 25974bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu if(returnValue > 0) returnValue *= -1; 25984bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } 25994bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } catch (RuntimeException e) { 26004bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception"); 26014bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal()); 26024bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu if(returnValue > 0) returnValue *= -1; 26034bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } 26044bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu 26054bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu return returnValue; 26064bf01bc69fe97b9675463978cf5a2afff26fcccbSteven Liu } 26075d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville 26085d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville @Override 26095d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville public void setRadioCapability(RadioAccessFamily[] rafs) { 26105d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville try { 26115d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville ProxyController.getInstance().setRadioCapability(rafs); 26125d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville } catch (RuntimeException e) { 26135d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville Log.w(LOG_TAG, "setRadioCapability: Runtime Exception"); 26145d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville } 26155d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville } 26165d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville 26175d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville @Override 261836b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt public int getRadioAccessFamily(int phoneId, String callingPackage) { 261936b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt if (!canReadPhoneState(callingPackage, "getRadioAccessFamily")) { 262036b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt return RadioAccessFamily.RAF_UNKNOWN; 262136b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt } 262236b23afecddd082056dc1ce65e38c38f2805ca84Robert Greenwalt 26235d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville return ProxyController.getInstance().getRadioAccessFamily(phoneId); 26245d475dda0d2c2a220b8e33e77f9a40f5983c75b9Wink Saville } 2625df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee 2626df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee @Override 2627df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee public void enableVideoCalling(boolean enable) { 2628df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee enforceModifyPermission(); 2629df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee SharedPreferences.Editor editor = mTelephonySharedPreferences.edit(); 2630df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee editor.putBoolean(PREF_ENABLE_VIDEO_CALLING, enable); 2631df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee editor.commit(); 2632df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee } 2633df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee 2634df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee @Override 2635b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov public boolean isVideoCallingEnabled(String callingPackage) { 2636b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov if (!canReadPhoneState(callingPackage, "isVideoCallingEnabled")) { 2637b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov return false; 2638b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov } 2639b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov 264077527ac0cdad089f51530066f5248cb7925dd365Andrew Lee // Check the user preference and the system-level IMS setting. Even if the user has 264177527ac0cdad089f51530066f5248cb7925dd365Andrew Lee // enabled video calling, if IMS is disabled we aren't able to support video calling. 264277527ac0cdad089f51530066f5248cb7925dd365Andrew Lee // In the long run, we may instead need to check if there exists a connection service 264377527ac0cdad089f51530066f5248cb7925dd365Andrew Lee // which can support video calling. 2644312e8177b25ab359627685d449e0a5fdb539809fAndrew Lee return ImsManager.isVtEnabledByPlatform(mPhone.getContext()) 2645312e8177b25ab359627685d449e0a5fdb539809fAndrew Lee && ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mPhone.getContext()) 2646312e8177b25ab359627685d449e0a5fdb539809fAndrew Lee && mTelephonySharedPreferences.getBoolean(PREF_ENABLE_VIDEO_CALLING, true); 2647df14ead5c9ddb3120a6841552db54d4713058d3bAndrew Lee } 2648afe8264bd1241982c39c86f40d0fd08f0888c824Libin.Tang@motorola.com 2649a1239f2604b7fed20970aadf7496d6e12ba7ceaeAndrew Lee @Override 2650a1239f2604b7fed20970aadf7496d6e12ba7ceaeAndrew Lee public boolean canChangeDtmfToneLength() { 26519504c6b5c5c7072f72d8a9e6df59dbda8a6ccbe4Jonathan Basseri return mApp.getCarrierConfig().getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL); 2652a1239f2604b7fed20970aadf7496d6e12ba7ceaeAndrew Lee } 2653a1239f2604b7fed20970aadf7496d6e12ba7ceaeAndrew Lee 2654a1239f2604b7fed20970aadf7496d6e12ba7ceaeAndrew Lee @Override 2655a1239f2604b7fed20970aadf7496d6e12ba7ceaeAndrew Lee public boolean isWorldPhone() { 26569504c6b5c5c7072f72d8a9e6df59dbda8a6ccbe4Jonathan Basseri return mApp.getCarrierConfig().getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL); 2657a1239f2604b7fed20970aadf7496d6e12ba7ceaeAndrew Lee } 2658a1239f2604b7fed20970aadf7496d6e12ba7ceaeAndrew Lee 26599431b838f89399db2278c0436bd2817322a45f74Andrew Lee @Override 26609431b838f89399db2278c0436bd2817322a45f74Andrew Lee public boolean isTtyModeSupported() { 26619431b838f89399db2278c0436bd2817322a45f74Andrew Lee TelecomManager telecomManager = TelecomManager.from(mPhone.getContext()); 26629431b838f89399db2278c0436bd2817322a45f74Andrew Lee TelephonyManager telephonyManager = 26639431b838f89399db2278c0436bd2817322a45f74Andrew Lee (TelephonyManager) mPhone.getContext().getSystemService(Context.TELEPHONY_SERVICE); 26649431b838f89399db2278c0436bd2817322a45f74Andrew Lee return !telephonyManager.isMultiSimEnabled() && telecomManager.isTtySupported(); 26659431b838f89399db2278c0436bd2817322a45f74Andrew Lee } 26669431b838f89399db2278c0436bd2817322a45f74Andrew Lee 26679431b838f89399db2278c0436bd2817322a45f74Andrew Lee @Override 26689431b838f89399db2278c0436bd2817322a45f74Andrew Lee public boolean isHearingAidCompatibilitySupported() { 26699431b838f89399db2278c0436bd2817322a45f74Andrew Lee return mPhone.getContext().getResources().getBoolean(R.bool.hac_enabled); 26709431b838f89399db2278c0436bd2817322a45f74Andrew Lee } 26719431b838f89399db2278c0436bd2817322a45f74Andrew Lee 26727310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe /** 26737310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe * Returns the unique device ID of phone, for example, the IMEI for 26747310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe * GSM and the MEID for CDMA phones. Return null if device ID is not available. 26757310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe * 26767310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe * <p>Requires Permission: 26777310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} 26787310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe */ 26797310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe @Override 2680b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov public String getDeviceId(String callingPackage) { 2681b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov if (!canReadPhoneState(callingPackage, "getDeviceId")) { 2682b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov return null; 2683b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov } 2684b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov 26857310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe final Phone phone = PhoneFactory.getPhone(0); 26867310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe if (phone != null) { 26877310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe return phone.getDeviceId(); 26887310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe } else { 26897310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe return null; 26907310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe } 26917310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe } 26927310cc789b2efe4674e75bb8255373ab0c5a6881Sanket Padawe 2693afe8264bd1241982c39c86f40d0fd08f0888c824Libin.Tang@motorola.com /* 2694afe8264bd1241982c39c86f40d0fd08f0888c824Libin.Tang@motorola.com * {@hide} 2695afe8264bd1241982c39c86f40d0fd08f0888c824Libin.Tang@motorola.com * Returns the IMS Registration Status 2696afe8264bd1241982c39c86f40d0fd08f0888c824Libin.Tang@motorola.com */ 26977a1885ba88b4ca833d6dae8b352097636f242917Santos Cordon @Override 2698afe8264bd1241982c39c86f40d0fd08f0888c824Libin.Tang@motorola.com public boolean isImsRegistered() { 2699afe8264bd1241982c39c86f40d0fd08f0888c824Libin.Tang@motorola.com return mPhone.isImsRegistered(); 2700afe8264bd1241982c39c86f40d0fd08f0888c824Libin.Tang@motorola.com } 27017a1885ba88b4ca833d6dae8b352097636f242917Santos Cordon 27027a1885ba88b4ca833d6dae8b352097636f242917Santos Cordon @Override 27037a1885ba88b4ca833d6dae8b352097636f242917Santos Cordon public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) { 27047a1885ba88b4ca833d6dae8b352097636f242917Santos Cordon return PhoneUtils.getSubIdForPhoneAccount(phoneAccount); 27057a1885ba88b4ca833d6dae8b352097636f242917Santos Cordon } 2706dcfc793ddff32e3fd5ab49db2647d7b08fc4d29cNathan Harold 2707c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold /* 2708c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold * {@hide} 2709c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold * Returns the IMS Registration Status 2710c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold */ 27113b7a1bce40307becff28763f505faeffa927d577Etan Cohen public boolean isWifiCallingAvailable() { 2712c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold return mPhone.isWifiCallingEnabled(); 2713c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold } 2714c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold 2715c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold /* 2716c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold * {@hide} 2717c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold * Returns the IMS Registration Status 2718c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold */ 27193b7a1bce40307becff28763f505faeffa927d577Etan Cohen public boolean isVolteAvailable() { 2720c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold return mPhone.isVolteEnabled(); 2721c55097a922f316dd97084bce196335b64c6a55b0Nathan Harold } 2722b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov 27233b7a1bce40307becff28763f505faeffa927d577Etan Cohen /* 27243b7a1bce40307becff28763f505faeffa927d577Etan Cohen * {@hide} Returns the IMS Registration Status 27253b7a1bce40307becff28763f505faeffa927d577Etan Cohen */ 27263b7a1bce40307becff28763f505faeffa927d577Etan Cohen public boolean isVideoTelephonyAvailable() { 27273b7a1bce40307becff28763f505faeffa927d577Etan Cohen return mPhone.isVideoEnabled(); 27283b7a1bce40307becff28763f505faeffa927d577Etan Cohen } 27293b7a1bce40307becff28763f505faeffa927d577Etan Cohen 2730b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov private boolean canReadPhoneState(String callingPackage, String message) { 2731921655c60d4b464b8f4add98e0e5fb3ca48cccd4Etan Cohen try { 273283ea23b90597f39f5f8f899023ae099eab0e98e2Amit Mahajan mApp.enforceCallingOrSelfPermission( 2733921655c60d4b464b8f4add98e0e5fb3ca48cccd4Etan Cohen android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, message); 2734921655c60d4b464b8f4add98e0e5fb3ca48cccd4Etan Cohen 273583ea23b90597f39f5f8f899023ae099eab0e98e2Amit Mahajan // SKIP checking for run-time permission since caller or self has PRIVILEDGED permission 2736921655c60d4b464b8f4add98e0e5fb3ca48cccd4Etan Cohen return true; 2737785783f758260e5d23633317f1a286a89d66090dAmit Mahajan } catch (SecurityException e) { 2738785783f758260e5d23633317f1a286a89d66090dAmit Mahajan mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE, 2739785783f758260e5d23633317f1a286a89d66090dAmit Mahajan message); 2740921655c60d4b464b8f4add98e0e5fb3ca48cccd4Etan Cohen } 2741b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov 2742b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(), 2743b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov callingPackage) != AppOpsManager.MODE_ALLOWED) { 2744b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov return false; 2745b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov } 2746b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov 2747b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov return true; 2748b320e187c6eddc4a9d5f31d397f52500d38b4c05Svet Ganov } 27498eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott 2750fee69345c86d13b46e9e1d1e36178ebef17538eeMakoto Onuki /** 2751fee69345c86d13b46e9e1d1e36178ebef17538eeMakoto Onuki * Besides READ_PHONE_STATE, WRITE_SMS also allows apps to get phone numbers. 2752fee69345c86d13b46e9e1d1e36178ebef17538eeMakoto Onuki */ 2753fee69345c86d13b46e9e1d1e36178ebef17538eeMakoto Onuki private boolean canReadPhoneNumber(String callingPackage, String message) { 2754e4072d10b761c7e167c4f9b5d7570c6417c1d054Makoto Onuki // Default SMS app can always read it. 2755e4072d10b761c7e167c4f9b5d7570c6417c1d054Makoto Onuki if (mAppOps.noteOp(AppOpsManager.OP_WRITE_SMS, 2756e4072d10b761c7e167c4f9b5d7570c6417c1d054Makoto Onuki Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED) { 2757e4072d10b761c7e167c4f9b5d7570c6417c1d054Makoto Onuki return true; 2758e4072d10b761c7e167c4f9b5d7570c6417c1d054Makoto Onuki } 2759e4072d10b761c7e167c4f9b5d7570c6417c1d054Makoto Onuki try { 2760e4072d10b761c7e167c4f9b5d7570c6417c1d054Makoto Onuki return canReadPhoneState(callingPackage, message); 2761e4072d10b761c7e167c4f9b5d7570c6417c1d054Makoto Onuki } catch (SecurityException e) { 2762e4072d10b761c7e167c4f9b5d7570c6417c1d054Makoto Onuki // Can be read with READ_SMS too. 2763e4072d10b761c7e167c4f9b5d7570c6417c1d054Makoto Onuki mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_SMS, message); 2764e4072d10b761c7e167c4f9b5d7570c6417c1d054Makoto Onuki return mAppOps.noteOp(AppOpsManager.OP_READ_SMS, 2765e4072d10b761c7e167c4f9b5d7570c6417c1d054Makoto Onuki Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED; 2766e4072d10b761c7e167c4f9b5d7570c6417c1d054Makoto Onuki } 2767fee69345c86d13b46e9e1d1e36178ebef17538eeMakoto Onuki } 2768fee69345c86d13b46e9e1d1e36178ebef17538eeMakoto Onuki 27698eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott @Override 27708eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott public void factoryReset(int subId) { 27718eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott enforceConnectivityInternalPermission(); 2772981d85874294656a51683ae6ecc6ba312d3635ceStuart Scott if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) { 2773981d85874294656a51683ae6ecc6ba312d3635ceStuart Scott return; 2774981d85874294656a51683ae6ecc6ba312d3635ceStuart Scott } 2775981d85874294656a51683ae6ecc6ba312d3635ceStuart Scott 2776cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov final long identity = Binder.clearCallingIdentity(); 2777cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov try { 2778981d85874294656a51683ae6ecc6ba312d3635ceStuart Scott if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction( 2779981d85874294656a51683ae6ecc6ba312d3635ceStuart Scott UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) { 2780cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov // Enable data 2781cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov setDataEnabled(subId, true); 2782cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov // Set network selection mode to automatic 2783cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov setNetworkSelectionModeAutomatic(subId); 2784cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov // Set preferred mobile network type to the best available 2785cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov setPreferredNetworkType(subId, Phone.PREFERRED_NT_MODE); 2786cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov // Turn off roaming 2787cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov SubscriptionManager.from(mApp).setDataRoaming(0, subId); 2788cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov } 2789cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov } finally { 2790cc087f8219bf8dd606a46a18a2b0f57079c7ff8aSvet Ganov Binder.restoreCallingIdentity(identity); 27918eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott } 27928eef64f25181774c3112892ca222af3c1cf259c7Stuart Scott } 27931c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath 27941c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath @Override 27951c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath public String getLocaleFromDefaultSim() { 27961c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath // We query all subscriptions instead of just the active ones, because 27971c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath // this might be called early on in the provisioning flow when the 27981c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath // subscriptions potentially aren't active yet. 27991c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath final List<SubscriptionInfo> slist = getAllSubscriptionInfoList(); 28001c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath if (slist == null || slist.isEmpty()) { 28011c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath return null; 28021c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 28031c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath 28041c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath // This function may be called very early, say, from the setup wizard, at 28051c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath // which point we won't have a default subscription set. If that's the case 28061c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath // we just choose the first, which will be valid in "most cases". 28071c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath final int defaultSubId = getDefaultSubscription(); 28081c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath SubscriptionInfo info = null; 28091c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath if (defaultSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 28101c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath info = slist.get(0); 28111c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } else { 28121c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath for (SubscriptionInfo item : slist) { 28131c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath if (item.getSubscriptionId() == defaultSubId) { 28141c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath info = item; 28151c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath break; 28161c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 28171c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 28181c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath 28191c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath if (info == null) { 28201c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath return null; 28211c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 28221c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 28231c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath 28241c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath // Try and fetch the locale from the carrier properties or from the SIM language 28251c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath // preferences (EF-PL and EF-LI)... 2826183b2de07cb23d8bdf68d14e25cdae96c905b37bTony Hill final int mcc = info.getMcc(); 28271c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath final Phone defaultPhone = getPhone(info.getSubscriptionId()); 2828011676f979e1f0c8fd2d042a38e21cde5852789eNarayan Kamath String simLanguage = null; 28291c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath if (defaultPhone != null) { 28301c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath final Locale localeFromDefaultSim = defaultPhone.getLocaleFromSimAndCarrierPrefs(); 28311c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath if (localeFromDefaultSim != null) { 2832011676f979e1f0c8fd2d042a38e21cde5852789eNarayan Kamath if (!localeFromDefaultSim.getCountry().isEmpty()) { 2833183b2de07cb23d8bdf68d14e25cdae96c905b37bTony Hill if (DBG) log("Using locale from default SIM:" + localeFromDefaultSim); 2834183b2de07cb23d8bdf68d14e25cdae96c905b37bTony Hill return localeFromDefaultSim.toLanguageTag(); 2835011676f979e1f0c8fd2d042a38e21cde5852789eNarayan Kamath } else { 2836011676f979e1f0c8fd2d042a38e21cde5852789eNarayan Kamath simLanguage = localeFromDefaultSim.getLanguage(); 2837183b2de07cb23d8bdf68d14e25cdae96c905b37bTony Hill } 28381c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 28391c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 28401c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath 2841011676f979e1f0c8fd2d042a38e21cde5852789eNarayan Kamath // The SIM language preferences only store a language (e.g. fr = French), not an 2842011676f979e1f0c8fd2d042a38e21cde5852789eNarayan Kamath // exact locale (e.g. fr_FR = French/France). So, if the locale returned from 2843011676f979e1f0c8fd2d042a38e21cde5852789eNarayan Kamath // the SIM and carrier preferences does not include a country we add the country 2844011676f979e1f0c8fd2d042a38e21cde5852789eNarayan Kamath // determined from the SIM MCC to provide an exact locale. 2845011676f979e1f0c8fd2d042a38e21cde5852789eNarayan Kamath final Locale mccLocale = MccTable.getLocaleFromMcc(mPhone.getContext(), mcc, simLanguage); 2846183b2de07cb23d8bdf68d14e25cdae96c905b37bTony Hill if (mccLocale != null) { 2847183b2de07cb23d8bdf68d14e25cdae96c905b37bTony Hill if (DBG) log("No locale from default SIM, using mcc locale:" + mccLocale); 2848183b2de07cb23d8bdf68d14e25cdae96c905b37bTony Hill return mccLocale.toLanguageTag(); 28491c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 28501c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath 2851183b2de07cb23d8bdf68d14e25cdae96c905b37bTony Hill if (DBG) log("No locale found - returning null"); 28521c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath return null; 28531c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 28541c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath 28551c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath private List<SubscriptionInfo> getAllSubscriptionInfoList() { 28561c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath final long identity = Binder.clearCallingIdentity(); 28571c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath try { 28581c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath return mSubscriptionController.getAllSubInfoList( 28591c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath mPhone.getContext().getOpPackageName()); 28601c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } finally { 28611c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath Binder.restoreCallingIdentity(identity); 28621c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 28631c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 28641c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath 28651c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath private List<SubscriptionInfo> getActiveSubscriptionInfoList() { 28661c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath final long identity = Binder.clearCallingIdentity(); 28671c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath try { 28681c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath return mSubscriptionController.getActiveSubscriptionInfoList( 28691c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath mPhone.getContext().getOpPackageName()); 28701c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } finally { 28711c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath Binder.restoreCallingIdentity(identity); 28721c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 28731c496c28c4122c00f3c54ce8717fb767d1421bf6Narayan Kamath } 28747fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham 28757fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham /** 28767fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham * {@hide} 28777fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham * Returns the modem stats 28787fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham */ 28797fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham @Override 28807fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham public ModemActivityInfo getModemActivityInfo() { 28817fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham return (ModemActivityInfo) sendRequest(CMD_GET_MODEM_ACTIVITY_INFO, null); 28827fcff6902e3a8b5f54c5020edbbb8818dfcdcbffPrerepa Viswanadham } 28837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon} 2884