Loading location/java/android/location/AbstractListenerManager.javadeleted 100644 → 0 +0 −220 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 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; import android.os.Handler; import android.os.HandlerExecutor; import android.os.RemoteException; import android.util.ArrayMap; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; import java.util.Objects; import java.util.concurrent.Executor; import java.util.function.Consumer; /** * A base class to manage listeners that have a 1:N -> source:listener relationship. * * @hide */ abstract class AbstractListenerManager<TRequest, TListener> { private static class Registration<TRequest, TListener> { private final Executor mExecutor; @Nullable private TRequest mRequest; @Nullable private volatile TListener mListener; private Registration(@Nullable TRequest request, Executor executor, TListener listener) { Preconditions.checkArgument(listener != null, "invalid null listener/callback"); Preconditions.checkArgument(executor != null, "invalid null executor"); mExecutor = executor; mListener = listener; mRequest = request; } @Nullable public TRequest getRequest() { return mRequest; } private void unregister() { mRequest = null; mListener = null; } private void execute(Consumer<TListener> operation) { mExecutor.execute( obtainRunnable(Registration<TRequest, TListener>::accept, this, operation) .recycleOnUse()); } 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); } } } @GuardedBy("mListeners") private final ArrayMap<Object, Registration<TRequest, TListener>> mListeners = new ArrayMap<>(); @GuardedBy("mListeners") @Nullable private TRequest mMergedRequest; public boolean addListener(@NonNull TListener listener, @NonNull Handler handler) throws RemoteException { return addInternal(/* request= */ null, listener, handler); } public boolean addListener(@NonNull TListener listener, @NonNull Executor executor) throws RemoteException { return addInternal(/* request= */ null, listener, executor); } public boolean addListener(@Nullable TRequest request, @NonNull TListener listener, @NonNull Handler handler) throws RemoteException { return addInternal(request, listener, handler); } public boolean addListener(@Nullable TRequest request, @NonNull TListener listener, @NonNull Executor executor) throws RemoteException { return addInternal(request, listener, executor); } protected final boolean addInternal(@Nullable TRequest request, @NonNull Object listener, @NonNull Handler handler) throws RemoteException { return addInternal(request, listener, new HandlerExecutor(handler)); } protected final boolean addInternal(@Nullable TRequest request, @NonNull Object listener, @NonNull Executor executor) throws RemoteException { Preconditions.checkArgument(listener != null, "invalid null listener/callback"); return addInternal(listener, new Registration<>(request, executor, convertKey(listener))); } private boolean addInternal(Object key, Registration<TRequest, TListener> registration) throws RemoteException { Preconditions.checkNotNull(registration); synchronized (mListeners) { boolean initialRequest = mListeners.isEmpty(); Registration<TRequest, TListener> oldRegistration = mListeners.put(key, registration); if (oldRegistration != null) { oldRegistration.unregister(); } TRequest merged = mergeRequests(); if (initialRequest || !Objects.equals(merged, mMergedRequest)) { mMergedRequest = merged; if (!initialRequest) { unregisterService(); } registerService(mMergedRequest); } return true; } } public void removeListener(Object listener) throws RemoteException { synchronized (mListeners) { Registration<TRequest, TListener> oldRegistration = mListeners.remove(listener); if (oldRegistration == null) { return; } oldRegistration.unregister(); boolean lastRequest = mListeners.isEmpty(); TRequest merged = lastRequest ? null : mergeRequests(); boolean newRequest = !lastRequest && !Objects.equals(merged, mMergedRequest); if (lastRequest || newRequest) { unregisterService(); mMergedRequest = merged; if (newRequest) { registerService(mMergedRequest); } } } } @SuppressWarnings("unchecked") protected TListener convertKey(@NonNull Object listener) { return (TListener) listener; } protected abstract boolean registerService(TRequest request) throws RemoteException; protected abstract void unregisterService() throws RemoteException; @Nullable protected TRequest merge(@NonNull TRequest[] requests) { for (TRequest request : requests) { Preconditions.checkArgument(request == null, "merge() has to be overridden for non-null requests."); } return null; } protected void execute(Consumer<TListener> operation) { synchronized (mListeners) { for (Registration<TRequest, TListener> registration : mListeners.values()) { registration.execute(operation); } } } @GuardedBy("mListeners") @SuppressWarnings("unchecked") @Nullable private TRequest mergeRequests() { Preconditions.checkState(Thread.holdsLock(mListeners)); if (mListeners.isEmpty()) { return null; } if (mListeners.size() == 1) { return mListeners.valueAt(0).getRequest(); } TRequest[] requests = (TRequest[]) new Object[mListeners.size()]; for (int index = 0; index < mListeners.size(); index++) { requests[index] = mListeners.valueAt(index).getRequest(); } return merge(requests); } } location/java/android/location/GnssRequest.java +3 −1 Original line number Diff line number Diff line Loading @@ -70,7 +70,9 @@ public final class GnssRequest implements Parcelable { public String toString() { StringBuilder s = new StringBuilder(); s.append("GnssRequest["); s.append("FullTracking=").append(mFullTracking); if (mFullTracking) { s.append("FullTracking"); } s.append(']'); return s.toString(); } Loading location/java/android/location/ILocationManager.aidl +13 −18 Original line number Diff line number Diff line Loading @@ -57,10 +57,6 @@ interface ILocationManager in PendingIntent intent, String packageName, String featureId); void removeGeofence(in Geofence fence, in PendingIntent intent, String packageName); boolean registerGnssStatusCallback(IGnssStatusListener callback, String packageName, String featureId); void unregisterGnssStatusCallback(IGnssStatusListener callback); boolean geocoderIsPresent(); String getFromLocation(double latitude, double longitude, int maxResults, in GeocoderParams params, out List<Address> addrs); Loading @@ -69,31 +65,30 @@ interface ILocationManager double upperRightLatitude, double upperRightLongitude, int maxResults, in GeocoderParams params, out List<Address> addrs); boolean addGnssMeasurementsListener(in GnssRequest request, in IGnssMeasurementsListener listener, String packageName, String featureId); void injectGnssMeasurementCorrections(in GnssMeasurementCorrections corrections, in String packageName); long getGnssCapabilities(); int getGnssYearOfHardware(); String getGnssHardwareModelName(); void registerGnssStatusCallback(in IGnssStatusListener callback, String packageName, String featureId); void unregisterGnssStatusCallback(in IGnssStatusListener callback); void addGnssMeasurementsListener(in GnssRequest request, in IGnssMeasurementsListener listener, String packageName, String featureId); void removeGnssMeasurementsListener(in IGnssMeasurementsListener listener); boolean addGnssAntennaInfoListener(in IGnssAntennaInfoListener listener, String packageName, String featureId); void addGnssAntennaInfoListener(in IGnssAntennaInfoListener listener, String packageName, String featureId); void removeGnssAntennaInfoListener(in IGnssAntennaInfoListener listener); boolean addGnssNavigationMessageListener(in IGnssNavigationMessageListener listener, String packageName, String featureId); void addGnssNavigationMessageListener(in IGnssNavigationMessageListener listener, String packageName, String featureId); void removeGnssNavigationMessageListener(in IGnssNavigationMessageListener listener); int getGnssYearOfHardware(); String getGnssHardwareModelName(); void injectGnssMeasurementCorrections(in GnssMeasurementCorrections corrections, String packageName); int getGnssBatchSize(String packageName); boolean addGnssBatchingCallback(in IBatchedLocationCallback callback, String packageName, String featureId); void addGnssBatchingCallback(in IBatchedLocationCallback callback, String packageName, String featureId); void removeGnssBatchingCallback(); boolean startGnssBatch(long periodNanos, boolean wakeOnFifoFull, String packageName, String featureId); void startGnssBatch(long periodNanos, boolean wakeOnFifoFull, String packageName, String featureId); void flushGnssBatch(String packageName); boolean stopGnssBatch(); void stopGnssBatch(); void injectLocation(in Location location); List<String> getAllProviders(); Loading Loading
location/java/android/location/AbstractListenerManager.javadeleted 100644 → 0 +0 −220 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 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; import android.os.Handler; import android.os.HandlerExecutor; import android.os.RemoteException; import android.util.ArrayMap; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; import java.util.Objects; import java.util.concurrent.Executor; import java.util.function.Consumer; /** * A base class to manage listeners that have a 1:N -> source:listener relationship. * * @hide */ abstract class AbstractListenerManager<TRequest, TListener> { private static class Registration<TRequest, TListener> { private final Executor mExecutor; @Nullable private TRequest mRequest; @Nullable private volatile TListener mListener; private Registration(@Nullable TRequest request, Executor executor, TListener listener) { Preconditions.checkArgument(listener != null, "invalid null listener/callback"); Preconditions.checkArgument(executor != null, "invalid null executor"); mExecutor = executor; mListener = listener; mRequest = request; } @Nullable public TRequest getRequest() { return mRequest; } private void unregister() { mRequest = null; mListener = null; } private void execute(Consumer<TListener> operation) { mExecutor.execute( obtainRunnable(Registration<TRequest, TListener>::accept, this, operation) .recycleOnUse()); } 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); } } } @GuardedBy("mListeners") private final ArrayMap<Object, Registration<TRequest, TListener>> mListeners = new ArrayMap<>(); @GuardedBy("mListeners") @Nullable private TRequest mMergedRequest; public boolean addListener(@NonNull TListener listener, @NonNull Handler handler) throws RemoteException { return addInternal(/* request= */ null, listener, handler); } public boolean addListener(@NonNull TListener listener, @NonNull Executor executor) throws RemoteException { return addInternal(/* request= */ null, listener, executor); } public boolean addListener(@Nullable TRequest request, @NonNull TListener listener, @NonNull Handler handler) throws RemoteException { return addInternal(request, listener, handler); } public boolean addListener(@Nullable TRequest request, @NonNull TListener listener, @NonNull Executor executor) throws RemoteException { return addInternal(request, listener, executor); } protected final boolean addInternal(@Nullable TRequest request, @NonNull Object listener, @NonNull Handler handler) throws RemoteException { return addInternal(request, listener, new HandlerExecutor(handler)); } protected final boolean addInternal(@Nullable TRequest request, @NonNull Object listener, @NonNull Executor executor) throws RemoteException { Preconditions.checkArgument(listener != null, "invalid null listener/callback"); return addInternal(listener, new Registration<>(request, executor, convertKey(listener))); } private boolean addInternal(Object key, Registration<TRequest, TListener> registration) throws RemoteException { Preconditions.checkNotNull(registration); synchronized (mListeners) { boolean initialRequest = mListeners.isEmpty(); Registration<TRequest, TListener> oldRegistration = mListeners.put(key, registration); if (oldRegistration != null) { oldRegistration.unregister(); } TRequest merged = mergeRequests(); if (initialRequest || !Objects.equals(merged, mMergedRequest)) { mMergedRequest = merged; if (!initialRequest) { unregisterService(); } registerService(mMergedRequest); } return true; } } public void removeListener(Object listener) throws RemoteException { synchronized (mListeners) { Registration<TRequest, TListener> oldRegistration = mListeners.remove(listener); if (oldRegistration == null) { return; } oldRegistration.unregister(); boolean lastRequest = mListeners.isEmpty(); TRequest merged = lastRequest ? null : mergeRequests(); boolean newRequest = !lastRequest && !Objects.equals(merged, mMergedRequest); if (lastRequest || newRequest) { unregisterService(); mMergedRequest = merged; if (newRequest) { registerService(mMergedRequest); } } } } @SuppressWarnings("unchecked") protected TListener convertKey(@NonNull Object listener) { return (TListener) listener; } protected abstract boolean registerService(TRequest request) throws RemoteException; protected abstract void unregisterService() throws RemoteException; @Nullable protected TRequest merge(@NonNull TRequest[] requests) { for (TRequest request : requests) { Preconditions.checkArgument(request == null, "merge() has to be overridden for non-null requests."); } return null; } protected void execute(Consumer<TListener> operation) { synchronized (mListeners) { for (Registration<TRequest, TListener> registration : mListeners.values()) { registration.execute(operation); } } } @GuardedBy("mListeners") @SuppressWarnings("unchecked") @Nullable private TRequest mergeRequests() { Preconditions.checkState(Thread.holdsLock(mListeners)); if (mListeners.isEmpty()) { return null; } if (mListeners.size() == 1) { return mListeners.valueAt(0).getRequest(); } TRequest[] requests = (TRequest[]) new Object[mListeners.size()]; for (int index = 0; index < mListeners.size(); index++) { requests[index] = mListeners.valueAt(index).getRequest(); } return merge(requests); } }
location/java/android/location/GnssRequest.java +3 −1 Original line number Diff line number Diff line Loading @@ -70,7 +70,9 @@ public final class GnssRequest implements Parcelable { public String toString() { StringBuilder s = new StringBuilder(); s.append("GnssRequest["); s.append("FullTracking=").append(mFullTracking); if (mFullTracking) { s.append("FullTracking"); } s.append(']'); return s.toString(); } Loading
location/java/android/location/ILocationManager.aidl +13 −18 Original line number Diff line number Diff line Loading @@ -57,10 +57,6 @@ interface ILocationManager in PendingIntent intent, String packageName, String featureId); void removeGeofence(in Geofence fence, in PendingIntent intent, String packageName); boolean registerGnssStatusCallback(IGnssStatusListener callback, String packageName, String featureId); void unregisterGnssStatusCallback(IGnssStatusListener callback); boolean geocoderIsPresent(); String getFromLocation(double latitude, double longitude, int maxResults, in GeocoderParams params, out List<Address> addrs); Loading @@ -69,31 +65,30 @@ interface ILocationManager double upperRightLatitude, double upperRightLongitude, int maxResults, in GeocoderParams params, out List<Address> addrs); boolean addGnssMeasurementsListener(in GnssRequest request, in IGnssMeasurementsListener listener, String packageName, String featureId); void injectGnssMeasurementCorrections(in GnssMeasurementCorrections corrections, in String packageName); long getGnssCapabilities(); int getGnssYearOfHardware(); String getGnssHardwareModelName(); void registerGnssStatusCallback(in IGnssStatusListener callback, String packageName, String featureId); void unregisterGnssStatusCallback(in IGnssStatusListener callback); void addGnssMeasurementsListener(in GnssRequest request, in IGnssMeasurementsListener listener, String packageName, String featureId); void removeGnssMeasurementsListener(in IGnssMeasurementsListener listener); boolean addGnssAntennaInfoListener(in IGnssAntennaInfoListener listener, String packageName, String featureId); void addGnssAntennaInfoListener(in IGnssAntennaInfoListener listener, String packageName, String featureId); void removeGnssAntennaInfoListener(in IGnssAntennaInfoListener listener); boolean addGnssNavigationMessageListener(in IGnssNavigationMessageListener listener, String packageName, String featureId); void addGnssNavigationMessageListener(in IGnssNavigationMessageListener listener, String packageName, String featureId); void removeGnssNavigationMessageListener(in IGnssNavigationMessageListener listener); int getGnssYearOfHardware(); String getGnssHardwareModelName(); void injectGnssMeasurementCorrections(in GnssMeasurementCorrections corrections, String packageName); int getGnssBatchSize(String packageName); boolean addGnssBatchingCallback(in IBatchedLocationCallback callback, String packageName, String featureId); void addGnssBatchingCallback(in IBatchedLocationCallback callback, String packageName, String featureId); void removeGnssBatchingCallback(); boolean startGnssBatch(long periodNanos, boolean wakeOnFifoFull, String packageName, String featureId); void startGnssBatch(long periodNanos, boolean wakeOnFifoFull, String packageName, String featureId); void flushGnssBatch(String packageName); boolean stopGnssBatch(); void stopGnssBatch(); void injectLocation(in Location location); List<String> getAllProviders(); Loading