Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5347bd4c authored by Robert Greenwalt's avatar Robert Greenwalt
Browse files

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.
parent 6347c322
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -61,6 +61,13 @@ public abstract class BatteryStats implements Parcelable {
     */
    public static final int SCAN_WIFI_LOCK = 6;

     /**
      * A constant indicating a wifi multicast timer
      *
      * {@hide}
      */
     public static final int WIFI_MULTICAST_ENABLED = 7;

    /**
     * Include all of the data in the stats, including previously saved data.
     */
@@ -225,9 +232,13 @@ public abstract class BatteryStats implements Parcelable {
        public abstract void noteFullWifiLockReleasedLocked();
        public abstract void noteScanWifiLockAcquiredLocked();
        public abstract void noteScanWifiLockReleasedLocked();
        public abstract void noteWifiMulticastEnabledLocked();
        public abstract void noteWifiMulticastDisabledLocked();
        public abstract long getWifiTurnedOnTime(long batteryRealtime, int which);
        public abstract long getFullWifiLockTime(long batteryRealtime, int which);
        public abstract long getScanWifiLockTime(long batteryRealtime, int which);
        public abstract long getWifiMulticastTime(long batteryRealtime,
                                                  int which);

        /**
         * Note that these must match the constants in android.os.LocalPowerManager.
+2 −0
Original line number Diff line number Diff line
@@ -45,6 +45,8 @@ interface IBatteryStats {
    void noteFullWifiLockReleased(int uid);
    void noteScanWifiLockAcquired(int uid);
    void noteScanWifiLockReleased(int uid);
    void noteWifiMulticastEnabled(int uid);
    void noteWifiMulticastDisabled(int uid);
    void setOnBattery(boolean onBattery, int level);
    void recordCurrentLevel(int level);
    long getAwakeTimeBattery();
+53 −5
Original line number Diff line number Diff line
@@ -1116,6 +1116,20 @@ public final class BatteryStatsImpl extends BatteryStats {
        }
    }

    public void noteWifiMulticastEnabledLocked(int uid) {
        Uid u = mUidStats.get(uid);
        if (u != null) {
            u.noteWifiMulticastEnabledLocked();
        }
    }

    public void noteWifiMulticastDisabledLocked(int uid) {
        Uid u = mUidStats.get(uid);
        if (u != null) {
            u.noteWifiMulticastDisabledLocked();
        }
    }

    @Override public long getScreenOnTime(long batteryRealtime, int which) {
        return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
    }
@@ -1201,6 +1215,9 @@ public final class BatteryStatsImpl extends BatteryStats {
        boolean mScanWifiLockOut;
        StopwatchTimer mScanWifiLockTimer;

        boolean mWifiMulticastEnabled;
        StopwatchTimer mWifiMulticastTimer;

        Counter[] mUserActivityCounters;
        
        /**
@@ -1228,6 +1245,8 @@ public final class BatteryStatsImpl extends BatteryStats {
            mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables);
            mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables);
            mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables);
            mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED,
                    null, mUnpluggables);
        }

        @Override
@@ -1335,6 +1354,22 @@ public final class BatteryStatsImpl extends BatteryStats {
            }
        }

        @Override
        public void noteWifiMulticastEnabledLocked() {
            if (!mWifiMulticastEnabled) {
                mWifiMulticastEnabled = true;
                mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this);
            }
        }

        @Override
        public void noteWifiMulticastDisabledLocked() {
            if (mWifiMulticastEnabled) {
                mWifiMulticastEnabled = false;
                mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this);
            }
        }

        @Override 
        public long getWifiTurnedOnTime(long batteryRealtime, int which) {
            return mWifiTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
@@ -1350,6 +1385,12 @@ public final class BatteryStatsImpl extends BatteryStats {
            return mScanWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
        }

        @Override
        public long getWifiMulticastTime(long batteryRealtime, int which) {
            return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime,
                                                          which);
        }

        @Override
        public void noteUserActivityLocked(int type) {
            if (mUserActivityCounters == null) {
@@ -1423,6 +1464,7 @@ public final class BatteryStatsImpl extends BatteryStats {
            mWifiTurnedOnTimer.writeToParcel(out, batteryRealtime);
            mFullWifiLockTimer.writeToParcel(out, batteryRealtime);
            mScanWifiLockTimer.writeToParcel(out, batteryRealtime);
            mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
            if (mUserActivityCounters == null) {
                out.writeInt(0);
            } else {
@@ -1482,6 +1524,9 @@ public final class BatteryStatsImpl extends BatteryStats {
            mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables, in);
            mScanWifiLockOut = false;
            mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables, in);
            mWifiMulticastEnabled = false;
            mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED,
                    null, mUnpluggables, in);
            if (in.readInt() == 0) {
                mUserActivityCounters = null;
            } else {
@@ -2709,6 +2754,8 @@ public final class BatteryStatsImpl extends BatteryStats {
            u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
            u.mScanWifiLockOut = false;
            u.mScanWifiLockTimer.readSummaryFromParcelLocked(in);
            u.mWifiMulticastEnabled = false;
            u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);

            if (in.readInt() != 0) {
                if (u.mUserActivityCounters == null) {
@@ -2842,6 +2889,7 @@ public final class BatteryStatsImpl extends BatteryStats {
            u.mWifiTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
            u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
            u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
            u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);

            if (u.mUserActivityCounters == null) {
                out.writeInt(0);
+117 −18
Original line number Diff line number Diff line
@@ -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);
        }
    }
}
+14 −0
Original line number Diff line number Diff line
@@ -261,6 +261,20 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
        }
    }

    public void noteWifiMulticastEnabled(int uid) {
        enforceCallingPermission();
        synchronized (mStats) {
            mStats.noteWifiMulticastEnabledLocked(uid);
        }
    }

    public void noteWifiMulticastDisabled(int uid) {
        enforceCallingPermission();
        synchronized (mStats) {
            mStats.noteWifiMulticastDisabledLocked(uid);
        }
    }

    public boolean isOnBattery() {
        return mStats.isOnBattery();
    }
Loading