Merge "Only allow completion callback to be run once for PIs" into sc-qpr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b53041d1eb
@@ -243,15 +243,24 @@ public class LocationProviderManager extends
|
|||||||
intent.putExtra(KEY_LOCATIONS, locationResult.asList().toArray(new Location[0]));
|
intent.putExtra(KEY_LOCATIONS, locationResult.asList().toArray(new Location[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// send() SHOULD only run the completion callback if it completes successfully. however,
|
||||||
|
// b/199464864 (which could not be fixed in the S timeframe) means that it's possible
|
||||||
|
// for send() to throw an exception AND run the completion callback. if this happens, we
|
||||||
|
// would over-release the wakelock... we take matters into our own hands to ensure that
|
||||||
|
// the completion callback can only be run if send() completes successfully. this means
|
||||||
|
// the completion callback may be run inline - but as we've never specified what thread
|
||||||
|
// the callback is run on, this is fine.
|
||||||
|
GatedCallback gatedCallback = new GatedCallback(onCompleteCallback);
|
||||||
|
|
||||||
mPendingIntent.send(
|
mPendingIntent.send(
|
||||||
mContext,
|
mContext,
|
||||||
0,
|
0,
|
||||||
intent,
|
intent,
|
||||||
onCompleteCallback != null ? (pI, i, rC, rD, rE) -> onCompleteCallback.run()
|
(pI, i, rC, rD, rE) -> gatedCallback.run(),
|
||||||
: null,
|
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
options.toBundle());
|
options.toBundle());
|
||||||
|
gatedCallback.allow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -2734,4 +2743,49 @@ public class LocationProviderManager extends
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class GatedCallback implements Runnable {
|
||||||
|
|
||||||
|
private @Nullable Runnable mCallback;
|
||||||
|
|
||||||
|
@GuardedBy("this")
|
||||||
|
private boolean mGate;
|
||||||
|
@GuardedBy("this")
|
||||||
|
private boolean mRun;
|
||||||
|
|
||||||
|
GatedCallback(Runnable callback) {
|
||||||
|
mCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void allow() {
|
||||||
|
Runnable callback = null;
|
||||||
|
synchronized (this) {
|
||||||
|
mGate = true;
|
||||||
|
if (mRun && mCallback != null) {
|
||||||
|
callback = mCallback;
|
||||||
|
mCallback = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callback != null) {
|
||||||
|
callback.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Runnable callback = null;
|
||||||
|
synchronized (this) {
|
||||||
|
mRun = true;
|
||||||
|
if (mGate && mCallback != null) {
|
||||||
|
callback = mCallback;
|
||||||
|
mCallback = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callback != null) {
|
||||||
|
callback.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user