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.java181
1 files changed, 107 insertions, 74 deletions
diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java
index fa54421..88f47fd 100644
--- a/services/java/com/android/server/TelephonyRegistry.java
+++ b/services/java/com/android/server/TelephonyRegistry.java
@@ -26,6 +26,7 @@ import android.os.RemoteException;
import android.telephony.CellLocation;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
@@ -39,48 +40,64 @@ 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.PhoneStateIntentReceiver;
import com.android.internal.telephony.TelephonyIntents;
import com.android.server.am.BatteryStatsService;
-
/**
- * Since phone process can be restarted, this class provides a centralized
- * place that applications can register and be called back from.
+ * Since phone process can be restarted, this class provides a centralized place
+ * that applications can register and be called back from.
*/
class TelephonyRegistry extends ITelephonyRegistry.Stub {
private static final String TAG = "TelephonyRegistry";
private static class Record {
String pkgForDebug;
+
IBinder binder;
+
IPhoneStateListener callback;
+
int events;
}
private final Context mContext;
+
private final ArrayList<Record> mRecords = new ArrayList();
+
private final IBatteryStats mBatteryStats;
private int mCallState = TelephonyManager.CALL_STATE_IDLE;
+
private String mCallIncomingNumber = "";
+
private ServiceState mServiceState = new ServiceState();
- private int mSignalStrength = -1;
+
+ private SignalStrength mSignalStrength = new SignalStrength();
+
private boolean mMessageWaiting = false;
+
private boolean mCallForwarding = false;
+
private int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
+
private int mDataConnectionState = TelephonyManager.DATA_CONNECTED;
+
private boolean mDataConnectionPossible = false;
+
private String mDataConnectionReason = "";
+
private String mDataConnectionApn = "";
+
private String mDataConnectionInterfaceName = "";
+
private Bundle mCellLocation = new Bundle();
- // we keep a copy of all of the sate so we can send it out when folks register for it
+ // we keep a copy of all of the state so we can send it out when folks
+ // register for it
//
- // In these calls we call with the lock held. This is safe becasuse remote
- // calls go through a oneway interface and local calls going through a handler before
- // they get to app code.
+ // In these calls we call with the lock held. This is safe becasuse remote
+ // calls go through a oneway interface and local calls going through a
+ // handler before they get to app code.
TelephonyRegistry(Context context) {
CellLocation.getEmpty().fillInNotifierBundle(mCellLocation);
@@ -90,13 +107,18 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
boolean notifyNow) {
- //Log.d(TAG, "listen pkg=" + pkgForDebug + " events=0x" + Integer.toHexString(events));
+ // Log.d(TAG, "listen pkg=" + pkgForDebug + " events=0x" +
+ // Integer.toHexString(events));
if (events != 0) {
// check permissions
if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
-
+ // ACCESS_FINE_LOCATION implies ACCESS_COARSE_LOCATION
+ if (mContext.checkCallingPermission(
+ android.Manifest.permission.ACCESS_FINE_LOCATION)
+ != PackageManager.PERMISSION_GRANTED) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
+ }
}
synchronized (mRecords) {
@@ -105,7 +127,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
find_and_add: {
IBinder b = callback.asBinder();
final int N = mRecords.size();
- for (int i=0; i<N; i++) {
+ for (int i = 0; i < N; i++) {
r = mRecords.get(i);
if (b == r.binder) {
break find_and_add;
@@ -125,7 +147,9 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
try {
- r.callback.onSignalStrengthChanged(mSignalStrength);
+ int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
+ r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
+ : gsmSignalStrength));
} catch (RemoteException ex) {
remove(r.binder);
}
@@ -168,6 +192,13 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
remove(r.binder);
}
}
+ if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
+ try {
+ r.callback.onSignalStrengthsChanged(mSignalStrength);
+ } catch (RemoteException ex) {
+ remove(r.binder);
+ }
+ }
}
}
} else {
@@ -177,8 +208,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
private void remove(IBinder binder) {
synchronized (mRecords) {
- final int N = mRecords.size();
- for (int i=0; i<N; i++) {
+ final int recordCount = mRecords.size();
+ for (int i = 0; i < recordCount; i++) {
if (mRecords.get(i).binder == binder) {
mRecords.remove(i);
return;
@@ -194,8 +225,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
synchronized (mRecords) {
mCallState = state;
mCallIncomingNumber = incomingNumber;
- final int N = mRecords.size();
- for (int i=N-1; i>=0; i--) {
+ for (int i = mRecords.size() - 1; i >= 0; i--) {
Record r = mRecords.get(i);
if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
try {
@@ -212,11 +242,10 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
public void notifyServiceState(ServiceState state) {
if (!checkPhoneStatePermission("notifyServiceState()")) {
return;
- }
+ }
synchronized (mRecords) {
mServiceState = state;
- final int N = mRecords.size();
- for (int i=N-1; i>=0; i--) {
+ for (int i = mRecords.size() - 1; i >= 0; i--) {
Record r = mRecords.get(i);
if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
sendServiceState(r, state);
@@ -226,35 +255,38 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
broadcastServiceStateChanged(state);
}
- public void notifySignalStrength(int signalStrengthASU) {
+ public void notifySignalStrength(SignalStrength signalStrength) {
if (!checkPhoneStatePermission("notifySignalStrength()")) {
return;
- }
+ }
synchronized (mRecords) {
- mSignalStrength = signalStrengthASU;
- final int N = mRecords.size();
- for (int i=N-1; i>=0; i--) {
+ mSignalStrength = signalStrength;
+ for (int i = mRecords.size() - 1; i >= 0; i--) {
Record r = mRecords.get(i);
+ if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
+ sendSignalStrength(r, signalStrength);
+ }
if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
try {
- r.callback.onSignalStrengthChanged(signalStrengthASU);
+ int gsmSignalStrength = signalStrength.getGsmSignalStrength();
+ r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
+ : gsmSignalStrength));
} catch (RemoteException ex) {
remove(r.binder);
}
}
}
}
- broadcastSignalStrengthChanged(signalStrengthASU);
+ broadcastSignalStrengthChanged(signalStrength);
}
public void notifyMessageWaitingChanged(boolean mwi) {
if (!checkPhoneStatePermission("notifyMessageWaitingChanged()")) {
return;
- }
+ }
synchronized (mRecords) {
mMessageWaiting = mwi;
- final int N = mRecords.size();
- for (int i=N-1; i>=0; i--) {
+ for (int i = mRecords.size() - 1; i >= 0; i--) {
Record r = mRecords.get(i);
if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
try {
@@ -270,11 +302,10 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
public void notifyCallForwardingChanged(boolean cfi) {
if (!checkPhoneStatePermission("notifyCallForwardingChanged()")) {
return;
- }
+ }
synchronized (mRecords) {
mCallForwarding = cfi;
- final int N = mRecords.size();
- for (int i=N-1; i>=0; i--) {
+ for (int i = mRecords.size() - 1; i >= 0; i--) {
Record r = mRecords.get(i);
if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
try {
@@ -290,11 +321,10 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
public void notifyDataActivity(int state) {
if (!checkPhoneStatePermission("notifyDataActivity()")) {
return;
- }
+ }
synchronized (mRecords) {
mDataActivity = state;
- final int N = mRecords.size();
- for (int i=N-1; i>=0; i--) {
+ for (int i = mRecords.size() - 1; i >= 0; i--) {
Record r = mRecords.get(i);
if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
try {
@@ -307,19 +337,18 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
}
- public void notifyDataConnection(int state, boolean isDataConnectivityPissible,
- String reason, String apn, String interfaceName) {
+ public void notifyDataConnection(int state, boolean isDataConnectivityPossible, String reason,
+ String apn, String interfaceName) {
if (!checkPhoneStatePermission("notifyDataConnection()")) {
return;
- }
+ }
synchronized (mRecords) {
mDataConnectionState = state;
- mDataConnectionPossible = isDataConnectivityPissible;
+ mDataConnectionPossible = isDataConnectivityPossible;
mDataConnectionReason = reason;
mDataConnectionApn = apn;
mDataConnectionInterfaceName = interfaceName;
- final int N = mRecords.size();
- for (int i=N-1; i>=0; i--) {
+ for (int i = mRecords.size() - 1; i >= 0; i--) {
Record r = mRecords.get(i);
if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
try {
@@ -330,17 +359,17 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
}
}
- broadcastDataConnectionStateChanged(state, isDataConnectivityPissible,
- reason, apn, interfaceName);
+ broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
+ interfaceName);
}
public void notifyDataConnectionFailed(String reason) {
if (!checkPhoneStatePermission("notifyDataConnectionFailed()")) {
return;
- }
+ }
/*
* This is commented out because there is on onDataConnectionFailed callback
- * on PhoneStateListener. There should be.
+ * on PhoneStateListener. There should be
synchronized (mRecords) {
mDataConnectionFailedReason = reason;
final int N = mRecords.size();
@@ -358,11 +387,10 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
public void notifyCellLocation(Bundle cellLocation) {
if (!checkPhoneStatePermission("notifyCellLocation()")) {
return;
- }
+ }
synchronized (mRecords) {
mCellLocation = cellLocation;
- final int N = mRecords.size();
- for (int i=N-1; i>=0; i--) {
+ for (int i = mRecords.size() - 1; i >= 0; i--) {
Record r = mRecords.get(i);
if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
sendCellLocation(r, cellLocation);
@@ -371,12 +399,10 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
}
- //
- // the new callback broadcasting
- //
- // copy the service state object so they can't mess it up in the local calls
- //
- public void sendServiceState(Record r, ServiceState state) {
+ /**
+ * Copy the service state object so they can't mess it up in the local calls
+ */
+ private void sendServiceState(Record r, ServiceState state) {
try {
r.callback.onServiceStateChanged(new ServiceState(state));
} catch (RemoteException ex) {
@@ -384,7 +410,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
}
- public void sendCellLocation(Record r, Bundle cellLocation) {
+ private void sendCellLocation(Record r, Bundle cellLocation) {
try {
r.callback.onCellLocationChanged(new Bundle(cellLocation));
} catch (RemoteException ex) {
@@ -392,18 +418,24 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
}
+ private void sendSignalStrength(Record r, SignalStrength signalStrength) {
+ try {
+ r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
+ } catch (RemoteException ex) {
+ remove(r.binder);
+ }
+ }
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
pw.println("Permission Denial: can't dump telephony.registry from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
return;
}
synchronized (mRecords) {
- final int N = mRecords.size();
+ final int recordCount = mRecords.size();
pw.println("last known state:");
pw.println(" mCallState=" + mCallState);
pw.println(" mCallIncomingNumber=" + mCallIncomingNumber);
@@ -418,15 +450,14 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
pw.println(" mDataConnectionApn=" + mDataConnectionApn);
pw.println(" mDataConnectionInterfaceName=" + mDataConnectionInterfaceName);
pw.println(" mCellLocation=" + mCellLocation);
- pw.println("registrations: count=" + N);
- for (int i=0; i<N; i++) {
+ pw.println("registrations: count=" + recordCount);
+ for (int i = 0; i < recordCount; i++) {
Record r = mRecords.get(i);
pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
}
}
}
-
//
// the legacy intent broadcasting
//
@@ -439,17 +470,20 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
mContext.sendStickyBroadcast(intent);
}
- private void broadcastSignalStrengthChanged(int asu) {
+ private void broadcastSignalStrengthChanged(SignalStrength signalStrength) {
long ident = Binder.clearCallingIdentity();
try {
- mBatteryStats.notePhoneSignalStrength(asu);
+ mBatteryStats.notePhoneSignalStrength(signalStrength);
} catch (RemoteException e) {
+ /* The remote entity disappeared, we can safely ignore the exception. */
} finally {
Binder.restoreCallingIdentity(ident);
}
-
+
Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
- intent.putExtra(PhoneStateIntentReceiver.INTENT_KEY_ASU, asu);
+ Bundle data = new Bundle();
+ signalStrength.fillInNotifierBundle(data);
+ intent.putExtras(data);
mContext.sendStickyBroadcast(intent);
}
@@ -462,13 +496,13 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
mBatteryStats.notePhoneOn();
}
} catch (RemoteException e) {
+ /* The remote entity disappeared, we can safely ignore the exception. */
} finally {
Binder.restoreCallingIdentity(ident);
}
-
+
Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
- intent.putExtra(Phone.STATE_KEY,
- DefaultPhoneNotifier.convertCallState(state).toString());
+ intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertCallState(state).toString());
if (!TextUtils.isEmpty(incomingNumber)) {
intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
}
@@ -498,15 +532,14 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
intent.putExtra(Phone.FAILURE_REASON_KEY, reason);
mContext.sendStickyBroadcast(intent);
}
-
+
private boolean checkPhoneStatePermission(String method) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
== PackageManager.PERMISSION_GRANTED) {
return true;
}
String msg = "Modify Phone State Permission Denial: " + method + " from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid();
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
Log.w(TAG, msg);
return false;
}