Loading core/java/com/android/internal/listeners/ListenerTransportManager.java +46 −10 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.internal.listeners; import android.os.RemoteException; import android.util.ArrayMap; import com.android.internal.annotations.GuardedBy; Loading @@ -36,13 +37,17 @@ public abstract class ListenerTransportManager<TTransport extends ListenerTransp @GuardedBy("mRegistrations") private final Map<Object, WeakReference<TTransport>> mRegistrations; protected ListenerTransportManager() { protected ListenerTransportManager(boolean allowServerSideTransportRemoval) { // using weakhashmap means that the transport may be GCed if the server drops its reference, // and thus the listener may be GCed as well if the client drops that reference. if the // server will never drop a reference without warning (ie, transport removal may only be // initiated from the client side), then arraymap or similar may be used without fear of // memory leaks. if (allowServerSideTransportRemoval) { mRegistrations = new WeakHashMap<>(); } else { mRegistrations = new ArrayMap<>(); } } /** Loading @@ -53,16 +58,21 @@ public abstract class ListenerTransportManager<TTransport extends ListenerTransp synchronized (mRegistrations) { // ordering of operations is important so that if an error occurs at any point we // are left in a reasonable state registerTransport(transport); WeakReference<TTransport> oldTransportRef = mRegistrations.put(key, new WeakReference<>(transport)); TTransport oldTransport; WeakReference<TTransport> oldTransportRef = mRegistrations.get(key); if (oldTransportRef != null) { TTransport oldTransport = oldTransportRef.get(); if (oldTransport != null) { oldTransport.unregister(); unregisterTransport(oldTransport); oldTransport = oldTransportRef.get(); } else { oldTransport = null; } if (oldTransport == null) { registerTransport(transport); } else { registerTransport(transport, oldTransport); oldTransport.unregister(); } mRegistrations.put(key, new WeakReference<>(transport)); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); Loading Loading @@ -91,7 +101,33 @@ public abstract class ListenerTransportManager<TTransport extends ListenerTransp } } /** * Registers a new transport. */ protected abstract void registerTransport(TTransport transport) throws RemoteException; /** * Registers a new transport that is replacing the given old transport. Implementations must * ensure that if they throw a remote exception, the call does not have any side effects. */ protected void registerTransport(TTransport transport, TTransport oldTransport) throws RemoteException { registerTransport(transport); try { unregisterTransport(oldTransport); } catch (RemoteException e) { try { // best effort to ensure there are no side effects unregisterTransport(transport); } catch (RemoteException suppressed) { e.addSuppressed(suppressed); } throw e; } } /** * Unregisters an existing transport. */ protected abstract void unregisterTransport(TTransport transport) throws RemoteException; } location/java/android/location/LocationManager.java +42 −9 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import static android.Manifest.permission.ACCESS_COARSE_LOCATION; import static android.Manifest.permission.ACCESS_FINE_LOCATION; import static android.Manifest.permission.LOCATION_HARDWARE; import static android.Manifest.permission.WRITE_SECURE_SETTINGS; import static android.location.GpsStatus.GPS_EVENT_STARTED; import static android.location.LocationRequest.createFromDeprecatedCriteria; import static android.location.LocationRequest.createFromDeprecatedProvider; Loading Loading @@ -412,7 +411,7 @@ public class LocationManager { private static final String CACHE_KEY_LOCATION_ENABLED_PROPERTY = "cache_key.location_enabled"; private static ILocationManager getService() throws RemoteException { static ILocationManager getService() throws RemoteException { try { return ILocationManager.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.LOCATION_SERVICE)); Loading @@ -439,11 +438,13 @@ public class LocationManager { new GnssNavigationTransportManager(); } private static final ProviderRequestTransportManager sProviderRequestListeners = private static class ProviderRequestLazyLoader { static final ProviderRequestTransportManager sProviderRequestListeners = new ProviderRequestTransportManager(); } private final Context mContext; private final ILocationManager mService; final Context mContext; final ILocationManager mService; private volatile PropertyInvalidatedCache<Integer, Boolean> mLocationEnabledCache = new PropertyInvalidatedCache<Integer, Boolean>( Loading Loading @@ -2790,7 +2791,7 @@ public class LocationManager { public boolean registerProviderRequestListener( @NonNull @CallbackExecutor Executor executor, @NonNull Listener listener) { sProviderRequestListeners.addListener(listener, ProviderRequestLazyLoader.sProviderRequestListeners.addListener(listener, new ProviderRequestTransport(executor, listener)); return true; } Loading @@ -2805,7 +2806,7 @@ public class LocationManager { @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) public void unregisterProviderRequestListener( @NonNull Listener listener) { sProviderRequestListeners.removeListener(listener); ProviderRequestLazyLoader.sProviderRequestListeners.removeListener(listener); } /** Loading Loading @@ -2917,6 +2918,10 @@ public class LocationManager { private static class GnssStatusTransportManager extends ListenerTransportManager<GnssStatusTransport> { GnssStatusTransportManager() { super(false); } @Override protected void registerTransport(GnssStatusTransport transport) throws RemoteException { Loading @@ -2934,6 +2939,10 @@ public class LocationManager { private static class GnssNmeaTransportManager extends ListenerTransportManager<GnssNmeaTransport> { GnssNmeaTransportManager() { super(false); } @Override protected void registerTransport(GnssNmeaTransport transport) throws RemoteException { Loading @@ -2951,6 +2960,10 @@ public class LocationManager { private static class GnssMeasurementsTransportManager extends ListenerTransportManager<GnssMeasurementsTransport> { GnssMeasurementsTransportManager() { super(false); } @Override protected void registerTransport(GnssMeasurementsTransport transport) throws RemoteException { Loading @@ -2968,6 +2981,10 @@ public class LocationManager { private static class GnssAntennaTransportManager extends ListenerTransportManager<GnssAntennaInfoTransport> { GnssAntennaTransportManager() { super(false); } @Override protected void registerTransport(GnssAntennaInfoTransport transport) { transport.getContext().registerReceiver(transport, Loading @@ -2983,6 +3000,10 @@ public class LocationManager { private static class GnssNavigationTransportManager extends ListenerTransportManager<GnssNavigationTransport> { GnssNavigationTransportManager() { super(false); } @Override protected void registerTransport(GnssNavigationTransport transport) throws RemoteException { Loading @@ -3000,6 +3021,10 @@ public class LocationManager { private static class ProviderRequestTransportManager extends ListenerTransportManager<ProviderRequestTransport> { ProviderRequestTransportManager() { super(false); } @Override protected void registerTransport(ProviderRequestTransport transport) throws RemoteException { Loading Loading @@ -3117,6 +3142,8 @@ public class LocationManager { } } /** @deprecated */ @Deprecated private static class GpsAdapter extends GnssStatus.Callback { private final GpsStatus.Listener mGpsListener; Loading @@ -3127,7 +3154,7 @@ public class LocationManager { @Override public void onStarted() { mGpsListener.onGpsStatusChanged(GPS_EVENT_STARTED); mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STARTED); } @Override Loading Loading @@ -3204,6 +3231,8 @@ public class LocationManager { } } /** @deprecated */ @Deprecated private static class GpsStatusTransport extends GnssStatusTransport { static volatile int sTtff; Loading Loading @@ -3442,6 +3471,8 @@ public class LocationManager { } } /** @deprecated */ @Deprecated private static class BatchedLocationCallbackWrapper implements LocationListener { private final BatchedLocationCallback mCallback; Loading @@ -3461,6 +3492,8 @@ public class LocationManager { } } /** @deprecated */ @Deprecated private static class BatchedLocationCallbackTransport extends LocationListenerTransport { BatchedLocationCallbackTransport(BatchedLocationCallback callback, Handler handler) { Loading Loading
core/java/com/android/internal/listeners/ListenerTransportManager.java +46 −10 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.internal.listeners; import android.os.RemoteException; import android.util.ArrayMap; import com.android.internal.annotations.GuardedBy; Loading @@ -36,13 +37,17 @@ public abstract class ListenerTransportManager<TTransport extends ListenerTransp @GuardedBy("mRegistrations") private final Map<Object, WeakReference<TTransport>> mRegistrations; protected ListenerTransportManager() { protected ListenerTransportManager(boolean allowServerSideTransportRemoval) { // using weakhashmap means that the transport may be GCed if the server drops its reference, // and thus the listener may be GCed as well if the client drops that reference. if the // server will never drop a reference without warning (ie, transport removal may only be // initiated from the client side), then arraymap or similar may be used without fear of // memory leaks. if (allowServerSideTransportRemoval) { mRegistrations = new WeakHashMap<>(); } else { mRegistrations = new ArrayMap<>(); } } /** Loading @@ -53,16 +58,21 @@ public abstract class ListenerTransportManager<TTransport extends ListenerTransp synchronized (mRegistrations) { // ordering of operations is important so that if an error occurs at any point we // are left in a reasonable state registerTransport(transport); WeakReference<TTransport> oldTransportRef = mRegistrations.put(key, new WeakReference<>(transport)); TTransport oldTransport; WeakReference<TTransport> oldTransportRef = mRegistrations.get(key); if (oldTransportRef != null) { TTransport oldTransport = oldTransportRef.get(); if (oldTransport != null) { oldTransport.unregister(); unregisterTransport(oldTransport); oldTransport = oldTransportRef.get(); } else { oldTransport = null; } if (oldTransport == null) { registerTransport(transport); } else { registerTransport(transport, oldTransport); oldTransport.unregister(); } mRegistrations.put(key, new WeakReference<>(transport)); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); Loading Loading @@ -91,7 +101,33 @@ public abstract class ListenerTransportManager<TTransport extends ListenerTransp } } /** * Registers a new transport. */ protected abstract void registerTransport(TTransport transport) throws RemoteException; /** * Registers a new transport that is replacing the given old transport. Implementations must * ensure that if they throw a remote exception, the call does not have any side effects. */ protected void registerTransport(TTransport transport, TTransport oldTransport) throws RemoteException { registerTransport(transport); try { unregisterTransport(oldTransport); } catch (RemoteException e) { try { // best effort to ensure there are no side effects unregisterTransport(transport); } catch (RemoteException suppressed) { e.addSuppressed(suppressed); } throw e; } } /** * Unregisters an existing transport. */ protected abstract void unregisterTransport(TTransport transport) throws RemoteException; }
location/java/android/location/LocationManager.java +42 −9 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import static android.Manifest.permission.ACCESS_COARSE_LOCATION; import static android.Manifest.permission.ACCESS_FINE_LOCATION; import static android.Manifest.permission.LOCATION_HARDWARE; import static android.Manifest.permission.WRITE_SECURE_SETTINGS; import static android.location.GpsStatus.GPS_EVENT_STARTED; import static android.location.LocationRequest.createFromDeprecatedCriteria; import static android.location.LocationRequest.createFromDeprecatedProvider; Loading Loading @@ -412,7 +411,7 @@ public class LocationManager { private static final String CACHE_KEY_LOCATION_ENABLED_PROPERTY = "cache_key.location_enabled"; private static ILocationManager getService() throws RemoteException { static ILocationManager getService() throws RemoteException { try { return ILocationManager.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.LOCATION_SERVICE)); Loading @@ -439,11 +438,13 @@ public class LocationManager { new GnssNavigationTransportManager(); } private static final ProviderRequestTransportManager sProviderRequestListeners = private static class ProviderRequestLazyLoader { static final ProviderRequestTransportManager sProviderRequestListeners = new ProviderRequestTransportManager(); } private final Context mContext; private final ILocationManager mService; final Context mContext; final ILocationManager mService; private volatile PropertyInvalidatedCache<Integer, Boolean> mLocationEnabledCache = new PropertyInvalidatedCache<Integer, Boolean>( Loading Loading @@ -2790,7 +2791,7 @@ public class LocationManager { public boolean registerProviderRequestListener( @NonNull @CallbackExecutor Executor executor, @NonNull Listener listener) { sProviderRequestListeners.addListener(listener, ProviderRequestLazyLoader.sProviderRequestListeners.addListener(listener, new ProviderRequestTransport(executor, listener)); return true; } Loading @@ -2805,7 +2806,7 @@ public class LocationManager { @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) public void unregisterProviderRequestListener( @NonNull Listener listener) { sProviderRequestListeners.removeListener(listener); ProviderRequestLazyLoader.sProviderRequestListeners.removeListener(listener); } /** Loading Loading @@ -2917,6 +2918,10 @@ public class LocationManager { private static class GnssStatusTransportManager extends ListenerTransportManager<GnssStatusTransport> { GnssStatusTransportManager() { super(false); } @Override protected void registerTransport(GnssStatusTransport transport) throws RemoteException { Loading @@ -2934,6 +2939,10 @@ public class LocationManager { private static class GnssNmeaTransportManager extends ListenerTransportManager<GnssNmeaTransport> { GnssNmeaTransportManager() { super(false); } @Override protected void registerTransport(GnssNmeaTransport transport) throws RemoteException { Loading @@ -2951,6 +2960,10 @@ public class LocationManager { private static class GnssMeasurementsTransportManager extends ListenerTransportManager<GnssMeasurementsTransport> { GnssMeasurementsTransportManager() { super(false); } @Override protected void registerTransport(GnssMeasurementsTransport transport) throws RemoteException { Loading @@ -2968,6 +2981,10 @@ public class LocationManager { private static class GnssAntennaTransportManager extends ListenerTransportManager<GnssAntennaInfoTransport> { GnssAntennaTransportManager() { super(false); } @Override protected void registerTransport(GnssAntennaInfoTransport transport) { transport.getContext().registerReceiver(transport, Loading @@ -2983,6 +3000,10 @@ public class LocationManager { private static class GnssNavigationTransportManager extends ListenerTransportManager<GnssNavigationTransport> { GnssNavigationTransportManager() { super(false); } @Override protected void registerTransport(GnssNavigationTransport transport) throws RemoteException { Loading @@ -3000,6 +3021,10 @@ public class LocationManager { private static class ProviderRequestTransportManager extends ListenerTransportManager<ProviderRequestTransport> { ProviderRequestTransportManager() { super(false); } @Override protected void registerTransport(ProviderRequestTransport transport) throws RemoteException { Loading Loading @@ -3117,6 +3142,8 @@ public class LocationManager { } } /** @deprecated */ @Deprecated private static class GpsAdapter extends GnssStatus.Callback { private final GpsStatus.Listener mGpsListener; Loading @@ -3127,7 +3154,7 @@ public class LocationManager { @Override public void onStarted() { mGpsListener.onGpsStatusChanged(GPS_EVENT_STARTED); mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STARTED); } @Override Loading Loading @@ -3204,6 +3231,8 @@ public class LocationManager { } } /** @deprecated */ @Deprecated private static class GpsStatusTransport extends GnssStatusTransport { static volatile int sTtff; Loading Loading @@ -3442,6 +3471,8 @@ public class LocationManager { } } /** @deprecated */ @Deprecated private static class BatchedLocationCallbackWrapper implements LocationListener { private final BatchedLocationCallback mCallback; Loading @@ -3461,6 +3492,8 @@ public class LocationManager { } } /** @deprecated */ @Deprecated private static class BatchedLocationCallbackTransport extends LocationListenerTransport { BatchedLocationCallbackTransport(BatchedLocationCallback callback, Handler handler) { Loading