summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server/TelephonyRegistry.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com/android/server/TelephonyRegistry.java')
-rw-r--r--services/java/com/android/server/TelephonyRegistry.java246
1 files changed, 153 insertions, 93 deletions
diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java
index 3370279..eb14180 100644
--- a/services/java/com/android/server/TelephonyRegistry.java
+++ b/services/java/com/android/server/TelephonyRegistry.java
@@ -19,7 +19,8 @@ package com.android.server;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.net.NetworkUtils;
+import android.net.LinkCapabilities;
+import android.net.LinkProperties;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
@@ -35,12 +36,14 @@ import android.util.Slog;
import java.util.ArrayList;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.net.NetworkInterface;
import com.android.internal.app.IBatteryStats;
import com.android.internal.telephony.ITelephonyRegistry;
import com.android.internal.telephony.IPhoneStateListener;
import com.android.internal.telephony.DefaultPhoneNotifier;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyIntents;
import com.android.server.am.BatteryStatsService;
@@ -63,7 +66,9 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
private final Context mContext;
- private final ArrayList<Record> mRecords = new ArrayList();
+ // access should be inside synchronized (mRecords) for these two fields
+ private final ArrayList<IBinder> mRemoveList = new ArrayList<IBinder>();
+ private final ArrayList<Record> mRecords = new ArrayList<Record>();
private final IBatteryStats mBatteryStats;
@@ -81,7 +86,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
private int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
- private int mDataConnectionState = TelephonyManager.DATA_CONNECTED;
+ private int mDataConnectionState = TelephonyManager.DATA_UNKNOWN;
private boolean mDataConnectionPossible = false;
@@ -89,14 +94,18 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
private String mDataConnectionApn = "";
- private String[] mDataConnectionApnTypes = null;
+ private ArrayList<String> mConnectedApns;
- private String mDataConnectionInterfaceName = "";
+ private LinkProperties mDataConnectionLinkProperties;
+
+ private LinkCapabilities mDataConnectionLinkCapabilities;
private Bundle mCellLocation = new Bundle();
private int mDataConnectionNetworkType;
+ private int mOtaspMode = ServiceStateTracker.OTASP_UNKNOWN;
+
static final int PHONE_STATE_PERMISSION_MASK =
PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR |
PhoneStateListener.LISTEN_CALL_STATE |
@@ -121,6 +130,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
mContext = context;
mBatteryStats = BatteryStatsService.getService();
+ mConnectedApns = new ArrayList<String>();
}
public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
@@ -153,7 +163,11 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
r.events = events;
if (notifyNow) {
if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
- sendServiceState(r, mServiceState);
+ try {
+ r.callback.onServiceStateChanged(new ServiceState(mServiceState));
+ } catch (RemoteException ex) {
+ remove(r.binder);
+ }
}
if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
try {
@@ -179,7 +193,11 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
}
if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
- sendCellLocation(r, mCellLocation);
+ try {
+ r.callback.onCellLocationChanged(new Bundle(mCellLocation));
+ } catch (RemoteException ex) {
+ remove(r.binder);
+ }
}
if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
try {
@@ -210,6 +228,13 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
remove(r.binder);
}
}
+ if ((events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) {
+ try {
+ r.callback.onOtaspChanged(mOtaspMode);
+ } catch (RemoteException ex) {
+ remove(r.binder);
+ }
+ }
}
}
} else {
@@ -236,16 +261,16 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
synchronized (mRecords) {
mCallState = state;
mCallIncomingNumber = incomingNumber;
- for (int i = mRecords.size() - 1; i >= 0; i--) {
- Record r = mRecords.get(i);
+ for (Record r : mRecords) {
if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
try {
r.callback.onCallStateChanged(state, incomingNumber);
} catch (RemoteException ex) {
- remove(r.binder);
+ mRemoveList.add(r.binder);
}
}
}
+ handleRemoveListLocked();
}
broadcastCallStateChanged(state, incomingNumber);
}
@@ -257,12 +282,16 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
Slog.i(TAG, "notifyServiceState: " + state);
synchronized (mRecords) {
mServiceState = state;
- for (int i = mRecords.size() - 1; i >= 0; i--) {
- Record r = mRecords.get(i);
+ for (Record r : mRecords) {
if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
- sendServiceState(r, state);
+ try {
+ r.callback.onServiceStateChanged(new ServiceState(state));
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
}
}
+ handleRemoveListLocked();
}
broadcastServiceStateChanged(state);
}
@@ -273,10 +302,13 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
synchronized (mRecords) {
mSignalStrength = signalStrength;
- for (int i = mRecords.size() - 1; i >= 0; i--) {
- Record r = mRecords.get(i);
+ for (Record r : mRecords) {
if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
- sendSignalStrength(r, signalStrength);
+ try {
+ r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
}
if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
try {
@@ -284,10 +316,11 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
: gsmSignalStrength));
} catch (RemoteException ex) {
- remove(r.binder);
+ mRemoveList.add(r.binder);
}
}
}
+ handleRemoveListLocked();
}
broadcastSignalStrengthChanged(signalStrength);
}
@@ -296,19 +329,18 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
return;
}
- Slog.i(TAG, "notifyMessageWaitingChanged: " + mwi);
synchronized (mRecords) {
mMessageWaiting = mwi;
- for (int i = mRecords.size() - 1; i >= 0; i--) {
- Record r = mRecords.get(i);
+ for (Record r : mRecords) {
if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
try {
r.callback.onMessageWaitingIndicatorChanged(mwi);
} catch (RemoteException ex) {
- remove(r.binder);
+ mRemoveList.add(r.binder);
}
}
}
+ handleRemoveListLocked();
}
}
@@ -316,19 +348,18 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
if (!checkNotifyPermission("notifyCallForwardingChanged()")) {
return;
}
- Slog.i(TAG, "notifyCallForwardingChanged: " + cfi);
synchronized (mRecords) {
mCallForwarding = cfi;
- for (int i = mRecords.size() - 1; i >= 0; i--) {
- Record r = mRecords.get(i);
+ for (Record r : mRecords) {
if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
try {
r.callback.onCallForwardingIndicatorChanged(cfi);
} catch (RemoteException ex) {
- remove(r.binder);
+ mRemoveList.add(r.binder);
}
}
}
+ handleRemoveListLocked();
}
}
@@ -338,58 +369,83 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
synchronized (mRecords) {
mDataActivity = state;
- for (int i = mRecords.size() - 1; i >= 0; i--) {
- Record r = mRecords.get(i);
+ for (Record r : mRecords) {
if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
try {
r.callback.onDataActivity(state);
} catch (RemoteException ex) {
- remove(r.binder);
+ mRemoveList.add(r.binder);
}
}
}
+ handleRemoveListLocked();
}
}
public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
- String reason, String apn, String[] apnTypes, String interfaceName, int networkType,
- String gateway) {
+ String reason, String apn, String apnType, LinkProperties linkProperties,
+ LinkCapabilities linkCapabilities, int networkType) {
if (!checkNotifyPermission("notifyDataConnection()" )) {
return;
}
Slog.i(TAG, "notifyDataConnection: state=" + state + " isDataConnectivityPossible="
- + isDataConnectivityPossible + " reason=" + reason
- + " interfaceName=" + interfaceName + " networkType=" + networkType);
+ + isDataConnectivityPossible + " reason='" + reason
+ + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType);
synchronized (mRecords) {
- mDataConnectionState = state;
+ boolean modified = false;
+ if (state == TelephonyManager.DATA_CONNECTED) {
+ if (!mConnectedApns.contains(apnType)) {
+ mConnectedApns.add(apnType);
+ if (mDataConnectionState != state) {
+ mDataConnectionState = state;
+ modified = true;
+ }
+ }
+ } else {
+ if (mConnectedApns.remove(apnType)) {
+ if (mConnectedApns.isEmpty()) {
+ mDataConnectionState = state;
+ modified = true;
+ } else {
+ // leave mDataConnectionState as is and
+ // send out the new status for the APN in question.
+ }
+ }
+ }
mDataConnectionPossible = isDataConnectivityPossible;
mDataConnectionReason = reason;
- mDataConnectionApn = apn;
- mDataConnectionApnTypes = apnTypes;
- mDataConnectionInterfaceName = interfaceName;
- mDataConnectionNetworkType = networkType;
- for (int i = mRecords.size() - 1; i >= 0; i--) {
- Record r = mRecords.get(i);
- if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
- try {
- r.callback.onDataConnectionStateChanged(state, networkType);
- } catch (RemoteException ex) {
- remove(r.binder);
+ mDataConnectionLinkProperties = linkProperties;
+ mDataConnectionLinkCapabilities = linkCapabilities;
+ if (mDataConnectionNetworkType != networkType) {
+ mDataConnectionNetworkType = networkType;
+ // need to tell registered listeners about the new network type
+ modified = true;
+ }
+ if (modified) {
+ Slog.d(TAG, "onDataConnectionStateChanged(" + state + ", " + networkType + ")");
+ for (Record r : mRecords) {
+ if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
+ try {
+ r.callback.onDataConnectionStateChanged(state, networkType);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
}
}
+ handleRemoveListLocked();
}
}
broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
- apnTypes, interfaceName, gateway);
+ apnType, linkProperties, linkCapabilities);
}
- public void notifyDataConnectionFailed(String reason) {
+ public void notifyDataConnectionFailed(String reason, String apnType) {
if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
return;
}
/*
- * This is commented out because there is on onDataConnectionFailed callback
- * on PhoneStateListener. There should be
+ * This is commented out because there is no onDataConnectionFailed callback
+ * in PhoneStateListener. There should be.
synchronized (mRecords) {
mDataConnectionFailedReason = reason;
final int N = mRecords.size();
@@ -401,7 +457,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
}
*/
- broadcastDataConnectionFailed(reason);
+ broadcastDataConnectionFailed(reason, apnType);
}
public void notifyCellLocation(Bundle cellLocation) {
@@ -410,39 +466,36 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
synchronized (mRecords) {
mCellLocation = cellLocation;
- for (int i = mRecords.size() - 1; i >= 0; i--) {
- Record r = mRecords.get(i);
+ for (Record r : mRecords) {
if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
- sendCellLocation(r, cellLocation);
+ try {
+ r.callback.onCellLocationChanged(new Bundle(cellLocation));
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
+
}
}
+ handleRemoveListLocked();
}
}
- /**
- * Copy the service state object so they can't mess it up in the local calls
- */
- public void sendServiceState(Record r, ServiceState state) {
- try {
- r.callback.onServiceStateChanged(new ServiceState(state));
- } catch (RemoteException ex) {
- remove(r.binder);
- }
- }
-
- private void sendCellLocation(Record r, Bundle cellLocation) {
- try {
- r.callback.onCellLocationChanged(new Bundle(cellLocation));
- } catch (RemoteException ex) {
- remove(r.binder);
+ public void notifyOtaspChanged(int otaspMode) {
+ if (!checkNotifyPermission("notifyOtaspChanged()" )) {
+ return;
}
- }
-
- private void sendSignalStrength(Record r, SignalStrength signalStrength) {
- try {
- r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
- } catch (RemoteException ex) {
- remove(r.binder);
+ synchronized (mRecords) {
+ mOtaspMode = otaspMode;
+ for (Record r : mRecords) {
+ if ((r.events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) {
+ try {
+ r.callback.onOtaspChanged(otaspMode);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
+ }
+ }
+ handleRemoveListLocked();
}
}
@@ -468,11 +521,11 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
pw.println(" mDataConnectionPossible=" + mDataConnectionPossible);
pw.println(" mDataConnectionReason=" + mDataConnectionReason);
pw.println(" mDataConnectionApn=" + mDataConnectionApn);
- pw.println(" mDataConnectionInterfaceName=" + mDataConnectionInterfaceName);
+ pw.println(" mDataConnectionLinkProperties=" + mDataConnectionLinkProperties);
+ pw.println(" mDataConnectionLinkCapabilities=" + mDataConnectionLinkCapabilities);
pw.println(" mCellLocation=" + mCellLocation);
pw.println("registrations: count=" + recordCount);
- for (int i = 0; i < recordCount; i++) {
- Record r = mRecords.get(i);
+ for (Record r : mRecords) {
pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
}
}
@@ -543,7 +596,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
private void broadcastDataConnectionStateChanged(int state,
boolean isDataConnectivityPossible,
- String reason, String apn, String[] apnTypes, String interfaceName, String gateway) {
+ String reason, String apn, String apnType, LinkProperties linkProperties,
+ LinkCapabilities linkCapabilities) {
// 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.
@@ -556,29 +610,26 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
if (reason != null) {
intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason);
}
- intent.putExtra(Phone.DATA_APN_KEY, apn);
- String types = new String("");
- if (apnTypes.length > 0) {
- types = apnTypes[0];
- for (int i = 1; i < apnTypes.length; i++) {
- types = types+","+apnTypes[i];
+ if (linkProperties != null) {
+ intent.putExtra(Phone.DATA_LINK_PROPERTIES_KEY, linkProperties);
+ String iface = linkProperties.getInterfaceName();
+ if (iface != null) {
+ intent.putExtra(Phone.DATA_IFACE_NAME_KEY, iface);
}
}
- intent.putExtra(Phone.DATA_APN_TYPES_KEY, types);
- intent.putExtra(Phone.DATA_IFACE_NAME_KEY, interfaceName);
- int gatewayAddr = 0;
- if (gateway != null) {
- gatewayAddr = NetworkUtils.v4StringToInt(gateway);
+ if (linkCapabilities != null) {
+ intent.putExtra(Phone.DATA_LINK_CAPABILITIES_KEY, linkCapabilities);
}
- intent.putExtra(Phone.DATA_GATEWAY_KEY, gatewayAddr);
-
+ intent.putExtra(Phone.DATA_APN_KEY, apn);
+ intent.putExtra(Phone.DATA_APN_TYPE_KEY, apnType);
mContext.sendStickyBroadcast(intent);
}
- private void broadcastDataConnectionFailed(String reason) {
+ private void broadcastDataConnectionFailed(String reason, String apnType) {
Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
intent.putExtra(Phone.FAILURE_REASON_KEY, reason);
+ intent.putExtra(Phone.DATA_APN_TYPE_KEY, apnType);
mContext.sendStickyBroadcast(intent);
}
@@ -605,4 +656,13 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
android.Manifest.permission.READ_PHONE_STATE, null);
}
}
+
+ private void handleRemoveListLocked() {
+ if (mRemoveList.size() > 0) {
+ for (IBinder b: mRemoveList) {
+ remove(b);
+ }
+ mRemoveList.clear();
+ }
+ }
}