Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d872ad7f authored by Dante Russo's avatar Dante Russo Committed by Android (Google) Code Review
Browse files

Merge changes I11204b07,I8ad3fb6f into main

* changes:
  Add missing attribution tags to com.android.location.fused
  Add an unstable fallback for the gnss/fused location provider overlay
parents 4bae066d fca4bcdd
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -233,6 +233,7 @@ public final class CurrentUserServiceSupplier extends BroadcastReceiver implemen
    private final boolean mMatchSystemAppsOnly;

    private volatile ServiceChangedListener mListener;
    private @Nullable String mUnstableService;

    private CurrentUserServiceSupplier(Context context, String action,
            @Nullable String explicitPackage, @Nullable String callerPermission,
@@ -330,6 +331,20 @@ public final class CurrentUserServiceSupplier extends BroadcastReceiver implemen
                }
            }

            // Prefer any service over the unstable service.
            if (mUnstableService != null && serviceInfo != null && bestServiceInfo != null) {
              if (mUnstableService.equals(serviceInfo.toString())) {
                  Log.d(TAG, "Not choosing unstable service " + mUnstableService
                          + " as we already have a service " + bestServiceInfo.toString());
                  continue;
              } else if (mUnstableService.equals(bestServiceInfo.toString())) {
                  Log.d(TAG, "Choosing service " + serviceInfo.toString()
                          + " over the unstable service " + mUnstableService);
                  bestServiceInfo = serviceInfo;
                  continue;
              }
            }

            if (sBoundServiceInfoComparator.compare(serviceInfo, bestServiceInfo) > 0) {
                bestServiceInfo = serviceInfo;
            }
@@ -338,6 +353,17 @@ public final class CurrentUserServiceSupplier extends BroadcastReceiver implemen
        return bestServiceInfo;
    }

    /**
     * Alerts the supplier that the given service is unstable.
     *
     * The service marked as unstable will be unpreferred over any other services,
     * which will last until the next device restart.
     */
    @Override
    public void alertUnstableService(String unstableService) {
        mUnstableService = unstableService;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
+32 −0
Original line number Diff line number Diff line
@@ -140,6 +140,11 @@ public interface ServiceWatcher {
         * null if no service currently meets the criteria. Only invoked while registered.
         */
        @Nullable TBoundServiceInfo getServiceInfo();

        /**
         * Alerts the supplier that the given service is unstable.
         */
        void alertUnstableService(String unstableService);
    }

    /**
@@ -229,6 +234,19 @@ public interface ServiceWatcher {
        return create(context, FgThread.getHandler(), tag, serviceSupplier, serviceListener);
    }

    /**
     * Creates a new ServiceWatcher instance.
     */
    static <TBoundServiceInfo extends BoundServiceInfo> ServiceWatcher create(
            Context context,
            String tag,
            boolean unstableFallbackEnabled,
            ServiceSupplier<TBoundServiceInfo> serviceSupplier,
            @Nullable ServiceListener<? super TBoundServiceInfo> serviceListener) {
        return create(context, FgThread.getHandler(), tag, unstableFallbackEnabled,
            serviceSupplier, serviceListener);
    }

    /**
     * Creates a new ServiceWatcher instance that runs on the given handler.
     */
@@ -241,6 +259,20 @@ public interface ServiceWatcher {
        return new ServiceWatcherImpl<>(context, handler, tag, serviceSupplier, serviceListener);
    }

    /**
     * Creates a new ServiceWatcher instance that runs on the given handler.
     */
    static <TBoundServiceInfo extends BoundServiceInfo> ServiceWatcher create(
            Context context,
            Handler handler,
            String tag,
            boolean unstableFallbackEnabled,
            ServiceSupplier<TBoundServiceInfo> serviceSupplier,
            @Nullable ServiceListener<? super TBoundServiceInfo> serviceListener) {
        return new ServiceWatcherImpl<>(context, handler, tag, unstableFallbackEnabled,
            serviceSupplier, serviceListener);
    }

    /**
     * Returns true if there is at least one service that the ServiceWatcher could hypothetically
     * bind to, as selected by the {@link ServiceSupplier}.
+74 −1
Original line number Diff line number Diff line
@@ -21,11 +21,13 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.location.flags.Flags;
import android.os.DeadObjectException;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.Log;

@@ -52,12 +54,22 @@ class ServiceWatcherImpl<TBoundServiceInfo extends BoundServiceInfo> implements
    static final boolean D = Log.isLoggable(TAG, Log.DEBUG);

    static final long RETRY_DELAY_MS = 15 * 1000;
    /* Used for the unstable fallback logic, it is the time period in milliseconds where the number
     * of disconnections is tracked in order to determine if the service is unstable. */
    private static final long UNSTABLE_TIME_PERIOD_MS = 60 * 1000;
    /* Used for the unstable fallback logic, it is the number of disconnections within the time
     * period that will mark the service as unstable and allow the fallback to a stable service. */
    private static final int DISCONNECTED_COUNT_BEFORE_MARKED_AS_UNSTABLE = 10;

    final Context mContext;
    final Handler mHandler;
    final String mTag;
    final ServiceSupplier<TBoundServiceInfo> mServiceSupplier;
    final @Nullable ServiceListener<? super TBoundServiceInfo> mServiceListener;
    private boolean mUnstableFallbackEnabled;
    private @Nullable String mDisconnectedService;
    private long mDisconnectedStartTime;
    private int mDisconnectedCount;

    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
        @Override
@@ -86,6 +98,20 @@ class ServiceWatcherImpl<TBoundServiceInfo extends BoundServiceInfo> implements
        mServiceListener = serviceListener;
    }

    ServiceWatcherImpl(Context context, Handler handler, String tag,
            boolean unstableFallbackEnabled,
            ServiceSupplier<TBoundServiceInfo> serviceSupplier,
            ServiceListener<? super TBoundServiceInfo> serviceListener) {
        mContext = context;
        mHandler = handler;
        mTag = tag;
        if (Flags.serviceWatcherUnstableFallback()) {
            mUnstableFallbackEnabled = unstableFallbackEnabled;
        }
        mServiceSupplier = serviceSupplier;
        mServiceListener = serviceListener;
    }

    @Override
    public boolean checkServiceResolves() {
        return mServiceSupplier.hasMatchingService();
@@ -178,6 +204,7 @@ class ServiceWatcherImpl<TBoundServiceInfo extends BoundServiceInfo> implements
        // volatile so that isConnected can be called from any thread easily
        private volatile @Nullable IBinder mBinder;
        private @Nullable Runnable mRebinder;
        private boolean mForcingRebind;

        MyServiceConnection(@Nullable TBoundServiceInfo boundServiceInfo) {
            mBoundServiceInfo = boundServiceInfo;
@@ -269,6 +296,11 @@ class ServiceWatcherImpl<TBoundServiceInfo extends BoundServiceInfo> implements
            Log.i(TAG, "[" + mTag + "] connected to " + component.toShortString());

            mBinder = binder;
            /* Used to keep track of whether we are forcing a rebind, so that we don't force a
             * rebind while in the process of already forcing a rebind. This is needed because
             * onServiceDisconnected and onBindingDied can happen in quick succession and we only
             * want one rebind to happen in this case. */
            mForcingRebind = false;

            if (mServiceListener != null) {
                try {
@@ -295,6 +327,44 @@ class ServiceWatcherImpl<TBoundServiceInfo extends BoundServiceInfo> implements
            if (mServiceListener != null) {
                mServiceListener.onUnbind();
            }

            // If unstable fallback is not enabled or no current service is bound, then avoid the
            // unstable fallback logic below and return early.
            if (!mUnstableFallbackEnabled
                    || mBoundServiceInfo == null
                    || mBoundServiceInfo.toString() == null) {
                return;
            }

            String currentService = mBoundServiceInfo.toString();
            // If the service has already disconnected within the time period, increment the count.
            // Otherwise, set the service as disconnected, set the start time, and reset the count.
            if (Objects.equals(mDisconnectedService, currentService)
                    && mDisconnectedStartTime > 0
                    && (SystemClock.elapsedRealtime() - mDisconnectedStartTime
                            <= UNSTABLE_TIME_PERIOD_MS)) {
                mDisconnectedCount++;
            } else {
                mDisconnectedService = currentService;
                mDisconnectedStartTime = SystemClock.elapsedRealtime();
                mDisconnectedCount = 1;
            }
            Log.d(TAG, "[" + mTag + "] Service disconnected : " + currentService + " Count = "
                + mDisconnectedCount);
            if (mDisconnectedCount >= DISCONNECTED_COUNT_BEFORE_MARKED_AS_UNSTABLE) {
                Log.i(TAG, "[" + mTag + "] Service disconnected too many times, set as unstable : "
                    + mDisconnectedService);
                // Alert this service as unstable will last until the next device restart.
                mServiceSupplier.alertUnstableService(mDisconnectedService);
                mDisconnectedService = null;
                mDisconnectedStartTime = 0;
                mDisconnectedCount = 0;
                // Force rebind to allow the possibility of fallback to a stable service.
                if (!mForcingRebind) {
                    mForcingRebind = true;
                    onServiceChanged(/*forceRebind=*/ true);
                }
            }
        }

        @Override
@@ -305,7 +375,10 @@ class ServiceWatcherImpl<TBoundServiceInfo extends BoundServiceInfo> implements

            // introduce a small delay to prevent spamming binding over and over, since the likely
            // cause of a binding dying is some package event that may take time to recover from
            mHandler.postDelayed(() -> onServiceChanged(true), 500);
            if (!mForcingRebind) {
                mForcingRebind = true;
                mHandler.postDelayed(() -> onServiceChanged(/*forceRebind=*/ true), 500);
            }
        }

        @Override
+13 −0
Original line number Diff line number Diff line
@@ -2125,14 +2125,27 @@
    <!-- Package name providing fused location support. Used only when
         config_enableFusedLocationOverlay is false. -->
    <string name="config_fusedLocationProviderPackageName" translatable="false">com.android.location.fused</string>
    <!-- If true, will fallback to use a different app if the chosen overlay app is determined to
         be unstable. Used only when config_enableFusedLocationOverlay is true. -->
    <bool name="config_fusedLocationOverlayUnstableFallback" translatable="false">false</bool>

    <!-- If true will use the GNSS hardware implementation to service the GPS_PROVIDER. If false
         will allow the GPS_PROVIDER to be replaced by an app at run-time (restricted to the package
         specified by config_gnssLocationProviderPackageName). -->
    <bool name="config_useGnssHardwareProvider" translatable="false">true</bool>
    <!-- Whether to enable gnss location provider overlay which allows gnss location provider to
         be replaced by an app at run-time. When disabled, only the
         config_gnssLocationProviderPackageName package will be searched for gnss location
         provider, otherwise any system package is eligible. Anyone who wants to disable the overlay
         mechanism can set it to false. Used only when config_useGnssHardwareProvider is false -->
    <bool name="config_enableGnssLocationOverlay" translatable="false">true</bool>
    <!-- Package name providing GNSS location support. Used only when
         config_useGnssHardwareProvider is false. -->
    <string name="config_gnssLocationProviderPackageName" translatable="false">@null</string>
    <!-- If true, will fallback to use a different app if the chosen overlay app is determined to
         be unstable. Used only when config_useGnssHardwareProvider is false and
         config_enableGnssLocationOverlay is true. -->
    <bool name="config_gnssLocationOverlayUnstableFallback" translatable="false">false</bool>

    <!-- Default value for the ADAS GNSS Location Enabled setting if this setting has never been
         set before. -->
+3 −0
Original line number Diff line number Diff line
@@ -2050,6 +2050,9 @@
  <java-symbol type="bool" name="config_enableActivityRecognitionHardwareOverlay" />
  <java-symbol type="bool" name="config_defaultAdasGnssLocationEnabled" />
  <java-symbol type="bool" name="config_enableFusedLocationOverlay" />
  <java-symbol type="bool" name="config_enableGnssLocationOverlay" />
  <java-symbol type="bool" name="config_fusedLocationOverlayUnstableFallback" />
  <java-symbol type="bool" name="config_gnssLocationOverlayUnstableFallback" />
  <java-symbol type="bool" name="config_useGnssHardwareProvider" />
  <java-symbol type="bool" name="config_enableGeocoderOverlay" />
  <java-symbol type="bool" name="config_enableGeofenceOverlay" />
Loading