diff options
Diffstat (limited to 'services/java/com/android/server/TelephonyRegistry.java')
| -rw-r--r-- | services/java/com/android/server/TelephonyRegistry.java | 100 |
1 files changed, 91 insertions, 9 deletions
diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java index 8361477..26684de 100644 --- a/services/java/com/android/server/TelephonyRegistry.java +++ b/services/java/com/android/server/TelephonyRegistry.java @@ -16,14 +16,19 @@ package com.android.server; +import android.app.ActivityManager; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.PackageManager; import android.net.LinkCapabilities; import android.net.LinkProperties; import android.os.Binder; import android.os.Bundle; +import android.os.Handler; import android.os.IBinder; +import android.os.Message; import android.os.RemoteException; import android.os.UserHandle; import android.telephony.CellLocation; @@ -39,13 +44,11 @@ import java.util.ArrayList; import java.util.List; 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.PhoneConstants; import com.android.internal.telephony.ServiceStateTracker; import com.android.internal.telephony.TelephonyIntents; @@ -58,6 +61,7 @@ import com.android.server.am.BatteryStatsService; 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 class Record { String pkgForDebug; @@ -66,7 +70,15 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { IPhoneStateListener callback; + int callerUid; + int events; + + @Override + public String toString() { + return "{pkgForDebug=" + pkgForDebug + " callerUid=" + callerUid + + " events=" + Integer.toHexString(events) + "}"; + } } private final Context mContext; @@ -120,6 +132,32 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { PhoneStateListener.LISTEN_DATA_CONNECTION_STATE | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR; + private static final int MSG_USER_SWITCHED = 1; + + private final Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_USER_SWITCHED: { + Slog.d(TAG, "MSG_USER_SWITCHED userId=" + msg.arg1); + TelephonyRegistry.this.notifyCellLocation(mCellLocation); + break; + } + } + } + }; + + private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (Intent.ACTION_USER_SWITCHED.equals(action)) { + mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHED, + intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0), 0)); + } + } + }; + // we keep a copy of all of the state so we can send it out when folks // register for it // @@ -140,10 +178,24 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { mConnectedApns = new ArrayList<String>(); } + public void systemReady() { + // Watch for interesting updates + final IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_USER_SWITCHED); + filter.addAction(Intent.ACTION_USER_REMOVED); + mContext.registerReceiver(mBroadcastReceiver, filter); + } + + @Override public void listen(String pkgForDebug, IPhoneStateListener callback, int events, boolean notifyNow) { - // Slog.d(TAG, "listen pkg=" + pkgForDebug + " events=0x" + - // Integer.toHexString(events)); + int callerUid = UserHandle.getCallingUserId(); + int myUid = UserHandle.myUserId(); + if (DBG) { + Slog.d(TAG, "listen: E pkg=" + pkgForDebug + " events=0x" + Integer.toHexString(events) + + " myUid=" + myUid + + " callerUid=" + callerUid); + } if (events != 0) { /* Checks permission and throws Security exception */ checkListenerPermission(events); @@ -164,7 +216,9 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { r.binder = b; r.callback = callback; r.pkgForDebug = pkgForDebug; + r.callerUid = callerUid; mRecords.add(r); + if (DBG) Slog.i(TAG, "listen: add new record=" + r); } int send = events & (events ^ r.events); r.events = events; @@ -199,8 +253,9 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { remove(r.binder); } } - if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) { + if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) { try { + if (DBG_LOC) Slog.d(TAG, "listen: mCellLocation=" + mCellLocation); r.callback.onCellLocationChanged(new Bundle(mCellLocation)); } catch (RemoteException ex) { remove(r.binder); @@ -242,8 +297,9 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { remove(r.binder); } } - if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) { + if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) { try { + if (DBG_LOC) Slog.d(TAG, "listen: mCellInfo=" + mCellInfo); r.callback.onCellInfoChanged(mCellInfo); } catch (RemoteException ex) { remove(r.binder); @@ -346,8 +402,11 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { synchronized (mRecords) { mCellInfo = cellInfo; for (Record r : mRecords) { - if ((r.events & PhoneStateListener.LISTEN_CELL_INFO) != 0) { + if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) { try { + if (DBG_LOC) { + Slog.d(TAG, "notifyCellInfo: mCellInfo=" + mCellInfo + " r=" + r); + } r.callback.onCellInfoChanged(cellInfo); } catch (RemoteException ex) { mRemoveList.add(r.binder); @@ -424,7 +483,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { if (DBG) { Slog.i(TAG, "notifyDataConnection: state=" + state + " isDataConnectivityPossible=" + isDataConnectivityPossible + " reason='" + reason - + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType); + + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType + + " mRecords.size()=" + mRecords.size() + " mRecords=" + mRecords); } synchronized (mRecords) { boolean modified = false; @@ -506,8 +566,12 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { synchronized (mRecords) { mCellLocation = cellLocation; for (Record r : mRecords) { - if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) { + if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) { try { + if (DBG_LOC) { + Slog.d(TAG, "notifyCellLocation: mCellLocation=" + mCellLocation + + " r=" + r); + } r.callback.onCellLocationChanged(new Bundle(cellLocation)); } catch (RemoteException ex) { mRemoveList.add(r.binder); @@ -712,4 +776,22 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { mRemoveList.clear(); } } + + private boolean validateEventsAndUserLocked(Record r, int events) { + int foregroundUser; + long callingIdentity = Binder.clearCallingIdentity(); + boolean valid = false; + try { + foregroundUser = ActivityManager.getCurrentUser(); + valid = r.callerUid == foregroundUser && (r.events & events) != 0; + if (DBG | DBG_LOC) { + Slog.d(TAG, "validateEventsAndUserLocked: valid=" + valid + + " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser + + " r.events=" + r.events + " events=" + events); + } + } finally { + Binder.restoreCallingIdentity(callingIdentity); + } + return valid; + } } |
