Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions core/java/android/provider/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -9055,8 +9055,12 @@ public static boolean putFloatForUser(ContentResolver cr, String name, float val
"location_time_zone_detection_enabled";

/**
* The accuracy in meters used for coarsening location for clients with only the coarse
* location permission.
* The nominal accuracy in meters used to scale the random offset applied before population
* density coarsening.
*
* <p>The provider directly selects the S2 coarsening level. This value can indirectly
* change that level when the offset crosses a population density boundary. The offset's
* standard deviation is one quarter of this value, subject to a minimum scale.
*
* @hide
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,22 @@ public String toString() {
*/
public static CurrentUserServiceSupplier createFromConfig(Context context, String action,
@BoolRes int enableOverlayResId, @StringRes int nonOverlayPackageResId) {
return createFromConfig(context, action, enableOverlayResId, nonOverlayPackageResId,
/* callerPermission= */ null, /* servicePermission= */ null);
}

/**
* Creates an instance using config resources and permission requirements.
*
* @see #create(Context, String, String, String, String)
*/
public static CurrentUserServiceSupplier createFromConfig(Context context, String action,
@BoolRes int enableOverlayResId, @StringRes int nonOverlayPackageResId,
@Nullable String callerPermission, @Nullable String servicePermission) {
String explicitPackage = retrieveExplicitPackage(context, enableOverlayResId,
nonOverlayPackageResId);
return CurrentUserServiceSupplier.create(context, action, explicitPackage,
/*callerPermission=*/null, /*servicePermission=*/null);
callerPermission, servicePermission);
}

/**
Expand Down Expand Up @@ -326,7 +338,7 @@ public BoundServiceInfo getServiceInfo() {
if (mContext.checkPermission(mServicePermission, Process.INVALID_PID,
serviceInfo.mUid) != PERMISSION_GRANTED) {
Log.d(TAG, serviceInfo.getComponentName().flattenToShortString()
+ " disqualified due to not holding " + mCallerPermission);
+ " disqualified due to not holding " + mServicePermission);
continue;
}
}
Expand Down
10 changes: 2 additions & 8 deletions core/res/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2308,14 +2308,8 @@
<permission android:name="android.permission.CONTROL_AUTOMOTIVE_GNSS"
android:protectionLevel="signature|privileged" />

<!-- @SystemApi @hide Allows an application to bind to a
android.service.PopulationDensityProviderService for the purpose of
querying population density. This prevents arbitrary clients connecting
to the service. The system server checks that the provider's intent
service explicitly sets this permission via the android:permission
attribute of the service.
This is only expected to be possessed by the system server outside of
tests.
<!-- @SystemApi @hide Allows the system server to bind to a population density provider.
Provider services must require this permission.
<p>Protection level: signature
-->
<permission android:name="android.permission.BIND_POPULATION_DENSITY_PROVIDER_SERVICE"
Expand Down
13 changes: 5 additions & 8 deletions core/res/res/values/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2274,15 +2274,12 @@
<item>app.grapheneos.networklocation</item>
</string-array>

<!-- Package name providing population density location support. -->
<string name="config_populationDensityProviderPackageName" translatable="false">com.android.location.populationdensity</string>
<!-- Package providing population density location support. -->
<string name="config_populationDensityProviderPackageName" translatable="false">app.grapheneos.networklocation</string>

<!-- Whether to enable population density provider overlay, which allows the population density provider to
be replaced by an app at run-time. When disabled, only the
config_populationDensityProviderPackageName package will be searched for a population density
provider, otherwise any system package is eligible. Anyone who wants to disable the overlay
mechanism can set it to false. -->
<bool name="config_enablePopulationDensityProviderOverlay" translatable="false">true</bool>
<!-- True permits an eligible system package to replace the population density provider.
False searches only the configured package. -->
<bool name="config_enablePopulationDensityProviderOverlay" translatable="false">false</bool>

<!-- Package name of the extension software fallback. -->
<string name="config_extensionFallbackPackageName" translatable="false"></string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.location.eventlog.LocationEventLog;
import com.android.server.location.fudger.LocationFudgerCache;
import com.android.server.location.geofence.GeofenceManager;
import com.android.server.location.geofence.GeofenceProxy;
import com.android.server.location.gnss.GnssConfiguration;
Expand Down Expand Up @@ -266,10 +265,7 @@ void onCurrentUserChanged(int fromUserId, int toUserId) {
private volatile @Nullable GnssManagerService mGnssManagerService = null;
private ProxyGeocodeProvider mGeocodeProvider;

private @Nullable ProxyPopulationDensityProvider mPopulationDensityProvider = null;

// A cache for population density lookups. Used if density-based coarse locations are enabled.
private @Nullable LocationFudgerCache mLocationFudgerCache = null;
private volatile @Nullable ProxyPopulationDensityProvider mPopulationDensityProvider = null;

private final Object mDeprecatedGnssBatchingLock = new Object();
@GuardedBy("mDeprecatedGnssBatchingLock")
Expand Down Expand Up @@ -404,6 +400,13 @@ void addLocationProviderManager(
manager.setRealProvider(realProvider);
}
mProviderManagers.add(manager);

// Managers added after onSystemThirdPartyAppsCanStart has wired the boot-time
// managers must also receive the population density provider; otherwise their
// fudger fails closed and suppresses every coarse fix.
if (mPopulationDensityProvider != null) {
manager.setPopulationDensityProvider(mPopulationDensityProvider);
}
}
}

Expand All @@ -413,10 +416,10 @@ protected void setProxyPopulationDensityProvider(ProxyPopulationDensityProvider
}

@VisibleForTesting
protected void setLocationFudgerCache(LocationFudgerCache cache) {
mLocationFudgerCache = cache;
protected void setPopulationDensityProviderOnFudgers(
@Nullable ProxyPopulationDensityProvider provider) {
for (LocationProviderManager manager : mProviderManagers) {
manager.setLocationFudgerCache(cache);
manager.setPopulationDensityProvider(provider);
}
}

Expand Down Expand Up @@ -575,18 +578,16 @@ void onSystemThirdPartyAppsCanStart() {
}

long startTime = System.currentTimeMillis();
setProxyPopulationDensityProvider(
ProxyPopulationDensityProvider.createAndRegister(mContext));
ProxyPopulationDensityProvider populationDensityProvider =
ProxyPopulationDensityProvider.createAndRegister(mContext);
setProxyPopulationDensityProvider(populationDensityProvider);
int duration = (int) (System.currentTimeMillis() - startTime);
if (mPopulationDensityProvider == null) {
Log.e(TAG, "no population density provider found");
}
// The proxy registers its watcher even when no provider currently resolves (it binds one
// that appears later), so resolution state at boot is diagnostic only.
FrameworkStatsLog.write(FrameworkStatsLog.POPULATION_DENSITY_PROVIDER_LOADING_REPORTED,
/* provider_null= */ (mPopulationDensityProvider == null),
/* provider_null= */ !populationDensityProvider.isServiceResolved(),
/* provider_start_time_millis= */ duration);
if (mPopulationDensityProvider != null) {
setLocationFudgerCache(new LocationFudgerCache(mPopulationDensityProvider));
}
setPopulationDensityProviderOnFudgers(populationDensityProvider);

if (!Flags.disableHardwareAr()) {
// bind to hardware activity recognition
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,13 @@ public void logProviderDeliveredLocations(String provider, int numLocations,
getAggregateStats(provider, identity).markLocationDelivered();
}

/** Logs a suppressed delivery to a client whose location could not be coarsened. */
public void logProviderCoarseningSuppressed(String provider, CallerIdentity identity) {
synchronized (this) {
mLocationsLog.logProviderCoarseningSuppressed(provider, identity);
}
}

/** Logs that a provider has entered or exited stationary throttling. */
public void logProviderStationaryThrottled(String provider, boolean throttled,
ProviderRequest request) {
Expand Down Expand Up @@ -460,6 +467,22 @@ public String toString() {
}
}

private static final class ProviderCoarseningSuppressedEvent extends ProviderEvent {

private final CallerIdentity mIdentity;

ProviderCoarseningSuppressedEvent(String provider, CallerIdentity identity) {
super(provider);
mIdentity = identity;
}

@Override
public String toString() {
return mProvider + " provider delivery suppressed (coarsening failed) for "
+ mIdentity;
}
}

private static final class ProviderStationaryThrottledEvent extends ProviderEvent {

private final boolean mStationaryThrottled;
Expand Down Expand Up @@ -643,6 +666,10 @@ public void logProviderDeliveredLocations(String provider, int numLocations,
addLog(new ProviderDeliverLocationEvent(provider, numLocations, identity));
}

public void logProviderCoarseningSuppressed(String provider, CallerIdentity identity) {
addLog(new ProviderCoarseningSuppressedEvent(provider, identity));
}

private void addLog(Object logEvent) {
this.addLog(SystemClock.elapsedRealtime(), logEvent);
}
Expand Down
Loading