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; 217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.content.ActivityNotFoundException; 227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.content.Context; 237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.content.Intent; 247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.net.ConnectivityManager; 257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.net.Uri; 267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.AsyncResult; 277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Binder; 287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Bundle; 297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Handler; 307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Looper; 317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Message; 327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Process; 337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.ServiceManager; 347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.UserHandle; 357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.telephony.NeighboringCellInfo; 367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.telephony.CellInfo; 377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.telephony.ServiceState; 387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.text.TextUtils; 397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.util.Log; 407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.DefaultPhoneNotifier; 427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.IccCard; 437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.ITelephony; 447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.Phone; 457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.CallManager; 469de0f754068c82ed1d1019afb414bc1fcd9298cfWink Savilleimport com.android.internal.telephony.CommandException; 477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.PhoneConstants; 487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport java.util.List; 507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport java.util.ArrayList; 517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon/** 537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Implementation of the ITelephony interface. 547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonpublic class PhoneInterfaceManager extends ITelephony.Stub { 567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final String LOG_TAG = "PhoneInterfaceManager"; 577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2); 587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final boolean DBG_LOC = false; 597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Message codes used with mMainThreadHandler 617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_HANDLE_PIN_MMI = 1; 627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_HANDLE_NEIGHBORING_CELL = 2; 637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int EVENT_NEIGHBORING_CELL_DONE = 3; 647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_ANSWER_RINGING_CALL = 4; 657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_END_CALL = 5; // not used yet 667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CMD_SILENCE_RINGER = 6; 677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The singleton instance. */ 697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static PhoneInterfaceManager sInstance; 707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneGlobals mApp; 727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Phone mPhone; 737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CallManager mCM; 747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AppOpsManager mAppOps; 757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon MainThreadHandler mMainThreadHandler; 76406c0341600bd414fe7561b4edd8cdf7ed11f315Santos Cordon CallHandlerServiceProxy mCallHandlerService; 777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the 807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * request after sending. The main thread will notify the request when it is complete. 817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final class MainThreadRequest { 837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The argument to use for the request */ 847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public Object argument; 857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The result of the request that is run on the main thread */ 867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public Object result; 877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public MainThreadRequest(Object argument) { 897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon this.argument = argument; 907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * A handler that processes messages on the main thread in the phone process. Since many 957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * of the Phone calls are not thread safe this is needed to shuttle the requests from the 967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * inbound binder threads to the main thread in the phone process. The Binder thread 977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting 987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * on, which will be notified when the operation completes and will contain the result of the 997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * request. 1007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 1017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * <p>If a MainThreadRequest object is provided in the msg.obj field, 1027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * note that request.result must be set to something non-null for the calling thread to 1037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * unblock. 1047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 1057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private final class MainThreadHandler extends Handler { 1067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 1077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void handleMessage(Message msg) { 1087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon MainThreadRequest request; 1097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message onCompleted; 1107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AsyncResult ar; 1117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon switch (msg.what) { 1137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_HANDLE_PIN_MMI: 1147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) msg.obj; 1157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.result = Boolean.valueOf( 1167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.handlePinMmi((String) request.argument)); 1177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wake up the requesting thread 1187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 1197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.notifyAll(); 1207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 1227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_HANDLE_NEIGHBORING_CELL: 1247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) msg.obj; 1257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onCompleted = obtainMessage(EVENT_NEIGHBORING_CELL_DONE, 1267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request); 1277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.getNeighboringCids(onCompleted); 1287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 1297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case EVENT_NEIGHBORING_CELL_DONE: 1317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ar = (AsyncResult) msg.obj; 1327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) ar.userObj; 1337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (ar.exception == null && ar.result != null) { 1347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.result = ar.result; 1357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 1367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // create an empty list to notify the waiting thread 1377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.result = new ArrayList<NeighboringCellInfo>(); 1387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wake up the requesting thread 1407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 1417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.notifyAll(); 1427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 1447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_ANSWER_RINGING_CALL: 1467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon answerRingingCallInternal(); 1477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 1487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_SILENCE_RINGER: 1507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon silenceRingerInternal(); 1517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 1527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CMD_END_CALL: 1547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request = (MainThreadRequest) msg.obj; 1557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean hungUp = false; 1567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int phoneType = mPhone.getPhoneType(); 1577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { 1587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // CDMA: If the user presses the Power button we treat it as 1597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ending the complete call session 1607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon hungUp = PhoneUtils.hangupRingingAndActive(mPhone); 1617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) { 1627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // GSM: End the call as per the Phone state 1637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon hungUp = PhoneUtils.hangup(mCM); 1647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 1657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon throw new IllegalStateException("Unexpected phone type: " + phoneType); 1667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("CMD_END_CALL: " + (hungUp ? "hung up!" : "no call to hang up")); 1687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.result = hungUp; 1697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wake up the requesting thread 1707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 1717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.notifyAll(); 1727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 1747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon default: 1767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what); 1777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 1787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Posts the specified command to be executed on the main thread, 1847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * waits for the request to complete, and returns the result. 1857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #sendRequestAsync 1867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 1877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Object sendRequest(int command, Object argument) { 1887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (Looper.myLooper() == mMainThreadHandler.getLooper()) { 1897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon throw new RuntimeException("This method will deadlock if called from the main thread."); 1907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon MainThreadRequest request = new MainThreadRequest(argument); 1937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message msg = mMainThreadHandler.obtainMessage(command, request); 1947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon msg.sendToTarget(); 1957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Wait for the request to complete 1977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (request) { 1987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon while (request.result == null) { 1997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 2007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon request.wait(); 2017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 2027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Do nothing, go back and wait until the request is complete 2037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return request.result; 2077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 2107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Asynchronous ("fire and forget") version of sendRequest(): 2117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Posts the specified command to be executed on the main thread, and 2127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * returns immediately. 2137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #sendRequest 2147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 2157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void sendRequestAsync(int command) { 2167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mMainThreadHandler.sendEmptyMessage(command); 2177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 2207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Initialize the singleton PhoneInterfaceManager instance. 2217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This is only done once, at startup, from PhoneApp.onCreate(). 2227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 223406c0341600bd414fe7561b4edd8cdf7ed11f315Santos Cordon /* package */ static PhoneInterfaceManager init(PhoneGlobals app, Phone phone, 224406c0341600bd414fe7561b4edd8cdf7ed11f315Santos Cordon CallHandlerServiceProxy callHandlerService) { 2257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (PhoneInterfaceManager.class) { 2267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (sInstance == null) { 227406c0341600bd414fe7561b4edd8cdf7ed11f315Santos Cordon sInstance = new PhoneInterfaceManager(app, phone, callHandlerService); 2287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 2297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance); 2307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return sInstance; 2327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** Private constructor; @see init() */ 236406c0341600bd414fe7561b4edd8cdf7ed11f315Santos Cordon private PhoneInterfaceManager(PhoneGlobals app, Phone phone, 237406c0341600bd414fe7561b4edd8cdf7ed11f315Santos Cordon CallHandlerServiceProxy callHandlerService) { 2387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp = app; 2397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone = phone; 2407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCM = PhoneGlobals.getInstance().mCM; 2417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE); 2427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mMainThreadHandler = new MainThreadHandler(); 243406c0341600bd414fe7561b4edd8cdf7ed11f315Santos Cordon mCallHandlerService = callHandlerService; 2447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon publish(); 2457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void publish() { 2487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("publish: " + this); 2497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ServiceManager.addService("phone", this); 2517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 2547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Implementation of the ITelephony interface. 2557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 2567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void dial(String number) { 2587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("dial: " + number); 2597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No permission check needed here: This is just a wrapper around the 2607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ACTION_DIAL intent, which is available to any app since it puts up 2617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the UI before it does anything. 2627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon String url = createTelUrl(number); 2647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (url == null) { 2657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 2667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // PENDING: should we just silently fail if phone is offhook or ringing? 2697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneConstants.State state = mCM.getState(); 2707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) { 2717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url)); 2727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.startActivity(intent); 2747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void call(String callingPackage, String number) { 2787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("call: " + number); 2797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // This is just a wrapper around the ACTION_CALL intent, but we still 2817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // need to do a permission check since we're calling startActivity() 2827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // from the context of the phone app. 2837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceCallPermission(); 2847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mAppOps.noteOp(AppOpsManager.OP_CALL_PHONE, Binder.getCallingUid(), callingPackage) 2867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon != AppOpsManager.MODE_ALLOWED) { 2877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 2887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon String url = createTelUrl(number); 2917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (url == null) { 2927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 2937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url)); 2967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.startActivity(intent); 2987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private boolean showCallScreenInternal(boolean specifyInitialDialpadState, 301bcf2099b92870b863f53e79288d4c8e73a4dc42dMakoto Onuki boolean showDialpad) { 3027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!PhoneGlobals.sVoiceCapable) { 3037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Never allow the InCallScreen to appear on data-only devices. 3047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return false; 3057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (isIdle()) { 3077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return false; 3087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If the phone isn't idle then go to the in-call screen 3107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon long callingId = Binder.clearCallingIdentity(); 311406c0341600bd414fe7561b4edd8cdf7ed11f315Santos Cordon 312bcf2099b92870b863f53e79288d4c8e73a4dc42dMakoto Onuki mCallHandlerService.bringToForeground(showDialpad); 313406c0341600bd414fe7561b4edd8cdf7ed11f315Santos Cordon 314406c0341600bd414fe7561b4edd8cdf7ed11f315Santos Cordon Binder.restoreCallingIdentity(callingId); 3157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 3167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Show the in-call screen without specifying the initial dialpad state. 3197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean showCallScreen() { 3207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return showCallScreenInternal(false, false); 3217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // The variation of showCallScreen() that specifies the initial dialpad state. 3247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // (Ideally this would be called showCallScreen() too, just with a different 3257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // signature, but AIDL doesn't allow that.) 3267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean showCallScreenWithDialpad(boolean showDialpad) { 3277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return showCallScreenInternal(true, showDialpad); 3287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 3317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * End a call based on call state 3327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return true is a call was ended 3337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 3347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean endCall() { 3357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceCallPermission(); 3367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return (Boolean) sendRequest(CMD_END_CALL, null); 3377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void answerRingingCall() { 3407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("answerRingingCall..."); 3417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: there should eventually be a separate "ANSWER_PHONE" permission, 3427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // but that can probably wait till the big TelephonyManager API overhaul. 3437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For now, protect this call with the MODIFY_PHONE_STATE permission. 3447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 3457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon sendRequestAsync(CMD_ANSWER_RINGING_CALL); 3467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 3497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make the actual telephony calls to implement answerRingingCall(). 3507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This should only be called from the main thread of the Phone app. 3517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #answerRingingCall 3527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 3537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * TODO: it would be nice to return true if we answered the call, or 3547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * false if there wasn't actually a ringing incoming call, or some 3557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * other error occurred. (In other words, pass back the return value 3567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * from PhoneUtils.answerCall() or PhoneUtils.answerAndEndActive().) 3577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * But that would require calling this method via sendRequest() rather 3587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * than sendRequestAsync(), and right now we don't actually *need* that 3597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * return value, so let's just return void for now. 3607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 3617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void answerRingingCallInternal() { 3627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final boolean hasRingingCall = !mPhone.getRingingCall().isIdle(); 3637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (hasRingingCall) { 3647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final boolean hasActiveCall = !mPhone.getForegroundCall().isIdle(); 3657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final boolean hasHoldingCall = !mPhone.getBackgroundCall().isIdle(); 3667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (hasActiveCall && hasHoldingCall) { 3677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Both lines are in use! 3687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: provide a flag to let the caller specify what 3697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // policy to use if both lines are in use. (The current 3707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // behavior is hardwired to "answer incoming, end ongoing", 3717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // which is how the CALL button is specced to behave.) 3727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.answerAndEndActive(mCM, mCM.getFirstActiveRingingCall()); 3737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 3747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 3757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // answerCall() will automatically hold the current active 3767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // call, if there is one. 3777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.answerCall(mCM.getFirstActiveRingingCall()); 3787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 3797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 3817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No call was ringing. 3827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 3837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void silenceRinger() { 3877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("silenceRinger..."); 3887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: find a more appropriate permission to check here. 3897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // (That can probably wait till the big TelephonyManager API overhaul. 3907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For now, protect this call with the MODIFY_PHONE_STATE permission.) 3917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 3927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon sendRequestAsync(CMD_SILENCE_RINGER); 3937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 3967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Internal implemenation of silenceRinger(). 3977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This should only be called from the main thread of the Phone app. 3987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #silenceRinger 3997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 4007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void silenceRingerInternal() { 4017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((mCM.getState() == PhoneConstants.State.RINGING) 4027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon && mApp.notifier.isRinging()) { 4037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Ringer is actually playing, so silence it. 4047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("silenceRingerInternal: silencing..."); 4057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.notifier.silenceRinger(); 4067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isOffhook() { 4107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return (mCM.getState() == PhoneConstants.State.OFFHOOK); 4117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isRinging() { 4147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return (mCM.getState() == PhoneConstants.State.RINGING); 4157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isIdle() { 4187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return (mCM.getState() == PhoneConstants.State.IDLE); 4197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isSimPinEnabled() { 4227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceReadPermission(); 4237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return (PhoneGlobals.getInstance().isSimPinEnabled()); 4247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean supplyPin(String pin) { 4279de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville int [] resultArray = supplyPinReportResult(pin); 4289de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false; 4299de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 4309de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville 4319de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville public boolean supplyPuk(String puk, String pin) { 4329de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville int [] resultArray = supplyPukReportResult(puk, pin); 4339de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false; 4349de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 4359de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville 4369de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville /** {@hide} */ 4379de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville public int[] supplyPinReportResult(String pin) { 4387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 4397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final UnlockSim checkSimPin = new UnlockSim(mPhone.getIccCard()); 4407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon checkSimPin.start(); 4417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return checkSimPin.unlockSim(null, pin); 4427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4449de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville /** {@hide} */ 4459de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville public int[] supplyPukReportResult(String puk, String pin) { 4467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 4477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final UnlockSim checkSimPuk = new UnlockSim(mPhone.getIccCard()); 4487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon checkSimPuk.start(); 4497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return checkSimPuk.unlockSim(puk, pin); 4507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 4539de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville * Helper thread to turn async call to SimCard#supplyPin into 4547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * a synchronous one. 4557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 4567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static class UnlockSim extends Thread { 4577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private final IccCard mSimCard; 4597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private boolean mDone = false; 4619de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville private int mResult = PhoneConstants.PIN_GENERAL_FAILURE; 4629de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville private int mRetryCount = -1; 4637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For replies from SimCard interface 4657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Handler mHandler; 4667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // For async handler to identify request type 4687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int SUPPLY_PIN_COMPLETE = 100; 4697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public UnlockSim(IccCard simCard) { 4717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSimCard = simCard; 4727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 4757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void run() { 4767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Looper.prepare(); 4777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (UnlockSim.this) { 4787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mHandler = new Handler() { 4797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 4807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void handleMessage(Message msg) { 4817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AsyncResult ar = (AsyncResult) msg.obj; 4827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon switch (msg.what) { 4837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case SUPPLY_PIN_COMPLETE: 4847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE"); 4857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (UnlockSim.this) { 4869de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mRetryCount = msg.arg1; 4879de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville if (ar.exception != null) { 4889de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville if (ar.exception instanceof CommandException && 4899de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville ((CommandException)(ar.exception)).getCommandError() 4909de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville == CommandException.Error.PASSWORD_INCORRECT) { 4919de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mResult = PhoneConstants.PIN_PASSWORD_INCORRECT; 4929de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } else { 4939de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mResult = PhoneConstants.PIN_GENERAL_FAILURE; 4949de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 4959de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } else { 4969de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville mResult = PhoneConstants.PIN_RESULT_SUCCESS; 4979de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville } 4987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mDone = true; 4997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon UnlockSim.this.notifyAll(); 5007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 5027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon }; 5057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon UnlockSim.this.notifyAll(); 5067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Looper.loop(); 5087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* 5117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Use PIN or PUK to unlock SIM card 5127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 5137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * If PUK is null, unlock SIM card with PIN 5147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 5157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * If PUK is not null, unlock SIM card with PUK and set PIN code 5167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 5179de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville synchronized int[] unlockSim(String puk, String pin) { 5187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon while (mHandler == null) { 5207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 5217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon wait(); 5227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 5237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Thread.currentThread().interrupt(); 5247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE); 5277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (puk == null) { 5297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSimCard.supplyPin(pin, callback); 5307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 5317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSimCard.supplyPuk(puk, pin, callback); 5327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon while (!mDone) { 5357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 5367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "wait for done"); 5377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon wait(); 5387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 5397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Restore the interrupted status 5407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Thread.currentThread().interrupt(); 5417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "done"); 5449de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville int[] resultArray = new int[2]; 5459de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville resultArray[0] = mResult; 5469de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville resultArray[1] = mRetryCount; 5479de0f754068c82ed1d1019afb414bc1fcd9298cfWink Saville return resultArray; 5487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void updateServiceLocation() { 5527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No permission check needed here: this call is harmless, and it's 5537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // needed for the ServiceState.requestStateUpdate() call (which is 5547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // already intentionally exposed to 3rd parties.) 5557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.updateServiceLocation(); 5567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isRadioOn() { 5597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getServiceState().getVoiceRegState() != ServiceState.STATE_POWER_OFF; 5607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void toggleRadioOnOff() { 5637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 5647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.setRadioPower(!isRadioOn()); 5657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean setRadio(boolean turnOn) { 5677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 5687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((mPhone.getServiceState().getVoiceRegState() != ServiceState.STATE_POWER_OFF) != turnOn) { 5697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toggleRadioOnOff(); 5707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 5727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean setRadioPower(boolean turnOn) { 5747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 5757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.setRadioPower(turnOn); 5767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 5777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean enableDataConnectivity() { 5807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 5817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ConnectivityManager cm = 5827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (ConnectivityManager)mApp.getSystemService(Context.CONNECTIVITY_SERVICE); 5837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon cm.setMobileDataEnabled(true); 5847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 5857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int enableApnType(String type) { 5887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 5897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.enableApnType(type); 5907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int disableApnType(String type) { 5937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 5947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.disableApnType(type); 5957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean disableDataConnectivity() { 5987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 5997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ConnectivityManager cm = 6007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (ConnectivityManager)mApp.getSystemService(Context.CONNECTIVITY_SERVICE); 6017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon cm.setMobileDataEnabled(false); 6027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 6037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean isDataConnectivityPossible() { 6067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.isDataConnectivityPossible(); 6077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean handlePinMmi(String dialString) { 6107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 6117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString); 6127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void cancelMissedCallsNotification() { 6157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon enforceModifyPermission(); 6167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.notificationMgr.cancelMissedCallNotification(); 6177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getCallState() { 6207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return DefaultPhoneNotifier.convertCallState(mCM.getState()); 6217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getDataState() { 6247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return DefaultPhoneNotifier.convertDataState(mPhone.getDataConnectionState()); 6257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getDataActivity() { 6287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return DefaultPhoneNotifier.convertDataActivityState(mPhone.getDataActivityState()); 6297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 6327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public Bundle getCellLocation() { 6337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 6347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 6357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_FINE_LOCATION, null); 6367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (SecurityException e) { 6377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If we have ACCESS_FINE_LOCATION permission, skip the check for ACCESS_COARSE_LOCATION 6387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // A failure should throw the SecurityException from ACCESS_COARSE_LOCATION since this 6397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // is the weaker precondition 6407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 6417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 6427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (checkIfCallerIsSelfOrForegoundUser()) { 6457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getCellLocation: is active user"); 6467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Bundle data = new Bundle(); 6477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.getCellLocation().fillInNotifierBundle(data); 6487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return data; 6497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 6507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getCellLocation: suppress non-active user"); 6517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 6527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 6567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void enableLocationUpdates() { 6577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 6587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.CONTROL_LOCATION_UPDATES, null); 6597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.enableLocationUpdates(); 6607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 6637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void disableLocationUpdates() { 6647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 6657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.CONTROL_LOCATION_UPDATES, null); 6667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.disableLocationUpdates(); 6677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 6707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @SuppressWarnings("unchecked") 6717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage) { 6727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 6737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 6747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_FINE_LOCATION, null); 6757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (SecurityException e) { 6767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If we have ACCESS_FINE_LOCATION permission, skip the check 6777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // for ACCESS_COARSE_LOCATION 6787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // A failure should throw the SecurityException from 6797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ACCESS_COARSE_LOCATION since this is the weaker precondition 6807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 6817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 6827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(), 6857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon callingPackage) != AppOpsManager.MODE_ALLOWED) { 6867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 6877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (checkIfCallerIsSelfOrForegoundUser()) { 6897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getNeighboringCellInfo: is active user"); 6907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ArrayList<NeighboringCellInfo> cells = null; 6927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 6947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon cells = (ArrayList<NeighboringCellInfo>) sendRequest( 6957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CMD_HANDLE_NEIGHBORING_CELL, null); 6967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (RuntimeException e) { 6977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.e(LOG_TAG, "getNeighboringCellInfo " + e); 6987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return cells; 7007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 7017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getNeighboringCellInfo: suppress non-active user"); 7027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 7037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 7087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public List<CellInfo> getAllCellInfo() { 7097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 7107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 7117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_FINE_LOCATION, null); 7127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (SecurityException e) { 7137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If we have ACCESS_FINE_LOCATION permission, skip the check for ACCESS_COARSE_LOCATION 7147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // A failure should throw the SecurityException from ACCESS_COARSE_LOCATION since this 7157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // is the weaker precondition 7167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission( 7177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 7187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (checkIfCallerIsSelfOrForegoundUser()) { 7217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getAllCellInfo: is active user"); 7227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getAllCellInfo(); 7237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 7247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("getAllCellInfo: suppress non-active user"); 7257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 7267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void setCellInfoListRate(int rateInMillis) { 7307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPhone.setCellInfoListRate(rateInMillis); 7317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 7347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Internal helper methods. 7357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 7367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private boolean checkIfCallerIsSelfOrForegoundUser() { 7387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean ok; 7397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean self = Binder.getCallingUid() == Process.myUid(); 7417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!self) { 7427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Get the caller's user id then clear the calling identity 7437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // which will be restored in the finally clause. 7447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int callingUser = UserHandle.getCallingUserId(); 7457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon long ident = Binder.clearCallingIdentity(); 7467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 7487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // With calling identity cleared the current user is the foreground user. 7497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int foregroundUser = ActivityManager.getCurrentUser(); 7507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ok = (foregroundUser == callingUser); 7517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) { 7527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon log("checkIfCallerIsSelfOrForegoundUser: foregroundUser=" + foregroundUser 7537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon + " callingUser=" + callingUser + " ok=" + ok); 7547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (Exception ex) { 7567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) loge("checkIfCallerIsSelfOrForegoundUser: Exception ex=" + ex); 7577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ok = false; 7587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } finally { 7597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Binder.restoreCallingIdentity(ident); 7607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 7627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("checkIfCallerIsSelfOrForegoundUser: is self"); 7637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ok = true; 7647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG_LOC) log("checkIfCallerIsSelfOrForegoundUser: ret=" + ok); 7667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return ok; 7677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 7707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make sure the caller has the READ_PHONE_STATE permission. 7717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 7727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @throws SecurityException if the caller does not have the required permission 7737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 7747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void enforceReadPermission() { 7757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE, null); 7767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 7797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make sure the caller has the MODIFY_PHONE_STATE permission. 7807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 7817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @throws SecurityException if the caller does not have the required permission 7827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 7837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void enforceModifyPermission() { 7847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null); 7857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 7887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Make sure the caller has the CALL_PHONE permission. 7897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 7907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @throws SecurityException if the caller does not have the required permission 7917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 7927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void enforceCallPermission() { 7937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null); 7947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private String createTelUrl(String number) { 7987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (TextUtils.isEmpty(number)) { 7997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return null; 8007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon StringBuilder buf = new StringBuilder("tel:"); 8037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon buf.append(number); 8047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return buf.toString(); 8057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void log(String msg) { 8087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg); 8097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void loge(String msg) { 8127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg); 8137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getActivePhoneType() { 8167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getPhoneType(); 8177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 8207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the CDMA ERI icon index to display 8217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 8227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getCdmaEriIconIndex() { 8237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getCdmaEriIconIndex(); 8247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 8277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the CDMA ERI icon mode, 8287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 0 - ON 8297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 1 - FLASHING 8307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 8317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getCdmaEriIconMode() { 8327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getCdmaEriIconMode(); 8337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 8367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the CDMA ERI text, 8377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 8387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public String getCdmaEriText() { 8397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getCdmaEriText(); 8407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 8437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns true if CDMA provisioning needs to run. 8447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 8457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean needsOtaServiceProvisioning() { 8467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.needsOtaServiceProvisioning(); 8477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 8507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the unread count of voicemails 8517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 8527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getVoiceMessageCount() { 8537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getVoiceMessageCount(); 8547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 8577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the data network type 8587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 8597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @Deprecated to be removed Q3 2013 use {@link #getDataNetworkType}. 8607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 8617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 8627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getNetworkType() { 8637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getServiceState().getDataNetworkType(); 8647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 8677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the data network type 8687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 8697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 8707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getDataNetworkType() { 8717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getServiceState().getDataNetworkType(); 8727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 8757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Returns the data network type 8767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 8777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 8787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getVoiceNetworkType() { 8797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getServiceState().getVoiceNetworkType(); 8807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 8837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return true if a ICC card is present 8847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 8857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public boolean hasIccCard() { 8867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getIccCard().hasIccCard(); 8877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 8907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Return if the current radio is LTE on CDMA. This 8917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * is a tri-state return value as for a period of time 8927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * the mode may be unknown. 8937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 8947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE} 8957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * or {@link PHone#LTE_ON_CDMA_TRUE} 8967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 8977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public int getLteOnCdmaMode() { 8987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPhone.getLteOnCdmaMode(); 8997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon} 901