am 8485098f: Merge "Fixed a leak in GeofenceHardwareImpl.java." into lmp-mr1-dev
* commit '8485098fa22a61f845cb2abbc5bc856b15835a9e': Fixed a leak in GeofenceHardwareImpl.java.
This commit is contained in:
@@ -23,6 +23,7 @@ import android.location.IGpsGeofenceHardware;
|
||||
import android.location.Location;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.IInterface;
|
||||
import android.os.Message;
|
||||
import android.os.PowerManager;
|
||||
import android.os.RemoteException;
|
||||
@@ -30,6 +31,7 @@ import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* This class manages the geofences which are handled by hardware.
|
||||
@@ -558,8 +560,34 @@ public final class GeofenceHardwareImpl {
|
||||
try {
|
||||
callback.onGeofenceRemove(geofenceId, msg.arg2);
|
||||
} catch (RemoteException e) {}
|
||||
IBinder callbackBinder = callback.asBinder();
|
||||
boolean callbackInUse = false;
|
||||
synchronized (mGeofences) {
|
||||
mGeofences.remove(geofenceId);
|
||||
// Check if the underlying binder is still useful for other geofences,
|
||||
// if no, unlink the DeathRecipient to avoid memory leak.
|
||||
for (int i = 0; i < mGeofences.size(); i++) {
|
||||
if (mGeofences.valueAt(i).asBinder() == callbackBinder) {
|
||||
callbackInUse = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the reaper associated with this binder.
|
||||
if (!callbackInUse) {
|
||||
for (Iterator<Reaper> iterator = mReapers.iterator();
|
||||
iterator.hasNext();) {
|
||||
Reaper reaper = iterator.next();
|
||||
if (reaper.mCallback != null &&
|
||||
reaper.mCallback.asBinder() == callbackBinder) {
|
||||
iterator.remove();
|
||||
reaper.unlinkToDeath();
|
||||
if (DEBUG) Log.d(TAG, String.format("Removed reaper %s " +
|
||||
"because binder %s is no longer needed.",
|
||||
reaper, callbackBinder));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
releaseWakeLock();
|
||||
@@ -803,8 +831,9 @@ public final class GeofenceHardwareImpl {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
result = 31 * result + (mCallback != null ? mCallback.hashCode() : 0);
|
||||
result = 31 * result + (mMonitorCallback != null ? mMonitorCallback.hashCode() : 0);
|
||||
result = 31 * result + (mCallback != null ? mCallback.asBinder().hashCode() : 0);
|
||||
result = 31 * result + (mMonitorCallback != null
|
||||
? mMonitorCallback.asBinder().hashCode() : 0);
|
||||
result = 31 * result + mMonitoringType;
|
||||
return result;
|
||||
}
|
||||
@@ -815,9 +844,38 @@ public final class GeofenceHardwareImpl {
|
||||
if (obj == this) return true;
|
||||
|
||||
Reaper rhs = (Reaper) obj;
|
||||
return rhs.mCallback == mCallback && rhs.mMonitorCallback == mMonitorCallback &&
|
||||
return binderEquals(rhs.mCallback, mCallback) &&
|
||||
binderEquals(rhs.mMonitorCallback, mMonitorCallback) &&
|
||||
rhs.mMonitoringType == mMonitoringType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the underlying Binder of the given two IInterface objects and returns true if
|
||||
* they equals. null values are accepted.
|
||||
*/
|
||||
private boolean binderEquals(IInterface left, IInterface right) {
|
||||
if (left == null) {
|
||||
return right == null;
|
||||
} else {
|
||||
return right == null ? false : left.asBinder() == right.asBinder();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlinks this DeathRecipient.
|
||||
*/
|
||||
private boolean unlinkToDeath() {
|
||||
if (mMonitorCallback != null) {
|
||||
return mMonitorCallback.asBinder().unlinkToDeath(this, 0);
|
||||
} else if (mCallback != null) {
|
||||
return mCallback.asBinder().unlinkToDeath(this, 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean callbackEquals(IGeofenceHardwareCallback cb) {
|
||||
return mCallback != null && mCallback.asBinder() == cb.asBinder();
|
||||
}
|
||||
}
|
||||
|
||||
int getAllowedResolutionLevel(int pid, int uid) {
|
||||
|
||||
Reference in New Issue
Block a user