Merge kwd to master
Add initial IMS and MSIM support from klp-wireless-dev-mirror
Change-Id: Idb607c0aa32f80fe4fe1539aedea7a221e9e7f04
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index cfaf016..9d92421 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -33,10 +33,13 @@
import android.os.UserHandle;
import android.telephony.CellLocation;
import android.telephony.DataConnectionRealTimeInfo;
+import android.telephony.TelephonyManager;
+import android.telephony.SubscriptionManager;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.CellInfo;
+import android.telephony.VoLteServiceState;
import android.telephony.TelephonyManager;
import android.telephony.DisconnectCause;
import android.telephony.PreciseCallState;
@@ -65,8 +68,9 @@
*/
class TelephonyRegistry extends ITelephonyRegistry.Stub {
private static final String TAG = "TelephonyRegistry";
- private static final boolean DBG = false;
- private static final boolean DBG_LOC = false;
+ private static final boolean DBG = false; // STOPSHIP if true
+ private static final boolean DBG_LOC = false; // STOPSHIP if true
+ private static final boolean VDBG = false; // STOPSHIP if true
private static class Record {
String pkgForDebug;
@@ -79,6 +83,10 @@
int events;
+ long subId;
+
+ boolean isLegacyApp;
+
@Override
public String toString() {
return "{pkgForDebug=" + pkgForDebug + " callerUid=" + callerUid +
@@ -94,41 +102,47 @@
private final IBatteryStats mBatteryStats;
- private int mCallState = TelephonyManager.CALL_STATE_IDLE;
+ private int mNumPhones;
- private String mCallIncomingNumber = "";
+ private int[] mCallState;
- private ServiceState mServiceState = new ServiceState();
+ private String[] mCallIncomingNumber;
- private SignalStrength mSignalStrength = new SignalStrength();
+ private ServiceState[] mServiceState;
- private boolean mMessageWaiting = false;
+ private SignalStrength[] mSignalStrength;
- private boolean mCallForwarding = false;
+ private boolean[] mMessageWaiting;
- private int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
+ private boolean[] mCallForwarding;
- private int mDataConnectionState = TelephonyManager.DATA_UNKNOWN;
+ private int[] mDataActivity;
- private boolean mDataConnectionPossible = false;
+ private int[] mDataConnectionState;
- private String mDataConnectionReason = "";
+ private boolean[] mDataConnectionPossible;
- private String mDataConnectionApn = "";
+ private String[] mDataConnectionReason;
+
+ private String[] mDataConnectionApn;
private ArrayList<String> mConnectedApns;
- private LinkProperties mDataConnectionLinkProperties;
+ private LinkProperties[] mDataConnectionLinkProperties;
- private NetworkCapabilities mDataConnectionNetworkCapabilities;
+ private NetworkCapabilities[] mDataConnectionNetworkCapabilities;
- private Bundle mCellLocation = new Bundle();
+ private Bundle[] mCellLocation;
- private int mDataConnectionNetworkType;
+ private int[] mDataConnectionNetworkType;
private int mOtaspMode = ServiceStateTracker.OTASP_UNKNOWN;
- private List<CellInfo> mCellInfo = null;
+ private ArrayList<List<CellInfo>> mCellInfo = null;
+
+ private VoLteServiceState mVoLteServiceState = new VoLteServiceState();
+
+ private long mDefaultSubId;
private DataConnectionRealTimeInfo mDcRtInfo = new DataConnectionRealTimeInfo();
@@ -148,21 +162,40 @@
PhoneStateListener.LISTEN_CALL_STATE |
PhoneStateListener.LISTEN_DATA_ACTIVITY |
PhoneStateListener.LISTEN_DATA_CONNECTION_STATE |
- PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR;
+ PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR |
+ PhoneStateListener.LISTEN_VOLTE_STATE;;
static final int PRECISE_PHONE_STATE_PERMISSION_MASK =
PhoneStateListener.LISTEN_PRECISE_CALL_STATE |
PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE;
private static final int MSG_USER_SWITCHED = 1;
+ private static final int MSG_UPDATE_DEFAULT_SUB = 2;
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_USER_SWITCHED: {
- if (DBG) Slog.d(TAG, "MSG_USER_SWITCHED userId=" + msg.arg1);
- TelephonyRegistry.this.notifyCellLocation(mCellLocation);
+ Slog.d(TAG, "MSG_USER_SWITCHED userId=" + msg.arg1);
+ int numPhones = TelephonyManager.getDefault().getPhoneCount();
+ for (int sub = 0; sub < numPhones; sub++) {
+ TelephonyRegistry.this.notifyCellLocationUsingSubId(sub, mCellLocation[sub]);
+ }
+ break;
+ }
+ case MSG_UPDATE_DEFAULT_SUB: {
+ Slog.d(TAG, "MSG_UPDATE_DEFAULT_SUB subid=" + mDefaultSubId);
+ // Default subscription id changed, update the changed default subscription
+ // id in all the legacy application listener records.
+ synchronized (mRecords) {
+ for (Record r : mRecords) {
+ // FIXME: Be sure we're using isLegacyApp correctly!
+ if (r.isLegacyApp == true) {
+ r.subId = mDefaultSubId;
+ }
+ }
+ }
break;
}
}
@@ -173,9 +206,14 @@
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
+ Slog.d(TAG, "mBroadcastReceiver: action=" + action);
if (Intent.ACTION_USER_SWITCHED.equals(action)) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHED,
intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0), 0));
+ } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_SUBSCRIPTION_CHANGED)) {
+ mDefaultSubId = intent.getLongExtra(PhoneConstants.SUBSCRIPTION_KEY,
+ SubscriptionManager.getDefaultSubId());
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE_DEFAULT_SUB, 0, 0));
}
}
};
@@ -190,13 +228,55 @@
TelephonyRegistry(Context context) {
CellLocation location = CellLocation.getEmpty();
+ mContext = context;
+ mBatteryStats = BatteryStatsService.getService();
+ mConnectedApns = new ArrayList<String>();
+
+ // Initialize default subscription to be used for single standby.
+ mDefaultSubId = SubscriptionManager.getDefaultSubId();
+
+ int numPhones = TelephonyManager.getDefault().getPhoneCount();
+ if (DBG) Slog.d(TAG, "TelephonyRegistor: ctor numPhones=" + numPhones);
+ mNumPhones = numPhones;
+ mCallState = new int[numPhones];
+ mDataActivity = new int[numPhones];
+ mDataConnectionState = new int[numPhones];
+ mDataConnectionNetworkType = new int[numPhones];
+ mCallIncomingNumber = new String[numPhones];
+ mServiceState = new ServiceState[numPhones];
+ mSignalStrength = new SignalStrength[numPhones];
+ mMessageWaiting = new boolean[numPhones];
+ mDataConnectionPossible = new boolean[numPhones];
+ mDataConnectionReason = new String[numPhones];
+ mDataConnectionApn = new String[numPhones];
+ mCallForwarding = new boolean[numPhones];
+ mCellLocation = new Bundle[numPhones];
+ mDataConnectionLinkProperties = new LinkProperties[numPhones];
+ mDataConnectionNetworkCapabilities = new NetworkCapabilities[numPhones];
+ mCellInfo = new ArrayList<List<CellInfo>>();
+ for (int i = 0; i < numPhones; i++) {
+ mCallState[i] = TelephonyManager.CALL_STATE_IDLE;
+ mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE;
+ mDataConnectionState[i] = TelephonyManager.DATA_UNKNOWN;
+ mCallIncomingNumber[i] = "";
+ mServiceState[i] = new ServiceState();
+ mSignalStrength[i] = new SignalStrength();
+ mMessageWaiting[i] = false;
+ mCallForwarding[i] = false;
+ mDataConnectionPossible[i] = false;
+ mDataConnectionReason[i] = "";
+ mDataConnectionApn[i] = "";
+ mCellLocation[i] = new Bundle();
+ mCellInfo.add(i, null);
+ }
+
// Note that location can be null for non-phone builds like
// like the generic one.
if (location != null) {
- location.fillInNotifierBundle(mCellLocation);
+ for (int i = 0; i < numPhones; i++) {
+ location.fillInNotifierBundle(mCellLocation[i]);
+ }
}
- mContext = context;
- mBatteryStats = BatteryStatsService.getService();
mConnectedApns = new ArrayList<String>();
}
@@ -205,16 +285,31 @@
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_SWITCHED);
filter.addAction(Intent.ACTION_USER_REMOVED);
+ filter.addAction(TelephonyIntents.ACTION_DEFAULT_SUBSCRIPTION_CHANGED);
+ Slog.d(TAG, "systemRunning register for intents");
mContext.registerReceiver(mBroadcastReceiver, filter);
}
@Override
public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
boolean notifyNow) {
+ listen(pkgForDebug, callback, events, notifyNow, mDefaultSubId, true);
+ }
+
+ @Override
+ public void listenUsingSubId(long subId, String pkgForDebug, IPhoneStateListener callback,
+ int events, boolean notifyNow) {
+ listen(pkgForDebug, callback, events, notifyNow, subId, false);
+ }
+
+ private void listen(String pkgForDebug, IPhoneStateListener callback, int events,
+ boolean notifyNow, long subId, boolean isLegacyApp) {
int callerUid = UserHandle.getCallingUserId();
int myUid = UserHandle.myUserId();
- if (DBG) {
+ if (VDBG) {
Slog.d(TAG, "listen: E pkg=" + pkgForDebug + " events=0x" + Integer.toHexString(events)
+ + " notifyNow=" + notifyNow + " subId=" + subId
+ + " isLegacyApp=" + isLegacyApp
+ " myUid=" + myUid
+ " callerUid=" + callerUid);
}
@@ -239,22 +334,37 @@
r.callback = callback;
r.pkgForDebug = pkgForDebug;
r.callerUid = callerUid;
+ r.subId = subId;
+ r.isLegacyApp = isLegacyApp;
+ // Legacy applications pass invalid subId(-1), based on
+ // the received subId value update the isLegacyApp field
+ if ((r.subId <= 0) || (r.subId == SubscriptionManager.INVALID_SUB_ID)) {
+ r.subId = mDefaultSubId;
+ r.isLegacyApp = true; // FIXME: is this needed ??
+ }
+ if (r.subId == SubscriptionManager.DEFAULT_SUB_ID) {
+ r.subId = mDefaultSubId;
+ if (DBG) Slog.i(TAG, "listen: DEFAULT_SUB_ID");
+ }
mRecords.add(r);
if (DBG) Slog.i(TAG, "listen: add new record=" + r);
}
+ int phoneId = SubscriptionManager.getPhoneId(subId);
int send = events & (events ^ r.events);
r.events = events;
- if (notifyNow) {
+ if (notifyNow && validatePhoneId(phoneId)) {
if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
try {
- r.callback.onServiceStateChanged(new ServiceState(mServiceState));
+ r.callback.onServiceStateChanged(
+ new ServiceState(mServiceState[phoneId]));
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
try {
- int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
+ int gsmSignalStrength = mSignalStrength[phoneId]
+ .getGsmSignalStrength();
r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
: gsmSignalStrength));
} catch (RemoteException ex) {
@@ -263,51 +373,56 @@
}
if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
try {
- r.callback.onMessageWaitingIndicatorChanged(mMessageWaiting);
+ r.callback.onMessageWaitingIndicatorChanged(
+ mMessageWaiting[phoneId]);
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
try {
- r.callback.onCallForwardingIndicatorChanged(mCallForwarding);
+ r.callback.onCallForwardingIndicatorChanged(
+ mCallForwarding[phoneId]);
} catch (RemoteException ex) {
remove(r.binder);
}
}
if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
try {
- if (DBG_LOC) Slog.d(TAG, "listen: mCellLocation=" + mCellLocation);
- r.callback.onCellLocationChanged(new Bundle(mCellLocation));
+ if (DBG_LOC) Slog.d(TAG, "listen: mCellLocation = "
+ + mCellLocation[phoneId]);
+ r.callback.onCellLocationChanged(
+ new Bundle(mCellLocation[phoneId]));
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
try {
- r.callback.onCallStateChanged(mCallState, mCallIncomingNumber);
+ r.callback.onCallStateChanged(mCallState[phoneId],
+ mCallIncomingNumber[phoneId]);
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
try {
- r.callback.onDataConnectionStateChanged(mDataConnectionState,
- mDataConnectionNetworkType);
+ r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId],
+ mDataConnectionNetworkType[phoneId]);
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
try {
- r.callback.onDataActivity(mDataActivity);
+ r.callback.onDataActivity(mDataActivity[phoneId]);
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
try {
- r.callback.onSignalStrengthsChanged(mSignalStrength);
+ r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]);
} catch (RemoteException ex) {
remove(r.binder);
}
@@ -321,8 +436,9 @@
}
if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) {
try {
- if (DBG_LOC) Slog.d(TAG, "listen: mCellInfo=" + mCellInfo);
- r.callback.onCellInfoChanged(mCellInfo);
+ if (DBG_LOC) Slog.d(TAG, "listen: mCellInfo[" + phoneId + "] = "
+ + mCellInfo.get(phoneId));
+ r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
} catch (RemoteException ex) {
remove(r.binder);
}
@@ -373,10 +489,10 @@
return;
}
synchronized (mRecords) {
- mCallState = state;
- mCallIncomingNumber = incomingNumber;
for (Record r : mRecords) {
- if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
+ if (((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) &&
+ (r.isLegacyApp == true)) {
+ // FIXME: why does isLegacyApp need to be true?
try {
r.callback.onCallStateChanged(state, incomingNumber);
} catch (RemoteException ex) {
@@ -386,82 +502,148 @@
}
handleRemoveListLocked();
}
- broadcastCallStateChanged(state, incomingNumber);
+ broadcastCallStateChanged(state, incomingNumber, mDefaultSubId);
}
- public void notifyServiceState(ServiceState state) {
+ public void notifyCallStateUsingSubId(long subId, int state, String incomingNumber) {
+ if (!checkNotifyPermission("notifyCallState()")) {
+ return;
+ }
+ if (VDBG) {
+ Slog.d(TAG, "notifyCallStateUsingSubId: subId=" + subId
+ + " state=" + state + " incomingNumber=" + incomingNumber);
+ }
+ synchronized (mRecords) {
+ int phoneId = SubscriptionManager.getPhoneId(subId);
+ if (validatePhoneId(phoneId)) {
+ mCallState[phoneId] = state;
+ mCallIncomingNumber[phoneId] = incomingNumber;
+ for (Record r : mRecords) {
+ if (((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) &&
+ (r.subId == subId) && (r.isLegacyApp == false)) {
+ // FIXME: why isLegacyApp false?
+ try {
+ r.callback.onCallStateChanged(state, incomingNumber);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
+ }
+ }
+ }
+ handleRemoveListLocked();
+ }
+ broadcastCallStateChanged(state, incomingNumber, subId);
+ }
+
+ public void notifyServiceState(ServiceState state) {
+ notifyServiceStateUsingSubId(mDefaultSubId, state);
+ }
+
+ public void notifyServiceStateUsingSubId(long subId, ServiceState state) {
if (!checkNotifyPermission("notifyServiceState()")){
return;
}
- long ident = Binder.clearCallingIdentity();
- try {
- mBatteryStats.notePhoneState(state.getState());
- } catch (RemoteException re) {
- // Can't do much
- } finally {
- Binder.restoreCallingIdentity(ident);
+ if (subId == SubscriptionManager.DEFAULT_SUB_ID) {
+ subId = mDefaultSubId;
+ Slog.d(TAG, "notifyServiceStateUsingSubId: using mDefaultSubId=" + mDefaultSubId);
+ }
+ if (VDBG) {
+ Slog.d(TAG, "notifyServiceStateUsingSubId: subId=" + subId
+ + " state=" + state);
}
synchronized (mRecords) {
- mServiceState = state;
- for (Record r : mRecords) {
- if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
- try {
- r.callback.onServiceStateChanged(new ServiceState(state));
- } catch (RemoteException ex) {
- mRemoveList.add(r.binder);
+ int phoneId = SubscriptionManager.getPhoneId(subId);
+ if (validatePhoneId(phoneId)) {
+ mServiceState[phoneId] = state;
+ for (Record r : mRecords) {
+ // FIXME: use DEFAULT_SUB_ID instead??
+ if (((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) &&
+ (r.subId == subId)) {
+ try {
+ r.callback.onServiceStateChanged(new ServiceState(state));
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
}
}
+ } else {
+ Slog.d(TAG, "notifyServiceStateUsingSubId: INVALID phoneId=" + phoneId);
}
handleRemoveListLocked();
}
- broadcastServiceStateChanged(state);
+ broadcastServiceStateChanged(state, subId);
}
public void notifySignalStrength(SignalStrength signalStrength) {
+ notifySignalStrengthUsingSubId(mDefaultSubId, signalStrength);
+ }
+
+ public void notifySignalStrengthUsingSubId(long subId, SignalStrength signalStrength) {
if (!checkNotifyPermission("notifySignalStrength()")) {
return;
}
+ if (VDBG) {
+ Slog.d(TAG, "notifySignalStrengthUsingSubId: subId=" + subId
+ + " signalStrength=" + signalStrength);
+ }
synchronized (mRecords) {
- mSignalStrength = signalStrength;
- for (Record r : mRecords) {
- if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
- try {
- r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
- } catch (RemoteException ex) {
- mRemoveList.add(r.binder);
+ int phoneId = SubscriptionManager.getPhoneId(subId);
+ if (validatePhoneId(phoneId)) {
+ mSignalStrength[phoneId] = signalStrength;
+ for (Record r : mRecords) {
+ if (((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) &&
+ (r.subId == subId)){
+ try {
+ r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
}
- }
- if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
- try {
- int gsmSignalStrength = signalStrength.getGsmSignalStrength();
- r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
- : gsmSignalStrength));
- } catch (RemoteException ex) {
- mRemoveList.add(r.binder);
+ if (((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) &&
+ (r.subId == subId)) {
+ try {
+ int gsmSignalStrength = signalStrength.getGsmSignalStrength();
+ r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
+ : gsmSignalStrength));
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
}
}
}
handleRemoveListLocked();
}
- broadcastSignalStrengthChanged(signalStrength);
+ broadcastSignalStrengthChanged(signalStrength, subId);
}
public void notifyCellInfo(List<CellInfo> cellInfo) {
+ notifyCellInfoUsingSubId(mDefaultSubId, cellInfo);
+ }
+
+ public void notifyCellInfoUsingSubId(long subId, List<CellInfo> cellInfo) {
if (!checkNotifyPermission("notifyCellInfo()")) {
return;
}
+ if (VDBG) {
+ Slog.d(TAG, "notifyCellInfoUsingSubId: subId=" + subId
+ + " cellInfo=" + cellInfo);
+ }
synchronized (mRecords) {
- mCellInfo = cellInfo;
- for (Record r : mRecords) {
- if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) {
- try {
- if (DBG_LOC) {
- Slog.d(TAG, "notifyCellInfo: mCellInfo=" + mCellInfo + " r=" + r);
+ int phoneId = SubscriptionManager.getPhoneId(subId);
+ if (validatePhoneId(phoneId)) {
+ mCellInfo.set(phoneId, cellInfo);
+ for (Record r : mRecords) {
+ if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)
+ && r.subId == subId) {
+ try {
+ if (DBG_LOC) {
+ Slog.d(TAG, "notifyCellInfo: mCellInfo=" + cellInfo + " r=" + r);
+ }
+ r.callback.onCellInfoChanged(cellInfo);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
}
- r.callback.onCellInfoChanged(cellInfo);
- } catch (RemoteException ex) {
- mRemoveList.add(r.binder);
}
}
}
@@ -495,17 +677,29 @@
}
public void notifyMessageWaitingChanged(boolean mwi) {
+ notifyMessageWaitingChangedUsingSubId(mDefaultSubId, mwi);
+ }
+
+ public void notifyMessageWaitingChangedUsingSubId(long subId, boolean mwi) {
if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
return;
}
+ if (VDBG) {
+ Slog.d(TAG, "notifyMessageWaitingChangedUsingSubId: subId=" + subId
+ + " mwi=" + mwi);
+ }
synchronized (mRecords) {
- mMessageWaiting = mwi;
- for (Record r : mRecords) {
- if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
- try {
- r.callback.onMessageWaitingIndicatorChanged(mwi);
- } catch (RemoteException ex) {
- mRemoveList.add(r.binder);
+ int phoneId = SubscriptionManager.getPhoneId(subId);
+ if (validatePhoneId(phoneId)) {
+ mMessageWaiting[phoneId] = mwi;
+ for (Record r : mRecords) {
+ if (((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) &&
+ (r.subId == subId)) {
+ try {
+ r.callback.onMessageWaitingIndicatorChanged(mwi);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
}
}
}
@@ -514,17 +708,29 @@
}
public void notifyCallForwardingChanged(boolean cfi) {
+ notifyCallForwardingChangedUsingSubId(mDefaultSubId, cfi);
+ }
+
+ public void notifyCallForwardingChangedUsingSubId(long subId, boolean cfi) {
if (!checkNotifyPermission("notifyCallForwardingChanged()")) {
return;
}
+ if (VDBG) {
+ Slog.d(TAG, "notifyCallForwardingChangedUsingSubId: subId=" + subId
+ + " cfi=" + cfi);
+ }
synchronized (mRecords) {
- mCallForwarding = cfi;
- for (Record r : mRecords) {
- if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
- try {
- r.callback.onCallForwardingIndicatorChanged(cfi);
- } catch (RemoteException ex) {
- mRemoveList.add(r.binder);
+ int phoneId = SubscriptionManager.getPhoneId(subId);
+ if (validatePhoneId(phoneId)) {
+ mCallForwarding[phoneId] = cfi;
+ for (Record r : mRecords) {
+ if (((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) &&
+ (r.subId == subId)) {
+ try {
+ r.callback.onCallForwardingIndicatorChanged(cfi);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
}
}
}
@@ -533,11 +739,16 @@
}
public void notifyDataActivity(int state) {
+ notifyDataActivityUsingSubId(mDefaultSubId, state);
+ }
+
+ public void notifyDataActivityUsingSubId(long subId, int state) {
if (!checkNotifyPermission("notifyDataActivity()" )) {
return;
}
synchronized (mRecords) {
- mDataActivity = state;
+ int phoneId = SubscriptionManager.getPhoneId(subId);
+ mDataActivity[phoneId] = state;
for (Record r : mRecords) {
if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
try {
@@ -554,29 +765,40 @@
public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
String reason, String apn, String apnType, LinkProperties linkProperties,
NetworkCapabilities networkCapabilities, int networkType, boolean roaming) {
+ notifyDataConnectionUsingSubId(mDefaultSubId, state, isDataConnectivityPossible,
+ reason, apn, apnType, linkProperties,
+ networkCapabilities, networkType, roaming);
+ }
+
+ public void notifyDataConnectionUsingSubId(long subId, int state,
+ boolean isDataConnectivityPossible, String reason, String apn, String apnType,
+ LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
+ int networkType, boolean roaming) {
if (!checkNotifyPermission("notifyDataConnection()" )) {
return;
}
- if (DBG) {
- Slog.i(TAG, "notifyDataConnection: state=" + state + " isDataConnectivityPossible="
- + isDataConnectivityPossible + " reason='" + reason
+ if (VDBG) {
+ Slog.i(TAG, "notifyDataConnectionUsingSubId: subId=" + subId
+ + " state=" + state + " isDataConnectivityPossible=" + isDataConnectivityPossible
+ + " reason='" + reason
+ "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType
+ " mRecords.size()=" + mRecords.size() + " mRecords=" + mRecords);
}
synchronized (mRecords) {
+ int phoneId = SubscriptionManager.getPhoneId(subId);
boolean modified = false;
if (state == TelephonyManager.DATA_CONNECTED) {
if (!mConnectedApns.contains(apnType)) {
mConnectedApns.add(apnType);
- if (mDataConnectionState != state) {
- mDataConnectionState = state;
+ if (mDataConnectionState[phoneId] != state) {
+ mDataConnectionState[phoneId] = state;
modified = true;
}
}
} else {
if (mConnectedApns.remove(apnType)) {
if (mConnectedApns.isEmpty()) {
- mDataConnectionState = state;
+ mDataConnectionState[phoneId] = state;
modified = true;
} else {
// leave mDataConnectionState as is and
@@ -584,25 +806,28 @@
}
}
}
- mDataConnectionPossible = isDataConnectivityPossible;
- mDataConnectionReason = reason;
- mDataConnectionLinkProperties = linkProperties;
- mDataConnectionNetworkCapabilities = networkCapabilities;
- if (mDataConnectionNetworkType != networkType) {
- mDataConnectionNetworkType = networkType;
+ mDataConnectionPossible[phoneId] = isDataConnectivityPossible;
+ mDataConnectionReason[phoneId] = reason;
+ mDataConnectionLinkProperties[phoneId] = linkProperties;
+ mDataConnectionNetworkCapabilities[phoneId] = networkCapabilities;
+ if (mDataConnectionNetworkType[phoneId] != networkType) {
+ mDataConnectionNetworkType[phoneId] = networkType;
// need to tell registered listeners about the new network type
modified = true;
}
if (modified) {
if (DBG) {
- Slog.d(TAG, "onDataConnectionStateChanged(" + mDataConnectionState
- + ", " + mDataConnectionNetworkType + ")");
+ Slog.d(TAG, "onDataConnectionStateChanged(" + mDataConnectionState[phoneId]
+ + ", " + mDataConnectionNetworkType[phoneId] + ")");
}
for (Record r : mRecords) {
- if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
+ if (((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) &&
+ (r.subId == subId)) {
try {
- r.callback.onDataConnectionStateChanged(mDataConnectionState,
- mDataConnectionNetworkType);
+ Slog.d(TAG,"Notify data connection state changed on sub: " +
+ subId);
+ r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId],
+ mDataConnectionNetworkType[phoneId]);
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
@@ -624,15 +849,24 @@
handleRemoveListLocked();
}
broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
- apnType, linkProperties, networkCapabilities, roaming);
+ apnType, linkProperties, networkCapabilities, roaming, subId);
broadcastPreciseDataConnectionStateChanged(state, networkType, apnType, apn, reason,
linkProperties, "");
}
public void notifyDataConnectionFailed(String reason, String apnType) {
+ notifyDataConnectionFailedUsingSubId(mDefaultSubId, reason, apnType);
+ }
+
+ public void notifyDataConnectionFailedUsingSubId(long subId,
+ String reason, String apnType) {
if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
return;
}
+ if (VDBG) {
+ Slog.d(TAG, "notifyDataConnectionFailedUsingSubId: subId=" + subId
+ + " reason=" + reason + " apnType=" + apnType);
+ }
synchronized (mRecords) {
mPreciseDataConnectionState = new PreciseDataConnectionState(
TelephonyManager.DATA_UNKNOWN,TelephonyManager.NETWORK_TYPE_UNKNOWN,
@@ -648,29 +882,42 @@
}
handleRemoveListLocked();
}
- broadcastDataConnectionFailed(reason, apnType);
+ broadcastDataConnectionFailed(reason, apnType, subId);
broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN,
TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, "", reason, null, "");
}
public void notifyCellLocation(Bundle cellLocation) {
+ notifyCellLocationUsingSubId(mDefaultSubId, cellLocation);
+ }
+
+ public void notifyCellLocationUsingSubId(long subId, Bundle cellLocation) {
+ Slog.d(TAG, "notifyCellLocationUsingSubId: subId=" + subId
+ + " cellLocation=" + cellLocation);
if (!checkNotifyPermission("notifyCellLocation()")) {
return;
}
+ if (VDBG) {
+ Slog.d(TAG, "notifyCellLocationUsingSubId: subId=" + subId
+ + " cellLocation=" + cellLocation);
+ }
synchronized (mRecords) {
- mCellLocation = cellLocation;
- for (Record r : mRecords) {
- if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
- try {
- if (DBG_LOC) {
- Slog.d(TAG, "notifyCellLocation: mCellLocation=" + mCellLocation
- + " r=" + r);
+ int phoneId = SubscriptionManager.getPhoneId(subId);
+ if (validatePhoneId(phoneId)) {
+ mCellLocation[phoneId] = cellLocation;
+ for (Record r : mRecords) {
+ if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)
+ && r.subId == subId) {
+ try {
+ if (DBG_LOC) {
+ Slog.d(TAG, "notifyCellLocation: cellLocation=" + cellLocation
+ + " r=" + r);
+ }
+ r.callback.onCellLocationChanged(new Bundle(cellLocation));
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
}
- r.callback.onCellLocationChanged(new Bundle(cellLocation));
- } catch (RemoteException ex) {
- mRemoveList.add(r.binder);
}
-
}
}
handleRemoveListLocked();
@@ -771,6 +1018,26 @@
TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, reason, null, failCause);
}
+ public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) {
+ if (!checkNotifyPermission("notifyVoLteServiceStateChanged()")) {
+ return;
+ }
+ synchronized (mRecords) {
+ mVoLteServiceState = lteState;
+ for (Record r : mRecords) {
+ if ((r.events & PhoneStateListener.LISTEN_VOLTE_STATE) != 0) {
+ try {
+ r.callback.onVoLteServiceStateChanged(
+ new VoLteServiceState(mVoLteServiceState));
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
+ }
+ }
+ handleRemoveListLocked();
+ }
+ }
+
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
@@ -810,15 +1077,26 @@
// the legacy intent broadcasting
//
- private void broadcastServiceStateChanged(ServiceState state) {
+ private void broadcastServiceStateChanged(ServiceState state, long subId) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ mBatteryStats.notePhoneState(state.getState());
+ } catch (RemoteException re) {
+ // Can't do much
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+
Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Bundle data = new Bundle();
state.fillInNotifierBundle(data);
intent.putExtras(data);
+ // Pass the subscription along with the intent.
+ intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
- private void broadcastSignalStrengthChanged(SignalStrength signalStrength) {
+ private void broadcastSignalStrengthChanged(SignalStrength signalStrength, long subId) {
long ident = Binder.clearCallingIdentity();
try {
mBatteryStats.notePhoneSignalStrength(signalStrength);
@@ -833,10 +1111,11 @@
Bundle data = new Bundle();
signalStrength.fillInNotifierBundle(data);
intent.putExtras(data);
+ intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
- private void broadcastCallStateChanged(int state, String incomingNumber) {
+ private void broadcastCallStateChanged(int state, String incomingNumber, long subId) {
long ident = Binder.clearCallingIdentity();
try {
if (state == TelephonyManager.CALL_STATE_IDLE) {
@@ -856,6 +1135,7 @@
if (!TextUtils.isEmpty(incomingNumber)) {
intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
}
+ intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
android.Manifest.permission.READ_PHONE_STATE);
}
@@ -863,7 +1143,7 @@
private void broadcastDataConnectionStateChanged(int state,
boolean isDataConnectivityPossible,
String reason, String apn, String apnType, LinkProperties linkProperties,
- NetworkCapabilities networkCapabilities, boolean roaming) {
+ NetworkCapabilities networkCapabilities, boolean roaming, long subId) {
// Note: not reporting to the battery stats service here, because the
// status bar takes care of that after taking into account all of the
// required info.
@@ -890,13 +1170,16 @@
intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
+ intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
- private void broadcastDataConnectionFailed(String reason, String apnType) {
+ private void broadcastDataConnectionFailed(String reason, String apnType,
+ long subId) {
Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason);
intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
+ intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
@@ -989,4 +1272,10 @@
}
return valid;
}
+
+ private boolean validatePhoneId(int phoneId) {
+ boolean valid = (phoneId >= 0) && (phoneId < mNumPhones);
+ if (VDBG) Slog.d(TAG, "validatePhoneId: " + valid);
+ return valid;
+ }
}