Fix MulticastLock API to match WifiLock API.
Adds option to make lock refcounted or not. Fixes 2017680.
This commit is contained in:
@@ -79956,6 +79956,19 @@
|
|||||||
visibility="public"
|
visibility="public"
|
||||||
>
|
>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="setReferenceCounted"
|
||||||
|
return="void"
|
||||||
|
abstract="false"
|
||||||
|
native="false"
|
||||||
|
synchronized="false"
|
||||||
|
static="false"
|
||||||
|
final="false"
|
||||||
|
deprecated="not deprecated"
|
||||||
|
visibility="public"
|
||||||
|
>
|
||||||
|
<parameter name="refCounted" type="boolean">
|
||||||
|
</parameter>
|
||||||
|
</method>
|
||||||
</class>
|
</class>
|
||||||
<class name="WifiManager.WifiLock"
|
<class name="WifiManager.WifiLock"
|
||||||
extends="java.lang.Object"
|
extends="java.lang.Object"
|
||||||
|
|||||||
@@ -870,7 +870,10 @@ public class WifiManager {
|
|||||||
* Create a new MulticastLock
|
* Create a new MulticastLock
|
||||||
*
|
*
|
||||||
* @param tag a tag for the MulticastLock to identify it in debugging
|
* @param tag a tag for the MulticastLock to identify it in debugging
|
||||||
* messages.
|
* messages. This string is never shown to the user under
|
||||||
|
* normal conditions, but should be descriptive enough to
|
||||||
|
* identify your application and the specific MulticastLock
|
||||||
|
* within it, if it holds multiple MulticastLocks.
|
||||||
*
|
*
|
||||||
* @return a new, unacquired MulticastLock with the given tag.
|
* @return a new, unacquired MulticastLock with the given tag.
|
||||||
*
|
*
|
||||||
@@ -886,26 +889,36 @@ public class WifiManager {
|
|||||||
* addressed to this device. Acquring a MulticastLock will
|
* addressed to this device. Acquring a MulticastLock will
|
||||||
* cause the stack to receive packets addressed to multicast
|
* cause the stack to receive packets addressed to multicast
|
||||||
* addresses. Processing these extra packets can cause a noticable
|
* addresses. Processing these extra packets can cause a noticable
|
||||||
* battery drain and should be disabled when not needed
|
* battery drain and should be disabled when not needed.
|
||||||
*/
|
*/
|
||||||
public class MulticastLock {
|
public class MulticastLock {
|
||||||
private String mTag;
|
private String mTag;
|
||||||
private final IBinder mBinder;
|
private final IBinder mBinder;
|
||||||
|
private int mRefCount;
|
||||||
|
private boolean mRefCounted;
|
||||||
private boolean mHeld;
|
private boolean mHeld;
|
||||||
|
|
||||||
private MulticastLock(String tag) {
|
private MulticastLock(String tag) {
|
||||||
mTag = tag;
|
mTag = tag;
|
||||||
mBinder = new Binder();
|
mBinder = new Binder();
|
||||||
|
mRefCount = 0;
|
||||||
|
mRefCounted = true;
|
||||||
mHeld = false;
|
mHeld = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Locks Wifi Multicast on until {@link #release} is called.
|
* Locks Wifi Multicast on until {@link #release} is called.
|
||||||
*
|
*
|
||||||
* The first call to {@code acquire} will lock the Multicast on
|
* If this MulticastLock is reference-counted each call to
|
||||||
* but subsequent calls will be ignored. Only one call to
|
* {@code acquire} will increment the reference count, and the
|
||||||
* {@link #release} will be required, regardless of the number of
|
* wifi interface will receive multicast packets as long as the
|
||||||
* times that {@code acquire} is called.
|
* reference count is above zero.
|
||||||
|
*
|
||||||
|
* If this MulticastLock is not reference-counted, the first call to
|
||||||
|
* {@code acquire} will turn on the multicast packets, but subsequent
|
||||||
|
* calls will be ignored. Only one call to {@link #release} will
|
||||||
|
* be required, regardless of the number of times that {@code acquire}
|
||||||
|
* is called.
|
||||||
*
|
*
|
||||||
* Note that other applications may also lock Wifi Multicast on.
|
* Note that other applications may also lock Wifi Multicast on.
|
||||||
* Only they can relinquish their lock.
|
* Only they can relinquish their lock.
|
||||||
@@ -915,7 +928,7 @@ public class WifiManager {
|
|||||||
*/
|
*/
|
||||||
public void acquire() {
|
public void acquire() {
|
||||||
synchronized (mBinder) {
|
synchronized (mBinder) {
|
||||||
if (!mHeld) {
|
if (mRefCounted ? (++mRefCount > 0) : (!mHeld)) {
|
||||||
try {
|
try {
|
||||||
mService.acquireMulticastLock(mBinder, mTag);
|
mService.acquireMulticastLock(mBinder, mTag);
|
||||||
synchronized (WifiManager.this) {
|
synchronized (WifiManager.this) {
|
||||||
@@ -926,9 +939,9 @@ public class WifiManager {
|
|||||||
}
|
}
|
||||||
mActiveLockCount++;
|
mActiveLockCount++;
|
||||||
}
|
}
|
||||||
mHeld = true;
|
|
||||||
} catch (RemoteException ignore) {
|
} catch (RemoteException ignore) {
|
||||||
}
|
}
|
||||||
|
mHeld = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -937,6 +950,18 @@ public class WifiManager {
|
|||||||
* Unlocks Wifi Multicast, restoring the filter of packets
|
* Unlocks Wifi Multicast, restoring the filter of packets
|
||||||
* not addressed specifically to this device and saving power.
|
* not addressed specifically to this device and saving power.
|
||||||
*
|
*
|
||||||
|
* If this MulticastLock is reference-counted, each call to
|
||||||
|
* {@code release} will decrement the reference count, and the
|
||||||
|
* multicast packets will only stop being received when the reference
|
||||||
|
* count reaches zero. If the reference count goes below zero (that
|
||||||
|
* is, if {@code release} is called a greater number of times than
|
||||||
|
* {@link #acquire}), an exception is thrown.
|
||||||
|
*
|
||||||
|
* If this MulticastLock is not reference-counted, the first call to
|
||||||
|
* {@code release} (after the radio was multicast locked using
|
||||||
|
* {@linke #acquire}) will unlock the multicast, and subsequent calls
|
||||||
|
* will be ignored.
|
||||||
|
*
|
||||||
* Note that if any other Wifi Multicast Locks are still outstanding
|
* Note that if any other Wifi Multicast Locks are still outstanding
|
||||||
* this {@code release} call will not have an immediate effect. Only
|
* this {@code release} call will not have an immediate effect. Only
|
||||||
* when all applications have released all their Multicast Locks will
|
* when all applications have released all their Multicast Locks will
|
||||||
@@ -947,19 +972,42 @@ public class WifiManager {
|
|||||||
*/
|
*/
|
||||||
public void release() {
|
public void release() {
|
||||||
synchronized (mBinder) {
|
synchronized (mBinder) {
|
||||||
if (mHeld) {
|
if (mRefCounted ? (--mRefCount == 0) : (mHeld)) {
|
||||||
try {
|
try {
|
||||||
mService.releaseMulticastLock();
|
mService.releaseMulticastLock();
|
||||||
synchronized (WifiManager.this) {
|
synchronized (WifiManager.this) {
|
||||||
mActiveLockCount--;
|
mActiveLockCount--;
|
||||||
}
|
}
|
||||||
mHeld = false;
|
|
||||||
} catch (RemoteException ignore) {
|
} catch (RemoteException ignore) {
|
||||||
}
|
}
|
||||||
|
mHeld = false;
|
||||||
|
}
|
||||||
|
if (mRefCount < 0) {
|
||||||
|
throw new RuntimeException("MulticastLock under-locked "
|
||||||
|
+ mTag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls whether this is a reference-counted or non-reference-
|
||||||
|
* counted MulticastLock.
|
||||||
|
*
|
||||||
|
* Reference-counted MulticastLocks keep track of the number of calls
|
||||||
|
* to {@link #acquire} and {@link #release}, and only stop the
|
||||||
|
* reception of multicast packets when every call to {@link #acquire}
|
||||||
|
* has been balanced with a call to {@link #release}. Non-reference-
|
||||||
|
* counted MulticastLocks allow the reception of multicast packets
|
||||||
|
* whenever {@link #acquire} is called and stop accepting multicast
|
||||||
|
* packets whenever {@link #release} is called.
|
||||||
|
*
|
||||||
|
* @param refCounted true if this MulticastLock should keep a reference
|
||||||
|
* count
|
||||||
|
*/
|
||||||
|
public void setReferenceCounted(boolean refCounted) {
|
||||||
|
mRefCounted = refCounted;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether this MulticastLock is currently held.
|
* Checks whether this MulticastLock is currently held.
|
||||||
*
|
*
|
||||||
@@ -972,17 +1020,23 @@ public class WifiManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String s1, s2;
|
String s1, s2, s3;
|
||||||
synchronized (mBinder) {
|
synchronized (mBinder) {
|
||||||
s1 = Integer.toHexString(System.identityHashCode(this));
|
s1 = Integer.toHexString(System.identityHashCode(this));
|
||||||
s2 = mHeld ? "held; " : "";
|
s2 = mHeld ? "held; " : "";
|
||||||
return "MulticastLock{ " + s1 + "; " + s2 + " }";
|
if (mRefCounted) {
|
||||||
|
s3 = "refcounted: refcount = " + mRefCount;
|
||||||
|
} else {
|
||||||
|
s3 = "not refcounted";
|
||||||
|
}
|
||||||
|
return "MulticastLock{ " + s1 + "; " + s2 + s3 + " }";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void finalize() throws Throwable {
|
protected void finalize() throws Throwable {
|
||||||
super.finalize();
|
super.finalize();
|
||||||
|
setReferenceCounted(false);
|
||||||
release();
|
release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user