Merge change 1590 into donut
* changes: 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.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -1115,7 +1115,21 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
u.noteScanWifiLockReleasedLocked();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -1200,7 +1214,10 @@ 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
|
||||
@@ -1334,7 +1353,23 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
mScanWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@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);
|
||||
@@ -1349,7 +1384,13 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
public long getScanWifiLockTime(long batteryRealtime, int which) {
|
||||
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,7 +2754,9 @@ 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) {
|
||||
u.initUserActivityLocked();
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -69,5 +69,11 @@ interface IWifiManager
|
||||
boolean acquireWifiLock(IBinder lock, int lockType, String tag);
|
||||
|
||||
boolean releaseWifiLock(IBinder lock);
|
||||
|
||||
boolean isWifiMulticastEnabled();
|
||||
|
||||
void enableWifiMulticast(IBinder binder, String tag);
|
||||
|
||||
void disableWifiMulticast();
|
||||
}
|
||||
|
||||
|
||||
@@ -823,4 +823,65 @@ public class WifiManager {
|
||||
public WifiLock createWifiLock(String tag) {
|
||||
return new WifiLock(WIFI_MODE_FULL, tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check multicast filter status.
|
||||
*
|
||||
* @return true if multicast packets are allowed.
|
||||
*
|
||||
* @hide pending API council approval
|
||||
*/
|
||||
public boolean isWifiMulticastEnabled() {
|
||||
try {
|
||||
return mService.isWifiMulticastEnabled();
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn on the reception of multicast packets.
|
||||
* The default behavior is to disable multicast packets as they
|
||||
* have a noticable negative effect on battery life. An
|
||||
* application can turn them on, but should not leave it on for longer
|
||||
* than needed. When the app quits (or crashes) its request will
|
||||
* be reverted.
|
||||
*
|
||||
* @param tag a string associated with this request for debugging.
|
||||
*
|
||||
* @return true on success
|
||||
*
|
||||
* @see #disableWifiMulticast
|
||||
*
|
||||
* @hide pending API council approval
|
||||
*/
|
||||
public boolean enableWifiMulticast(String tag) {
|
||||
try {
|
||||
mService.enableWifiMulticast(new Binder(), tag);
|
||||
return true;
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return to the default multicast-off setting.
|
||||
* Note that if others had turned on Multicast reception, your
|
||||
* call will not turn it back off - they must also turn off their
|
||||
* request for multicast reception.
|
||||
*
|
||||
* @return true on success
|
||||
*
|
||||
* @see #enableWifiMulticast
|
||||
*
|
||||
* @hide pending API council approval
|
||||
*/
|
||||
public boolean disableWifiMulticast() {
|
||||
try {
|
||||
mService.disableWifiMulticast();
|
||||
return true;
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -732,15 +732,19 @@ public class WifiStateTracker extends NetworkStateTracker {
|
||||
/*
|
||||
* Filter out multicast packets. This saves battery power, since
|
||||
* the CPU doesn't have to spend time processing packets that
|
||||
* are going to end up being thrown away. Obviously, if we
|
||||
* ever want to support multicast, this will have to change.
|
||||
* are going to end up being thrown away.
|
||||
*
|
||||
* Note that rather than turn this off directly, we use the
|
||||
* public api - this keeps us all in sync - turn multicast on
|
||||
* first and then off.. if nobody else wants it on it'll be
|
||||
* off then and it's all synchronized within the API.
|
||||
*/
|
||||
mWM.enableWifiMulticast("WifiStateTracker");
|
||||
mWM.disableWifiMulticast();
|
||||
|
||||
if (mBluetoothA2dp == null) {
|
||||
mBluetoothA2dp = new BluetoothA2dp(mContext);
|
||||
}
|
||||
synchronized (this) {
|
||||
WifiNative.startPacketFiltering();
|
||||
}
|
||||
checkIsBluetoothPlaying();
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user