Merge kwd to master
Add support for type and subid to Call.java
Add MSIM and IMS to PhoneInterfaceManager
Change-Id: Idb607c0aa32f80fe4fe1539aedea7a221e9e7f04
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 7c89b50..c71ea79 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -21,6 +21,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.AsyncResult;
import android.os.Binder;
@@ -37,6 +38,7 @@
import android.telephony.CellInfo;
import android.telephony.NeighboringCellInfo;
import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
@@ -49,13 +51,19 @@
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.CallManager;
+import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.dataconnection.DctController;
import com.android.internal.telephony.uicc.IccIoResult;
import com.android.internal.telephony.uicc.IccUtils;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.util.HexDump;
import com.android.services.telephony.common.Call;
+import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -463,6 +471,15 @@
* @see #sendRequestAsync
*/
private Object sendRequest(int command, Object argument) {
+ return sendRequest(command, argument);
+ }
+
+ /**
+ * Posts the specified command to be executed on the main thread,
+ * waits for the request to complete, and returns the result.
+ * @see #sendRequestAsync
+ */
+ private Object sendRequest(int command, Object argument, Object argument2) {
if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
throw new RuntimeException("This method will deadlock if called from the main thread.");
}
@@ -538,11 +555,22 @@
ServiceManager.addService("phone", this);
}
+ // returns phone associated with the subId.
+ // getPhone(0) returns default phone in single SIM mode.
+ private Phone getPhone(long subId) {
+ // FIXME: hack for the moment
+ return mPhone;
+ // return PhoneUtils.getPhoneUsingSubId(subId);
+ }
//
// Implementation of the ITelephony interface.
//
public void dial(String number) {
+ dialUsingSubId(getPreferredVoiceSubscription(), number);
+ }
+
+ public void dialUsingSubId(long subId, String number) {
if (DBG) log("dial: " + number);
// No permission check needed here: This is just a wrapper around the
// ACTION_DIAL intent, which is available to any app since it puts up
@@ -554,15 +582,20 @@
}
// PENDING: should we just silently fail if phone is offhook or ringing?
- PhoneConstants.State state = mCM.getState();
+ PhoneConstants.State state = mCM.getState(subId);
if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.putExtra(SUBSCRIPTION_KEY, subId);
mApp.startActivity(intent);
}
}
public void call(String callingPackage, String number) {
+ callUsingSubId(getPreferredVoiceSubscription(), callingPackage, number);
+ }
+
+ public void callUsingSubId(long subId, String callingPackage, String number) {
if (DBG) log("call: " + number);
// This is just a wrapper around the ACTION_CALL intent, but we still
@@ -581,6 +614,7 @@
}
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
+ intent.putExtra(SUBSCRIPTION_KEY, subId);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mApp.startActivity(intent);
}
@@ -590,11 +624,23 @@
* @return true is a call was ended
*/
public boolean endCall() {
+ return endCallUsingSubId(getDefaultSubscription());
+ }
+
+ /**
+ * End a call based on the call state of the subId
+ * @return true is a call was ended
+ */
+ public boolean endCallUsingSubId(long subId) {
enforceCallPermission();
- return (Boolean) sendRequest(CMD_END_CALL, null);
+ return (Boolean) sendRequest(CMD_END_CALL, subId, null);
}
public void answerRingingCall() {
+ answerRingingCallUsingSubId(getDefaultSubscription());
+ }
+
+ public void answerRingingCallUsingSubId(long subId) {
if (DBG) log("answerRingingCall...");
// TODO: there should eventually be a separate "ANSWER_PHONE" permission,
// but that can probably wait till the big TelephonyManager API overhaul.
@@ -665,15 +711,27 @@
}
public boolean isOffhook() {
- return (mCM.getState() == PhoneConstants.State.OFFHOOK);
+ return isOffhookUsingSubId(getDefaultSubscription());
+ }
+
+ public boolean isOffhookUsingSubId(long subId) {
+ return (getPhone(subId).getState() == PhoneConstants.State.OFFHOOK);
}
public boolean isRinging() {
- return (mCM.getState() == PhoneConstants.State.RINGING);
+ return (isRingingUsingSubId(getDefaultSubscription()));
+ }
+
+ public boolean isRingingUsingSubId(long subId) {
+ return (getPhone(subId).getState() == PhoneConstants.State.RINGING);
}
public boolean isIdle() {
- return (mCM.getState() == PhoneConstants.State.IDLE);
+ return isIdleUsingSubId(getDefaultSubscription());
+ }
+
+ public boolean isIdleUsingSubId(long subId) {
+ return (getPhone(subId).getState() == PhoneConstants.State.IDLE);
}
public boolean isSimPinEnabled() {
@@ -682,27 +740,43 @@
}
public boolean supplyPin(String pin) {
- int [] resultArray = supplyPinReportResult(pin);
+ return supplyPinUsingSubId(getDefaultSubscription(), pin);
+ }
+
+ public boolean supplyPinUsingSubId(long subId, String pin) {
+ int [] resultArray = supplyPinReportResultUsingSubId(subId, pin);
return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
}
public boolean supplyPuk(String puk, String pin) {
- int [] resultArray = supplyPukReportResult(puk, pin);
+ return supplyPukUsingSubId(getDefaultSubscription(), puk, pin);
+ }
+
+ public boolean supplyPukUsingSubId(long subId, String puk, String pin) {
+ int [] resultArray = supplyPukReportResultUsingSubId(subId, puk, pin);
return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
}
/** {@hide} */
public int[] supplyPinReportResult(String pin) {
+ return supplyPinReportResultUsingSubId(getDefaultSubscription(), pin);
+ }
+
+ public int[] supplyPinReportResultUsingSubId(long subId, String pin) {
enforceModifyPermission();
- final UnlockSim checkSimPin = new UnlockSim(mPhone.getIccCard());
+ final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard());
checkSimPin.start();
return checkSimPin.unlockSim(null, pin);
}
/** {@hide} */
public int[] supplyPukReportResult(String puk, String pin) {
+ return supplyPukReportResultUsingSubId(getDefaultSubscription(), puk, pin);
+ }
+
+ public int[] supplyPukReportResultUsingSubId(long subId, String puk, String pin) {
enforceModifyPermission();
- final UnlockSim checkSimPuk = new UnlockSim(mPhone.getIccCard());
+ final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard());
checkSimPuk.start();
return checkSimPuk.unlockSim(puk, pin);
}
@@ -807,79 +881,140 @@
}
public void updateServiceLocation() {
+ updateServiceLocationUsingSubId(getDefaultSubscription());
+
+ }
+
+ public void updateServiceLocationUsingSubId(long subId) {
// No permission check needed here: this call is harmless, and it's
// needed for the ServiceState.requestStateUpdate() call (which is
// already intentionally exposed to 3rd parties.)
- mPhone.updateServiceLocation();
+ getPhone(subId).updateServiceLocation();
}
public boolean isRadioOn() {
- return mPhone.getServiceState().getVoiceRegState() != ServiceState.STATE_POWER_OFF;
+ return isRadioOnUsingSubId(getDefaultSubscription());
+ }
+
+ public boolean isRadioOnUsingSubId(long subId) {
+ return getPhone(subId).getServiceState().getState() != ServiceState.STATE_POWER_OFF;
}
public void toggleRadioOnOff() {
- enforceModifyPermission();
- mPhone.setRadioPower(!isRadioOn());
+ toggleRadioOnOffUsingSubId(getDefaultSubscription());
+
}
- public boolean setRadio(boolean turnOn) {
+
+ public void toggleRadioOnOffUsingSubId(long subId) {
enforceModifyPermission();
- if ((mPhone.getServiceState().getVoiceRegState() != ServiceState.STATE_POWER_OFF) != turnOn) {
- toggleRadioOnOff();
+ getPhone(subId).setRadioPower(!isRadioOnUsingSubId(subId));
+ }
+
+ public boolean setRadio(boolean turnOn) {
+ return setRadioUsingSubId(getDefaultSubscription(), turnOn);
+ }
+
+ public boolean setRadioUsingSubId(long subId, boolean turnOn) {
+ enforceModifyPermission();
+ if ((getPhone(subId).getServiceState().getState() !=
+ ServiceState.STATE_POWER_OFF) != turnOn) {
+ toggleRadioOnOffUsingSubId(subId);
}
return true;
}
+
public boolean setRadioPower(boolean turnOn) {
+ return setRadioPowerUsingSubId(getDefaultSubscription(), turnOn);
+ }
+
+ public boolean setRadioPowerUsingSubId(long subId, boolean turnOn) {
enforceModifyPermission();
- mPhone.setRadioPower(turnOn);
+ getPhone(subId).setRadioPower(turnOn);
return true;
}
+ // FIXME: subId version needed
public boolean enableDataConnectivity() {
enforceModifyPermission();
- mPhone.setDataEnabled(true);
+ long subId = SubscriptionManager.getDefaultDataSubId();
+ getPhone(subId).setDataEnabled(true);
return true;
}
+ public int enableApnTypeUsingSub(long subId, String type) {
+ enforceModifyPermission();
+ log("enableApnTypeUsingSub subId = " + subId);
+ return DctController.getInstance().enableApnType(subId, type);
+ }
+
+ public int disableApnTypeUsingSub(long subId, String type) {
+ enforceModifyPermission();
+ log("enableApnTypeUsingSub subId = " + subId);
+ return DctController.getInstance().disableApnType(subId, type);
+ }
+
+ // FIXME: subId version needed
public int enableApnType(String type) {
enforceModifyPermission();
- return mPhone.enableApnType(type);
+ long subId = SubscriptionManager.getDefaultDataSubId();
+ return getPhone(subId).enableApnType(type);
}
+ // FIXME: subId version needed
public int disableApnType(String type) {
enforceModifyPermission();
- return mPhone.disableApnType(type);
+ long subId = SubscriptionManager.getDefaultDataSubId();
+ return getPhone(subId).disableApnType(type);
}
+ // FIXME: subId version needed
public boolean disableDataConnectivity() {
enforceModifyPermission();
- mPhone.setDataEnabled(false);
+ long subId = SubscriptionManager.getDefaultDataSubId();
+ getPhone(subId).setDataEnabled(false);
return true;
}
+ // FIXME: subId version needed
public boolean isDataConnectivityPossible() {
- return mPhone.isDataConnectivityPossible();
+ long subId = SubscriptionManager.getDefaultDataSubId();
+ return getPhone(subId).isDataConnectivityPossible();
}
public boolean handlePinMmi(String dialString) {
+ return handlePinMmiUsingSubId(getDefaultSubscription(), dialString);
+ }
+
+ public boolean handlePinMmiUsingSubId(long subId, String dialString) {
enforceModifyPermission();
- return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString);
+ return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
}
public void cancelMissedCallsNotification() {
+ cancelMissedCallsNotificationUsingSubId(getDefaultSubscription());
+ }
+
+ public void cancelMissedCallsNotificationUsingSubId(long subId) {
enforceModifyPermission();
mApp.notificationMgr.cancelMissedCallNotification();
}
public int getCallState() {
- return DefaultPhoneNotifier.convertCallState(mCM.getState());
+ return getCallStateUsingSubId(getDefaultSubscription());
+ }
+
+ public int getCallStateUsingSubId(long subId) {
+ return DefaultPhoneNotifier.convertCallState(getPhone(subId).getState());
}
public int getDataState() {
- return DefaultPhoneNotifier.convertDataState(mPhone.getDataConnectionState());
+ Phone phone = getPhone(SubscriptionManager.getDefaultDataSubId());
+ return DefaultPhoneNotifier.convertDataState(phone.getDataConnectionState());
}
public int getDataActivity() {
- return DefaultPhoneNotifier.convertDataActivityState(mPhone.getDataActivityState());
+ Phone phone = getPhone(SubscriptionManager.getDefaultDataSubId());
+ return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState());
}
@Override
@@ -908,16 +1043,24 @@
@Override
public void enableLocationUpdates() {
+ enableLocationUpdatesUsingSubId(getDefaultSubscription());
+ }
+
+ public void enableLocationUpdatesUsingSubId(long subId) {
mApp.enforceCallingOrSelfPermission(
android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
- mPhone.enableLocationUpdates();
+ getPhone(subId).enableLocationUpdates();
}
@Override
public void disableLocationUpdates() {
+ disableLocationUpdatesUsingSubId(getDefaultSubscription());
+ }
+
+ public void disableLocationUpdatesUsingSubId(long subId) {
mApp.enforceCallingOrSelfPermission(
android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
- mPhone.disableLocationUpdates();
+ getPhone(subId).disableLocationUpdates();
}
@Override
@@ -946,9 +1089,9 @@
try {
cells = (ArrayList<NeighboringCellInfo>) sendRequest(
- CMD_HANDLE_NEIGHBORING_CELL, null);
+ CMD_HANDLE_NEIGHBORING_CELL, null, null);
} catch (RuntimeException e) {
- loge("getNeighboringCellInfo " + e);
+ Log.e(LOG_TAG, "getNeighboringCellInfo " + e);
}
return cells;
} else {
@@ -1084,14 +1227,23 @@
}
public int getActivePhoneType() {
- return mPhone.getPhoneType();
+ return getActivePhoneTypeUsingSubId(getDefaultSubscription());
+ }
+
+ public int getActivePhoneTypeUsingSubId(long subId) {
+ return getPhone(subId).getPhoneType();
}
/**
* Returns the CDMA ERI icon index to display
*/
public int getCdmaEriIconIndex() {
- return mPhone.getCdmaEriIconIndex();
+ return getCdmaEriIconIndexUsingSubId(getDefaultSubscription());
+
+ }
+
+ public int getCdmaEriIconIndexUsingSubId(long subId) {
+ return getPhone(subId).getCdmaEriIconIndex();
}
/**
@@ -1100,14 +1252,22 @@
* 1 - FLASHING
*/
public int getCdmaEriIconMode() {
- return mPhone.getCdmaEriIconMode();
+ return getCdmaEriIconModeUsingSubId(getDefaultSubscription());
+ }
+
+ public int getCdmaEriIconModeUsingSubId(long subId) {
+ return getPhone(subId).getCdmaEriIconMode();
}
/**
* Returns the CDMA ERI text,
*/
public String getCdmaEriText() {
- return mPhone.getCdmaEriText();
+ return getCdmaEriTextUsingSubId(getDefaultSubscription());
+ }
+
+ public String getCdmaEriTextUsingSubId(long subId) {
+ return getPhone(subId).getCdmaEriText();
}
/**
@@ -1121,7 +1281,14 @@
* Returns the unread count of voicemails
*/
public int getVoiceMessageCount() {
- return mPhone.getVoiceMessageCount();
+ return getVoiceMessageCountUsingSubId(getDefaultSubscription());
+ }
+
+ /**
+ * Returns the unread count of voicemails for a subId
+ */
+ public int getVoiceMessageCountUsingSubId( long subId) {
+ return getPhone(subId).getVoiceMessageCount();
}
/**
@@ -1131,7 +1298,15 @@
*/
@Override
public int getNetworkType() {
- return mPhone.getServiceState().getDataNetworkType();
+ return getNetworkTypeUsingSubId(getDefaultSubscription());
+ }
+
+ /**
+ * Returns the network type for a subId
+ */
+ @Override
+ public int getNetworkTypeUsingSubId(long subId) {
+ return getPhone(subId).getServiceState().getDataNetworkType();
}
/**
@@ -1139,7 +1314,15 @@
*/
@Override
public int getDataNetworkType() {
- return mPhone.getServiceState().getDataNetworkType();
+ return getDataNetworkTypeUsingSubId(getDefaultSubscription());
+ }
+
+ /**
+ * Returns the data network type for a subId
+ */
+ @Override
+ public int getDataNetworkTypeUsingSubId(long subId) {
+ return getPhone(subId).getServiceState().getDataNetworkType();
}
/**
@@ -1147,14 +1330,30 @@
*/
@Override
public int getVoiceNetworkType() {
- return mPhone.getServiceState().getVoiceNetworkType();
+ return getVoiceNetworkTypeUsingSubId(getDefaultSubscription());
+ }
+
+ /**
+ * Returns the Voice network type for a subId
+ */
+ @Override
+ public int getVoiceNetworkTypeUsingSubId(long subId) {
+ return getPhone(subId).getServiceState().getVoiceNetworkType();
}
/**
* @return true if a ICC card is present
*/
public boolean hasIccCard() {
- return mPhone.getIccCard().hasIccCard();
+ // FIXME Make changes to pass defaultSimId of type int
+ return hasIccCardUsingSlotId(getDefaultSubscription());
+ }
+
+ /**
+ * @return true if a ICC card is present for a slotId
+ */
+ public boolean hasIccCardUsingSlotId(long slotId) {
+ return getPhone(slotId).getIccCard().hasIccCard();
}
/**
@@ -1166,7 +1365,27 @@
* or {@link Phone#LTE_ON_CDMA_TRUE}
*/
public int getLteOnCdmaMode() {
- return mPhone.getLteOnCdmaMode();
+ return getLteOnCdmaModeUsingSubId(getDefaultSubscription());
+ }
+
+ public int getLteOnCdmaModeUsingSubId(long subId) {
+ return getPhone(subId).getLteOnCdmaMode();
+ }
+
+ public void setPhone(Phone phone) {
+ mPhone = phone;
+ }
+
+ /**
+ * {@hide}
+ * Returns Default subId, 0 in the case of single standby.
+ */
+ private long getDefaultSubscription() {
+ return SubscriptionManager.getDefaultSubId();
+ }
+
+ private long getPreferredVoiceSubscription() {
+ return SubscriptionManager.getDefaultVoiceSubId();
}
/**
@@ -1329,6 +1548,25 @@
}
/**
+ * {@hide}
+ * Returns Default sim, 0 in the case of single standby.
+ */
+ public int getDefaultSim() {
+ //TODO Need to get it from Telephony Devcontroller
+ return 0;
+ }
+
+ public String[] getPcscfAddress() {
+ enforceReadPermission();
+ return mPhone.getPcscfAddress();
+ }
+
+ public void setImsRegistrationState(boolean registered) {
+ enforceModifyPermission();
+ mPhone.setImsRegistrationState(registered);
+ }
+
+ /**
* Get the preferred network type.
* Used for device configuration by some CDMA operators.
*