summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Dante Russo <russodante@google.com> 2025-03-19 17:26:05 -0700
committer Android (Google) Code Review <android-gerrit@google.com> 2025-03-19 17:26:05 -0700
commitd872ad7f84c0d5af72e709f2e3f7913a785c9cae (patch)
tree8db6797045b32b61e9c5f5f57459509516d6d90b
parent4bae066de0e2249d74022e90eed3e33dd78171a3 (diff)
parentfca4bcdd90f2bb276dd9869e99c3912546b37887 (diff)
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
-rw-r--r--core/java/com/android/server/servicewatcher/CurrentUserServiceSupplier.java26
-rw-r--r--core/java/com/android/server/servicewatcher/ServiceWatcher.java32
-rw-r--r--core/java/com/android/server/servicewatcher/ServiceWatcherImpl.java75
-rw-r--r--core/res/res/values/config.xml13
-rw-r--r--core/res/res/values/symbols.xml3
-rw-r--r--location/java/android/location/flags/location.aconfig14
-rw-r--r--packages/FusedLocation/AndroidManifest.xml3
-rw-r--r--packages/FusedLocation/res/values/strings.xml4
-rw-r--r--packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java9
-rw-r--r--packages/FusedLocation/src/com/android/location/gnss/GnssOverlayLocationProvider.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/widgets/GlanceableHubWidgetManagerServiceSupplier.kt4
-rw-r--r--services/core/java/com/android/server/location/LocationManagerService.java10
-rw-r--r--services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java34
13 files changed, 228 insertions, 9 deletions
diff --git a/core/java/com/android/server/servicewatcher/CurrentUserServiceSupplier.java b/core/java/com/android/server/servicewatcher/CurrentUserServiceSupplier.java
index e8aeb8653d06..d8093c4b1f1c 100644
--- a/core/java/com/android/server/servicewatcher/CurrentUserServiceSupplier.java
+++ b/core/java/com/android/server/servicewatcher/CurrentUserServiceSupplier.java
@@ -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();
diff --git a/core/java/com/android/server/servicewatcher/ServiceWatcher.java b/core/java/com/android/server/servicewatcher/ServiceWatcher.java
index 38872c996596..12dad359dd92 100644
--- a/core/java/com/android/server/servicewatcher/ServiceWatcher.java
+++ b/core/java/com/android/server/servicewatcher/ServiceWatcher.java
@@ -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);
}
/**
@@ -230,6 +235,19 @@ public interface ServiceWatcher {
}
/**
+ * 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.
*/
static <TBoundServiceInfo extends BoundServiceInfo> ServiceWatcher create(
@@ -242,6 +260,20 @@ public interface ServiceWatcher {
}
/**
+ * 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}.
*/
diff --git a/core/java/com/android/server/servicewatcher/ServiceWatcherImpl.java b/core/java/com/android/server/servicewatcher/ServiceWatcherImpl.java
index ccbab9fdba12..30d8710a3f12 100644
--- a/core/java/com/android/server/servicewatcher/ServiceWatcherImpl.java
+++ b/core/java/com/android/server/servicewatcher/ServiceWatcherImpl.java
@@ -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
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 7bb799a24ef1..828461c66a1f 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -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. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 2dc5687a1253..219ac3f89997 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -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" />
diff --git a/location/java/android/location/flags/location.aconfig b/location/java/android/location/flags/location.aconfig
index f26e72fa79f1..9cc58ae35692 100644
--- a/location/java/android/location/flags/location.aconfig
+++ b/location/java/android/location/flags/location.aconfig
@@ -205,3 +205,17 @@ flag {
bug: "209078566"
}
+flag {
+ name: "service_watcher_unstable_fallback"
+ namespace: "location"
+ description: "Flag for service watcher to fallback on an unstable service"
+ bug: "402997842"
+ is_fixed_read_only: true
+}
+
+flag {
+ name: "missing_attribution_tags_in_overlay"
+ namespace: "location"
+ description: "Adds missing attribution tags in the Fused and Gnss overlay"
+ bug: "403337028"
+}
diff --git a/packages/FusedLocation/AndroidManifest.xml b/packages/FusedLocation/AndroidManifest.xml
index 158c33ae2035..56fe38905660 100644
--- a/packages/FusedLocation/AndroidManifest.xml
+++ b/packages/FusedLocation/AndroidManifest.xml
@@ -30,6 +30,9 @@
<uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
+ <attribution android:tag="FusedOverlayService" android:label="@string/fused_overlay_service"/>
+ <attribution android:tag="GnssOverlayService" android:label="@string/gnss_overlay_service"/>
+
<application
android:label="@string/app_label"
android:process="system"
diff --git a/packages/FusedLocation/res/values/strings.xml b/packages/FusedLocation/res/values/strings.xml
index 5b78e39d1ba6..25e1fe7677bb 100644
--- a/packages/FusedLocation/res/values/strings.xml
+++ b/packages/FusedLocation/res/values/strings.xml
@@ -2,4 +2,8 @@
<resources>
<!-- Name of the application. [CHAR LIMIT=35] -->
<string name="app_label">Fused Location</string>
+ <!-- Attribution for Fused Overlay Service. [CHAR LIMIT=NONE]-->
+ <string name="fused_overlay_service">Fused Overlay Service</string>
+ <!-- Attribution for GNSS Overlay Service. [CHAR LIMIT=NONE]-->
+ <string name="gnss_overlay_service">GNSS Overlay Service</string>
</resources>
diff --git a/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java b/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java
index a0e008c9437f..78b2f7e52ca5 100644
--- a/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java
+++ b/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java
@@ -53,6 +53,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public class FusedLocationProvider extends LocationProviderBase {
private static final String TAG = "FusedLocationProvider";
+ private static final String ATTRIBUTION_TAG = "FusedOverlayService";
private static final ProviderProperties PROPERTIES = new ProviderProperties.Builder()
.setHasAltitudeSupport(true)
@@ -89,8 +90,12 @@ public class FusedLocationProvider extends LocationProviderBase {
public FusedLocationProvider(Context context) {
super(context, TAG, PROPERTIES);
- mContext = context;
- mLocationManager = Objects.requireNonNull(context.getSystemService(LocationManager.class));
+ if (Flags.missingAttributionTagsInOverlay()) {
+ mContext = context.createAttributionContext(ATTRIBUTION_TAG);
+ } else {
+ mContext = context;
+ }
+ mLocationManager = Objects.requireNonNull(mContext.getSystemService(LocationManager.class));
mGpsListener = new ChildLocationListener(GPS_PROVIDER);
mNetworkListener = new ChildLocationListener(NETWORK_PROVIDER);
diff --git a/packages/FusedLocation/src/com/android/location/gnss/GnssOverlayLocationProvider.java b/packages/FusedLocation/src/com/android/location/gnss/GnssOverlayLocationProvider.java
index c6576e39de99..86bcd99822fc 100644
--- a/packages/FusedLocation/src/com/android/location/gnss/GnssOverlayLocationProvider.java
+++ b/packages/FusedLocation/src/com/android/location/gnss/GnssOverlayLocationProvider.java
@@ -21,6 +21,7 @@ import static android.location.provider.ProviderProperties.POWER_USAGE_HIGH;
import android.annotation.Nullable;
import android.content.Context;
+import android.location.flags.Flags;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
@@ -41,6 +42,7 @@ import java.util.List;
public class GnssOverlayLocationProvider extends LocationProviderBase {
private static final String TAG = "GnssOverlay";
+ private static final String ATTRIBUTION_TAG = "GnssOverlayService";
private static final ProviderProperties PROPERTIES = new ProviderProperties.Builder()
.setHasAltitudeSupport(true)
@@ -87,7 +89,13 @@ public class GnssOverlayLocationProvider extends LocationProviderBase {
public GnssOverlayLocationProvider(Context context) {
super(context, TAG, PROPERTIES);
- mLocationManager = context.getSystemService(LocationManager.class);
+
+ if (Flags.missingAttributionTagsInOverlay()) {
+ Context contextWithAttribution = context.createAttributionContext(ATTRIBUTION_TAG);
+ mLocationManager = contextWithAttribution.getSystemService(LocationManager.class);
+ } else {
+ mLocationManager = context.getSystemService(LocationManager.class);
+ }
}
void start() {
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/GlanceableHubWidgetManagerServiceSupplier.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/GlanceableHubWidgetManagerServiceSupplier.kt
index ed77e6f5d7ea..b86c23bc3e71 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/GlanceableHubWidgetManagerServiceSupplier.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/GlanceableHubWidgetManagerServiceSupplier.kt
@@ -62,6 +62,10 @@ constructor(
userTracker.removeCallback(this)
}
+ override fun alertUnstableService(unstableService: String?) {
+ // Unused. Do nothing.
+ }
+
override fun onBeforeUserSwitching(newUser: Int) {
userAboutToSwitch = true
listener?.onServiceChanged()
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index 6780866d4038..6dff2d8d0a98 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -475,7 +475,8 @@ public class LocationManagerService extends ILocationManager.Stub implements
FUSED_PROVIDER,
ACTION_FUSED_PROVIDER,
com.android.internal.R.bool.config_enableFusedLocationOverlay,
- com.android.internal.R.string.config_fusedLocationProviderPackageName);
+ com.android.internal.R.string.config_fusedLocationProviderPackageName,
+ com.android.internal.R.bool.config_fusedLocationOverlayUnstableFallback);
if (fusedProvider != null) {
LocationProviderManager fusedManager = new LocationProviderManager(mContext, mInjector,
FUSED_PROVIDER, mPassiveManager);
@@ -498,14 +499,13 @@ public class LocationManagerService extends ILocationManager.Stub implements
com.android.internal.R.bool.config_useGnssHardwareProvider);
AbstractLocationProvider gnssProvider = null;
if (!useGnssHardwareProvider) {
- // TODO: Create a separate config_enableGnssLocationOverlay config resource
- // if we want to selectively enable a GNSS overlay but disable a fused overlay.
gnssProvider = ProxyLocationProvider.create(
mContext,
GPS_PROVIDER,
ACTION_GNSS_PROVIDER,
- com.android.internal.R.bool.config_enableFusedLocationOverlay,
- com.android.internal.R.string.config_gnssLocationProviderPackageName);
+ com.android.internal.R.bool.config_enableGnssLocationOverlay,
+ com.android.internal.R.string.config_gnssLocationProviderPackageName,
+ com.android.internal.R.bool.config_gnssLocationOverlayUnstableFallback);
}
if (gnssProvider == null) {
gnssProvider = mGnssManagerService.getGnssLocationProvider();
diff --git a/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java b/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java
index 8fdc22b81769..a52b948dc53f 100644
--- a/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java
+++ b/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java
@@ -77,6 +77,22 @@ public class ProxyLocationProvider extends AbstractLocationProvider implements
}
}
+ /**
+ * Creates and registers this proxy. If no suitable service is available for the proxy, returns
+ * null.
+ */
+ @Nullable
+ public static ProxyLocationProvider create(Context context, String provider, String action,
+ int enableOverlayResId, int nonOverlayPackageResId, int unstableOverlayFallbackResId) {
+ ProxyLocationProvider proxy = new ProxyLocationProvider(context, provider, action,
+ enableOverlayResId, nonOverlayPackageResId, unstableOverlayFallbackResId);
+ if (proxy.checkServiceResolves()) {
+ return proxy;
+ } else {
+ return null;
+ }
+ }
+
final Object mLock = new Object();
final Context mContext;
@@ -111,6 +127,24 @@ public class ProxyLocationProvider extends AbstractLocationProvider implements
mRequest = ProviderRequest.EMPTY_REQUEST;
}
+ private ProxyLocationProvider(Context context, String provider, String action,
+ int enableOverlayResId, int nonOverlayPackageResId, int unstableOverlayFallbackResId) {
+ // safe to use direct executor since our locks are not acquired in a code path invoked by
+ // our owning provider
+ super(DIRECT_EXECUTOR, null, null, Collections.emptySet());
+
+ mContext = context;
+ boolean unstableFallbackEnabled =
+ context.getResources().getBoolean(unstableOverlayFallbackResId);
+ mServiceWatcher = ServiceWatcher.create(context, provider, unstableFallbackEnabled,
+ CurrentUserServiceSupplier.createFromConfig(context, action, enableOverlayResId,
+ nonOverlayPackageResId), this);
+ mName = provider;
+
+ mProxy = null;
+ mRequest = ProviderRequest.EMPTY_REQUEST;
+ }
+
private boolean checkServiceResolves() {
return mServiceWatcher.checkServiceResolves();
}