diff options
author | Robert Greenwalt <robdroid@android.com> | 2009-05-13 15:10:16 -0700 |
---|---|---|
committer | Robert Greenwalt <robdroid@android.com> | 2009-05-13 15:10:16 -0700 |
commit | 5347bd4cda2b6afc18f8acab48e52131f35ed13c (patch) | |
tree | af3c0e520ff5712344bd5174b7d02d24ef34c4e7 /services/java/com/android/server/WifiService.java | |
parent | 6347c322b36cdf6a30a35e80d205d00d40368e61 (diff) |
Add wifi multicast filter api (enable/disable).
Fixes 1833432. Automatically re-disables any request when the app
exits/crashes. Also hooked into Battery Stats for power managment analysis.
Diffstat (limited to 'services/java/com/android/server/WifiService.java')
-rw-r--r-- | services/java/com/android/server/WifiService.java | 135 |
1 files changed, 117 insertions, 18 deletions
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java index 8850c3123e22..348f0a19c717 100644 --- a/services/java/com/android/server/WifiService.java +++ b/services/java/com/android/server/WifiService.java @@ -96,6 +96,11 @@ public class WifiService extends IWifiManager.Stub { private int mScanLocksAcquired; private int mScanLocksReleased; + private final List<WifiMulticaster> mMulticasters = + new ArrayList<WifiMulticaster>(); + private int mMulticastEnabled; + private int mMulticastDisabled; + private final IBatteryStats mBatteryStats; /** @@ -1727,21 +1732,9 @@ public class WifiService extends IWifiManager.Stub { } } - private class WifiLock implements IBinder.DeathRecipient { - String mTag; - int mLockMode; - IBinder mBinder; - + private class WifiLock extends WifiDeathRecipient { WifiLock(int lockMode, String tag, IBinder binder) { - super(); - mTag = tag; - mLockMode = lockMode; - mBinder = binder; - try { - mBinder.linkToDeath(this, 0); - } catch (RemoteException e) { - binderDied(); - } + super(lockMode, tag, binder); } public void binderDied() { @@ -1751,7 +1744,7 @@ public class WifiService extends IWifiManager.Stub { } public String toString() { - return "WifiLock{" + mTag + " type=" + mLockMode + " binder=" + mBinder + "}"; + return "WifiLock{" + mTag + " type=" + mMode + " binder=" + mBinder + "}"; } } @@ -1771,7 +1764,7 @@ public class WifiService extends IWifiManager.Stub { return WifiManager.WIFI_MODE_FULL; } for (WifiLock l : mList) { - if (l.mLockMode == WifiManager.WIFI_MODE_FULL) { + if (l.mMode == WifiManager.WIFI_MODE_FULL) { return WifiManager.WIFI_MODE_FULL; } } @@ -1826,7 +1819,7 @@ public class WifiService extends IWifiManager.Stub { int uid = Binder.getCallingUid(); long ident = Binder.clearCallingIdentity(); try { - switch(wifiLock.mLockMode) { + switch(wifiLock.mMode) { case WifiManager.WIFI_MODE_FULL: ++mFullLocksAcquired; mBatteryStats.noteFullWifiLockAcquired(uid); @@ -1862,7 +1855,7 @@ public class WifiService extends IWifiManager.Stub { int uid = Binder.getCallingUid(); long ident = Binder.clearCallingIdentity(); try { - switch(wifiLock.mLockMode) { + switch(wifiLock.mMode) { case WifiManager.WIFI_MODE_FULL: ++mFullLocksReleased; mBatteryStats.noteFullWifiLockReleased(uid); @@ -1881,4 +1874,110 @@ public class WifiService extends IWifiManager.Stub { updateWifiState(); return hadLock; } + + private abstract class WifiDeathRecipient + implements IBinder.DeathRecipient { + String mTag; + int mMode; + IBinder mBinder; + + WifiDeathRecipient(int mode, String tag, IBinder binder) { + super(); + mTag = tag; + mMode = mode; + mBinder = binder; + try { + mBinder.linkToDeath(this, 0); + } catch (RemoteException e) { + binderDied(); + } + } + } + + private class WifiMulticaster extends WifiDeathRecipient { + WifiMulticaster(String tag, IBinder binder) { + super(Binder.getCallingUid(), tag, binder); + } + + public void binderDied() { + Log.e(TAG, "WifiMulticaster binderDied"); + synchronized (mMulticasters) { + int i = mMulticasters.indexOf(this); + if (i != -1) { + removeMulticasterLocked(i, mMode); + } + } + } + + public String toString() { + return "WifiMulticaster{" + mTag + " binder=" + mBinder + "}"; + } + + public int getUid() { + return mMode; + } + } + + public void enableWifiMulticast(IBinder binder, String tag) { + enforceChangePermission(); + + synchronized (mMulticasters) { + mMulticastEnabled++; + mMulticasters.add(new WifiMulticaster(tag, binder)); + // Note that we could call stopPacketFiltering only when + // our new size == 1 (first call), but this function won't + // be called often and by making the stopPacket call each + // time we're less fragile and self-healing. + WifiNative.stopPacketFiltering(); + } + + int uid = Binder.getCallingUid(); + Long ident = Binder.clearCallingIdentity(); + try { + mBatteryStats.noteWifiMulticastEnabled(uid); + } catch (RemoteException e) { + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + public void disableWifiMulticast() { + enforceChangePermission(); + + int uid = Binder.getCallingUid(); + synchronized (mMulticasters) { + mMulticastDisabled++; + int size = mMulticasters.size(); + for (int i = size - 1; i >= 0; i--) { + WifiMulticaster m = mMulticasters.get(i); + if ((m != null) && (m.getUid() == uid)) { + removeMulticasterLocked(i, uid); + } + } + } + } + + private void removeMulticasterLocked(int i, int uid) + { + mMulticasters.remove(i); + if (mMulticasters.size() == 0) { + WifiNative.startPacketFiltering(); + } + + Long ident = Binder.clearCallingIdentity(); + try { + mBatteryStats.noteWifiMulticastDisabled(uid); + } catch (RemoteException e) { + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + public boolean isWifiMulticastEnabled() { + enforceAccessPermission(); + + synchronized (mMulticasters) { + return (mMulticasters.size() > 0); + } + } } |