diff options
author | Soonil Nagarkar <sooniln@google.com> | 2020-02-13 09:21:27 -0800 |
---|---|---|
committer | Soonil Nagarkar <sooniln@google.com> | 2020-02-13 09:25:27 -0800 |
commit | a598462fb20c30ce313646b15500117090d16459 (patch) | |
tree | 7e9acc2d20217fa2b1728cf28ac342cd275e9b30 /location | |
parent | 3b726119ac628e0a7016ef22d2b14e1802dcfd48 (diff) |
Reduce allocations in hot paths
Prevent lambda allocations in common paths in location.
Test: presubmits
Change-Id: Ia4fc7680e8e4304fcd6164a9aded56ed32492cbc
Diffstat (limited to 'location')
-rw-r--r-- | location/java/android/location/AbstractListenerManager.java | 32 | ||||
-rw-r--r-- | location/java/android/location/LocationManager.java | 144 |
2 files changed, 99 insertions, 77 deletions
diff --git a/location/java/android/location/AbstractListenerManager.java b/location/java/android/location/AbstractListenerManager.java index f075a53829ce..3dc7cfce2d92 100644 --- a/location/java/android/location/AbstractListenerManager.java +++ b/location/java/android/location/AbstractListenerManager.java @@ -16,6 +16,8 @@ package android.location; +import static com.android.internal.util.function.pooled.PooledLambda.obtainRunnable; + import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Binder; @@ -62,20 +64,24 @@ abstract class AbstractListenerManager<TRequest, TListener> { } private void execute(Consumer<TListener> operation) { - mExecutor.execute(() -> { - TListener listener = mListener; - if (listener == null) { - return; - } + mExecutor.execute( + obtainRunnable(Registration<TRequest, TListener>::accept, this, operation) + .recycleOnUse()); + } - // we may be under the binder identity if a direct executor is used - long identity = Binder.clearCallingIdentity(); - try { - operation.accept(listener); - } finally { - Binder.restoreCallingIdentity(identity); - } - }); + private void accept(Consumer<TListener> operation) { + TListener listener = mListener; + if (listener == null) { + return; + } + + // we may be under the binder identity if a direct executor is used + long identity = Binder.clearCallingIdentity(); + try { + operation.accept(listener); + } finally { + Binder.restoreCallingIdentity(identity); + } } } diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index 3d0765bb0855..03e1c758feb3 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -22,6 +22,8 @@ import static android.Manifest.permission.LOCATION_HARDWARE; import static android.Manifest.permission.WRITE_SECURE_SETTINGS; import static android.app.AlarmManager.ELAPSED_REALTIME; +import static com.android.internal.util.function.pooled.PooledLambda.obtainRunnable; + import android.Manifest; import android.annotation.CallbackExecutor; import android.annotation.NonNull; @@ -57,6 +59,7 @@ import android.util.ArrayMap; import com.android.internal.annotations.GuardedBy; import com.android.internal.location.ProviderProperties; import com.android.internal.util.Preconditions; +import com.android.internal.util.function.pooled.PooledRunnable; import java.util.Collections; import java.util.List; @@ -81,8 +84,6 @@ import java.util.function.Consumer; @RequiresFeature(PackageManager.FEATURE_LOCATION) public class LocationManager { - private static final String TAG = "LocationManager"; - /** * For apps targeting Android K and above, supplied {@link PendingIntent}s must be targeted to a * specific package. @@ -91,7 +92,7 @@ public class LocationManager { */ @ChangeId @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.JELLY_BEAN) - public static final long TARGETED_PENDING_INTENT = 148963590L; + private static final long TARGETED_PENDING_INTENT = 148963590L; /** * For apps targeting Android K and above, incomplete locations may not be passed to @@ -2604,18 +2605,28 @@ public class LocationManager { return; } - mExecutor.execute(() -> { - Consumer<Location> consumer; - synchronized (GetCurrentLocationTransport.this) { - if (mConsumer == null) { - return; - } - consumer = mConsumer; - cancel(); + PooledRunnable runnable = + obtainRunnable(GetCurrentLocationTransport::acceptResult, this, location) + .recycleOnUse(); + try { + mExecutor.execute(runnable); + } catch (RejectedExecutionException e) { + runnable.recycle(); + throw e; + } + } + + private void acceptResult(Location location) { + Consumer<Location> consumer; + synchronized (this) { + if (mConsumer == null) { + return; } + consumer = mConsumer; + cancel(); + } - consumer.accept(location); - }); + consumer.accept(location); } } @@ -2649,30 +2660,36 @@ public class LocationManager { return; } + PooledRunnable runnable = + obtainRunnable(LocationListenerTransport::acceptLocation, this, currentExecutor, + location).recycleOnUse(); try { - currentExecutor.execute(() -> { - try { - if (currentExecutor != mExecutor) { - return; - } - - // we may be under the binder identity if a direct executor is used - long identity = Binder.clearCallingIdentity(); - try { - mListener.onLocationChanged(location); - } finally { - Binder.restoreCallingIdentity(identity); - } - } finally { - locationCallbackFinished(); - } - }); + currentExecutor.execute(runnable); } catch (RejectedExecutionException e) { + runnable.recycle(); locationCallbackFinished(); throw e; } } + private void acceptLocation(Executor currentExecutor, Location location) { + try { + if (currentExecutor != mExecutor) { + return; + } + + // we may be under the binder identity if a direct executor is used + long identity = Binder.clearCallingIdentity(); + try { + mListener.onLocationChanged(location); + } finally { + Binder.restoreCallingIdentity(identity); + } + } finally { + locationCallbackFinished(); + } + } + @Override public void onProviderEnabled(String provider) { Executor currentExecutor = mExecutor; @@ -2680,25 +2697,13 @@ public class LocationManager { return; } + PooledRunnable runnable = + obtainRunnable(LocationListenerTransport::acceptProviderChange, this, + currentExecutor, provider, true).recycleOnUse(); try { - currentExecutor.execute(() -> { - try { - if (currentExecutor != mExecutor) { - return; - } - - // we may be under the binder identity if a direct executor is used - long identity = Binder.clearCallingIdentity(); - try { - mListener.onProviderEnabled(provider); - } finally { - Binder.restoreCallingIdentity(identity); - } - } finally { - locationCallbackFinished(); - } - }); + currentExecutor.execute(runnable); } catch (RejectedExecutionException e) { + runnable.recycle(); locationCallbackFinished(); throw e; } @@ -2711,30 +2716,41 @@ public class LocationManager { return; } + PooledRunnable runnable = + obtainRunnable(LocationListenerTransport::acceptProviderChange, this, + currentExecutor, provider, false).recycleOnUse(); try { - currentExecutor.execute(() -> { - try { - if (currentExecutor != mExecutor) { - return; - } - - // we may be under the binder identity if a direct executor is used - long identity = Binder.clearCallingIdentity(); - try { - mListener.onProviderDisabled(provider); - } finally { - Binder.restoreCallingIdentity(identity); - } - } finally { - locationCallbackFinished(); - } - }); + currentExecutor.execute(runnable); } catch (RejectedExecutionException e) { + runnable.recycle(); locationCallbackFinished(); throw e; } } + private void acceptProviderChange(Executor currentExecutor, String provider, + boolean enabled) { + try { + if (currentExecutor != mExecutor) { + return; + } + + // we may be under the binder identity if a direct executor is used + long identity = Binder.clearCallingIdentity(); + try { + if (enabled) { + mListener.onProviderEnabled(provider); + } else { + mListener.onProviderDisabled(provider); + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } finally { + locationCallbackFinished(); + } + } + @Override public void onRemoved() { // TODO: onRemoved is necessary to GC hanging listeners, but introduces some interesting |