Merge "Update location bypass allowlist" into sc-dev am: 20b934e7db am: 54d0f31169

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14671675

Change-Id: I02e0183b1c3153f81881fa92f68e93f8b906d550
This commit is contained in:
Soonil Nagarkar
2021-05-22 05:01:15 +00:00
committed by Automerger Merge Worker
25 changed files with 814 additions and 206 deletions

View File

@@ -4929,6 +4929,10 @@ package android.location {
field @Deprecated public static final String EXTRA_NO_GPS_LOCATION = "noGPSLocation";
}
public final class LocationDeviceConfig {
field public static final String IGNORE_SETTINGS_ALLOWLIST = "ignore_settings_allowlist";
}
public class LocationManager {
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void addProviderRequestChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.location.provider.ProviderRequest.ChangedListener);
method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void flushGnssBatch();
@@ -9085,6 +9089,7 @@ package android.provider {
field public static final String NAMESPACE_GAME_DRIVER = "game_driver";
field public static final String NAMESPACE_INPUT_NATIVE_BOOT = "input_native_boot";
field public static final String NAMESPACE_INTELLIGENCE_ATTENTION = "intelligence_attention";
field public static final String NAMESPACE_LOCATION = "location";
field public static final String NAMESPACE_MEDIA = "media";
field public static final String NAMESPACE_MEDIA_NATIVE = "media_native";
field public static final String NAMESPACE_NETD_NATIVE = "netd_native";

View File

@@ -1356,9 +1356,14 @@ package android.location {
method public void setType(int);
}
public final class LocationDeviceConfig {
field public static final String IGNORE_SETTINGS_ALLOWLIST = "ignore_settings_allowlist";
}
public class LocationManager {
method @NonNull public String[] getBackgroundThrottlingWhitelist();
method @NonNull public String[] getIgnoreSettingsWhitelist();
method @NonNull public android.os.PackageTagsList getIgnoreSettingsAllowlist();
method @Deprecated @NonNull public String[] getIgnoreSettingsWhitelist();
method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public java.util.List<java.lang.String> getProviderPackages(@NonNull String);
}
@@ -1653,6 +1658,28 @@ package android.os {
method public void removeSyncBarrier(int);
}
public final class PackageTagsList implements android.os.Parcelable {
method public boolean contains(@NonNull String, @Nullable String);
method public boolean contains(@NonNull android.os.PackageTagsList);
method public boolean containsAll(@NonNull String);
method public int describeContents();
method public boolean includes(@NonNull String);
method public boolean isEmpty();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.os.PackageTagsList> CREATOR;
}
public static final class PackageTagsList.Builder {
ctor public PackageTagsList.Builder();
ctor public PackageTagsList.Builder(int);
method @NonNull public android.os.PackageTagsList.Builder add(@NonNull String);
method @NonNull public android.os.PackageTagsList.Builder add(@NonNull String, @Nullable String);
method @NonNull public android.os.PackageTagsList.Builder add(@NonNull android.os.PackageTagsList);
method @NonNull public android.os.PackageTagsList.Builder add(@NonNull java.util.Map<java.lang.String,? extends java.util.Set<java.lang.String>>);
method @NonNull public android.os.PackageTagsList build();
method @NonNull public android.os.PackageTagsList.Builder clear();
}
public final class Parcel {
method public boolean allowSquashing();
method public int readExceptionCode();
@@ -2087,7 +2114,7 @@ package android.provider {
field public static final String HIDDEN_API_BLACKLIST_EXEMPTIONS = "hidden_api_blacklist_exemptions";
field public static final String HIDDEN_API_POLICY = "hidden_api_policy";
field public static final String HIDE_ERROR_DIALOGS = "hide_error_dialogs";
field public static final String LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST = "location_ignore_settings_package_whitelist";
field @Deprecated public static final String LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST = "location_ignore_settings_package_whitelist";
field public static final String LOW_POWER_MODE = "low_power";
field public static final String LOW_POWER_MODE_STICKY = "low_power_sticky";
field @Deprecated public static final String NOTIFICATION_BUBBLES = "notification_bubbles";

View File

@@ -49,6 +49,7 @@ import android.os.HandlerExecutor;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.PackageTagsList;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Process;
@@ -7407,7 +7408,7 @@ public class AppOpsManager {
/** @hide */
public void setUserRestriction(int code, boolean restricted, IBinder token) {
setUserRestriction(code, restricted, token, (Map<String, String[]>) null);
setUserRestriction(code, restricted, token, null);
}
/**
@@ -7415,7 +7416,7 @@ public class AppOpsManager {
* @hide
*/
public void setUserRestriction(int code, boolean restricted, IBinder token,
@Nullable Map<String, String[]> excludedPackageTags) {
@Nullable PackageTagsList excludedPackageTags) {
setUserRestrictionForUser(code, restricted, token, excludedPackageTags,
mContext.getUserId());
}
@@ -7425,7 +7426,7 @@ public class AppOpsManager {
* @hide
*/
public void setUserRestrictionForUser(int code, boolean restricted, IBinder token,
@Nullable Map<String, String[]> excludedPackageTags, int userId) {
@Nullable PackageTagsList excludedPackageTags, int userId) {
try {
mService.setUserRestriction(code, restricted, token, userId, excludedPackageTags);
} catch (RemoteException e) {

View File

@@ -0,0 +1,18 @@
/* Copyright 2018, 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.os;
parcelable PackageTagsList;

View File

@@ -0,0 +1,310 @@
/*
* Copyright (C) 2021 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.os;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.annotation.TestApi;
import android.util.ArrayMap;
import android.util.ArraySet;
import java.io.PrintWriter;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
* A list of packages and associated attribution tags that supports easy membership checks.
*
* @hide
*/
@TestApi
public final class PackageTagsList implements Parcelable {
// an empty set value matches any attribution tag
private final ArrayMap<String, ArraySet<String>> mPackageTags;
private PackageTagsList(@NonNull ArrayMap<String, ArraySet<String>> packageTags) {
mPackageTags = Objects.requireNonNull(packageTags);
}
/**
* Returns true if this instance is empty;
*/
public boolean isEmpty() {
return mPackageTags.isEmpty();
}
/**
* Returns true if the given package is represented within this instance. If this returns true
* this does not imply anything about whether any given attribution tag under the given package
* name is present.
*/
public boolean includes(@NonNull String packageName) {
return mPackageTags.containsKey(packageName);
}
/**
* Returns true if all attribution tags under the given package are contained within this
* instance.
*/
public boolean containsAll(@NonNull String packageName) {
Set<String> tags = mPackageTags.get(packageName);
return tags != null && tags.isEmpty();
}
/**
* Returns true if the given package and attribution tag are contained within this instance.
*/
public boolean contains(@NonNull String packageName, @Nullable String attributionTag) {
Set<String> tags = mPackageTags.get(packageName);
if (tags == null) {
return false;
} else if (tags.isEmpty()) {
return true;
} else {
return tags.contains(attributionTag);
}
}
/**
* Returns true if the given PackageTagsList is a subset of this instance.
*/
public boolean contains(@NonNull PackageTagsList packageTagsList) {
int otherSize = packageTagsList.mPackageTags.size();
if (otherSize > mPackageTags.size()) {
return false;
}
for (int i = 0; i < otherSize; i++) {
String packageName = packageTagsList.mPackageTags.keyAt(i);
ArraySet<String> tags = mPackageTags.get(packageName);
if (tags == null) {
return false;
}
if (tags.isEmpty()) {
continue;
}
ArraySet<String> otherTags = packageTagsList.mPackageTags.valueAt(i);
if (otherTags.isEmpty()) {
return false;
}
if (!tags.containsAll(otherTags)) {
return false;
}
}
return true;
}
public static final @NonNull Parcelable.Creator<PackageTagsList> CREATOR =
new Parcelable.Creator<PackageTagsList>() {
@SuppressWarnings("unchecked")
@Override
public PackageTagsList createFromParcel(Parcel in) {
int count = in.readInt();
ArrayMap<String, ArraySet<String>> packageTags = new ArrayMap<>(count);
for (int i = 0; i < count; i++) {
String key = in.readString8();
ArraySet<String> value = (ArraySet<String>) in.readArraySet(null);
packageTags.append(key, value);
}
return new PackageTagsList(packageTags);
}
@Override
public PackageTagsList[] newArray(int size) {
return new PackageTagsList[size];
}
};
@Override
public void writeToParcel(@NonNull Parcel parcel, int flags) {
int count = mPackageTags.size();
parcel.writeInt(count);
for (int i = 0; i < count; i++) {
parcel.writeString8(mPackageTags.keyAt(i));
parcel.writeArraySet(mPackageTags.valueAt(i));
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof PackageTagsList)) {
return false;
}
PackageTagsList that = (PackageTagsList) o;
return mPackageTags.equals(that.mPackageTags);
}
@Override
public int hashCode() {
return Objects.hash(mPackageTags);
}
@Override
public @NonNull String toString() {
return mPackageTags.toString();
}
/**
* @hide
*/
public void dump(PrintWriter pw) {
int size = mPackageTags.size();
for (int i = 0; i < size; i++) {
String packageName = mPackageTags.keyAt(i);
pw.print(packageName);
pw.print("[");
int tagsSize = mPackageTags.valueAt(i).size();
if (tagsSize == 0) {
pw.print("*");
} else {
for (int j = 0; j < tagsSize; j++) {
String attributionTag = mPackageTags.valueAt(i).valueAt(j);
if (j > 0) {
pw.print(", ");
}
if (attributionTag.startsWith(packageName)) {
pw.print(attributionTag.substring(packageName.length()));
} else {
pw.print(attributionTag);
}
}
}
pw.println("]");
}
}
/**
* Builder class for {@link PackageTagsList}.
*/
public static final class Builder {
private final ArrayMap<String, ArraySet<String>> mPackageTags;
/**
* Creates a new builder.
*/
public Builder() {
mPackageTags = new ArrayMap<>();
}
/**
* Creates a new builder with the given initial capacity.
*/
public Builder(int capacity) {
mPackageTags = new ArrayMap<>(capacity);
}
/**
* Adds all attribution tags under the specified package to the builder.
*/
@SuppressLint("MissingGetterMatchingBuilder")
public @NonNull Builder add(@NonNull String packageName) {
mPackageTags.computeIfAbsent(packageName, p -> new ArraySet<>()).clear();
return this;
}
/**
* Adds the specified package and attribution tag to the builder.
*/
@SuppressLint("MissingGetterMatchingBuilder")
public @NonNull Builder add(@NonNull String packageName, @Nullable String attributionTag) {
ArraySet<String> tags = mPackageTags.get(packageName);
if (tags == null) {
tags = new ArraySet<>(1);
tags.add(attributionTag);
mPackageTags.put(packageName, tags);
} else if (!tags.isEmpty()) {
tags.add(attributionTag);
}
return this;
}
/**
* Adds the specified {@link PackageTagsList} to the builder.
*/
@SuppressLint("MissingGetterMatchingBuilder")
public @NonNull Builder add(@NonNull PackageTagsList packageTagsList) {
return add(packageTagsList.mPackageTags);
}
/**
* Adds the given map of package to attribution tags to the builder. An empty set of
* attribution tags is interpreted to imply all attribution tags under that package.
*/
@SuppressLint("MissingGetterMatchingBuilder")
public @NonNull Builder add(@NonNull Map<String, ? extends Set<String>> packageTagsMap) {
mPackageTags.ensureCapacity(packageTagsMap.size());
for (Map.Entry<String, ? extends Set<String>> entry : packageTagsMap.entrySet()) {
Set<String> newTags = entry.getValue();
if (newTags.isEmpty()) {
add(entry.getKey());
} else {
ArraySet<String> tags = mPackageTags.get(entry.getKey());
if (tags == null) {
tags = new ArraySet<>(newTags);
mPackageTags.put(entry.getKey(), tags);
} else if (!tags.isEmpty()) {
tags.addAll(newTags);
}
}
}
return this;
}
/**
* Clears the builder.
*/
public @NonNull Builder clear() {
mPackageTags.clear();
return this;
}
/**
* Constructs a new {@link PackageTagsList}.
*/
public @NonNull PackageTagsList build() {
return new PackageTagsList(copy(mPackageTags));
}
private static ArrayMap<String, ArraySet<String>> copy(
ArrayMap<String, ArraySet<String>> value) {
int size = value.size();
ArrayMap<String, ArraySet<String>> copy = new ArrayMap<>(size);
for (int i = 0; i < size; i++) {
String packageName = value.keyAt(i);
ArraySet<String> tags = new ArraySet<>(Objects.requireNonNull(value.valueAt(i)));
copy.append(packageName, tags);
}
return copy;
}
}
}

View File

@@ -257,6 +257,14 @@ public final class DeviceConfig {
@TestApi
public static final String NAMESPACE_JOB_SCHEDULER = "jobscheduler";
/**
* Namespace for all location related features.
*
* @hide
*/
@SystemApi
public static final String NAMESPACE_LOCATION = "location";
/**
* Namespace for all media related features.
*

View File

@@ -10988,10 +10988,12 @@ public final class Settings {
/**
* Packages that are whitelisted for ignoring location settings (may retrieve location even
* when user location settings are off), for emergency purposes.
* @deprecated No longer used from Android 12+
* @hide
*/
@TestApi
@Readable
@Deprecated
public static final String LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST =
"location_ignore_settings_package_whitelist";

View File

@@ -23,6 +23,7 @@ import android.app.RuntimeAppOpAccessMessage;
import android.content.AttributionSource;
import android.content.pm.ParceledListSlice;
import android.os.Bundle;
import android.os.PackageTagsList;
import android.os.RemoteCallback;
import com.android.internal.app.IAppOpsCallback;
import com.android.internal.app.IAppOpsActiveCallback;
@@ -92,7 +93,7 @@ interface IAppOpsService {
void setAudioRestriction(int code, int usage, int uid, int mode, in String[] exceptionPackages);
void setUserRestrictions(in Bundle restrictions, IBinder token, int userHandle);
void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle, in Map<String, String[]> excludedPackageTags);
void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle, in PackageTagsList excludedPackageTags);
void removeUser(int userHandle);
void startWatchingActive(in int[] ops, IAppOpsActiveCallback callback);

View File

@@ -169,7 +169,7 @@ public class SystemConfig {
// These are the packages that are white-listed to be able to retrieve location even when user
// location settings are off, for emergency purposes, as read from the configuration files.
final ArraySet<String> mAllowIgnoreLocationSettings = new ArraySet<>();
final ArrayMap<String, ArraySet<String>> mAllowIgnoreLocationSettings = new ArrayMap<>();
// These are the action strings of broadcasts which are whitelisted to
// be delivered anonymously even to apps which target O+.
@@ -313,7 +313,7 @@ public class SystemConfig {
return mAllowUnthrottledLocation;
}
public ArraySet<String> getAllowIgnoreLocationSettings() {
public ArrayMap<String, ArraySet<String>> getAllowIgnoreLocationSettings() {
return mAllowIgnoreLocationSettings;
}
@@ -867,11 +867,25 @@ public class SystemConfig {
case "allow-ignore-location-settings": {
if (allowOverrideAppRestrictions) {
String pkgname = parser.getAttributeValue(null, "package");
String attributionTag = parser.getAttributeValue(null,
"attributionTag");
if (pkgname == null) {
Slog.w(TAG, "<" + name + "> without package in "
+ permFile + " at " + parser.getPositionDescription());
} else {
mAllowIgnoreLocationSettings.add(pkgname);
ArraySet<String> tags = mAllowIgnoreLocationSettings.get(pkgname);
if (tags == null || !tags.isEmpty()) {
if (tags == null) {
tags = new ArraySet<>(1);
mAllowIgnoreLocationSettings.put(pkgname, tags);
}
if (!"*".equals(attributionTag)) {
if ("null".equals(attributionTag)) {
attributionTag = null;
}
tags.add(attributionTag);
}
}
}
} else {
logNotAllowedInPartition(name, permFile, parser);

View File

@@ -0,0 +1,109 @@
/*
* Copyright (C) 2019 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.os;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.platform.test.annotations.Presubmit;
import android.util.ArrayMap;
import android.util.ArraySet;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Arrays;
@Presubmit
@RunWith(AndroidJUnit4.class)
public class PackageTagsListTest {
@Test
public void testPackageTagsList() {
PackageTagsList.Builder builder = new PackageTagsList.Builder()
.add("package1", "attr1")
.add("package1", "attr2")
.add("package2");
PackageTagsList list = builder.build();
assertTrue(list.contains(builder.build()));
assertTrue(list.contains("package1", "attr1"));
assertTrue(list.contains("package1", "attr2"));
assertTrue(list.contains("package2", "attr1"));
assertTrue(list.contains("package2", "attr2"));
assertTrue(list.contains("package2", "attr3"));
assertTrue(list.containsAll("package2"));
assertTrue(list.includes("package1"));
assertTrue(list.includes("package2"));
assertFalse(list.contains("package1", "attr3"));
assertFalse(list.containsAll("package1"));
assertFalse(list.includes("package3"));
PackageTagsList bigList = builder.add("package3").build();
assertTrue(bigList.contains(builder.build()));
assertTrue(bigList.contains(list));
assertFalse(list.contains(bigList));
}
@Test
public void testPackageTagsList_BuildFromMap() {
ArrayMap<String, ArraySet<String>> map = new ArrayMap<>();
map.put("package1", new ArraySet<>(Arrays.asList("attr1", "attr2")));
map.put("package2", new ArraySet<>());
PackageTagsList.Builder builder = new PackageTagsList.Builder().add(map);
PackageTagsList list = builder.build();
assertTrue(list.contains(builder.build()));
assertTrue(list.contains("package1", "attr1"));
assertTrue(list.contains("package1", "attr2"));
assertTrue(list.contains("package2", "attr1"));
assertTrue(list.contains("package2", "attr2"));
assertTrue(list.contains("package2", "attr3"));
assertTrue(list.containsAll("package2"));
assertTrue(list.includes("package1"));
assertTrue(list.includes("package2"));
assertFalse(list.contains("package1", "attr3"));
assertFalse(list.containsAll("package1"));
assertFalse(list.includes("package3"));
map.put("package3", new ArraySet<>());
PackageTagsList bigList = builder.add(map).build();
assertTrue(bigList.contains(builder.build()));
assertTrue(bigList.contains(list));
assertFalse(list.contains(bigList));
}
@Test
public void testWriteToParcel() {
PackageTagsList list = new PackageTagsList.Builder()
.add("package1", "attr1")
.add("package1", "attr2")
.add("package2")
.build();
Parcel parcel = Parcel.obtain();
list.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
PackageTagsList newList = PackageTagsList.CREATOR.createFromParcel(parcel);
parcel.recycle();
assertEquals(list, newList);
}
}

View File

@@ -98,6 +98,7 @@
</xs:complexType>
<xs:complexType name="allow-ignore-location-settings">
<xs:attribute name="package" type="xs:string"/>
<xs:attribute name="attributionTag" type="xs:string"/>
</xs:complexType>
<xs:complexType name="allow-implicit-broadcast">
<xs:attribute name="action" type="xs:string"/>

View File

@@ -11,7 +11,9 @@ package com.android.xml.permission.configfile {
public class AllowIgnoreLocationSettings {
ctor public AllowIgnoreLocationSettings();
method public String getAttributionTag();
method public String get_package();
method public void setAttributionTag(String);
method public void set_package(String);
}

View File

@@ -41,6 +41,7 @@ import android.location.provider.IProviderRequestListener;
import android.location.provider.ProviderProperties;
import android.os.Bundle;
import android.os.ICancellationSignal;
import android.os.PackageTagsList;
/**
* System private API for talking with the location service.
@@ -133,5 +134,5 @@ interface ILocationManager
// used by gts tests to verify whitelists
String[] getBackgroundThrottlingWhitelist();
String[] getIgnoreSettingsWhitelist();
PackageTagsList getIgnoreSettingsAllowlist();
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (C) 2021 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 android.annotation.SystemApi;
import android.annotation.TestApi;
/**
* DeviceConfig keys within the location namespace.
*
* @hide
*/
@SystemApi
@TestApi
public final class LocationDeviceConfig {
/**
* Package/tag combinations that are allowedlisted for ignoring location settings (may retrieve
* location even when user location settings are off, and may ignore throttling, etc), for
* emergency purposes only.
*
* <p>Package/tag combinations are separated by commas (","), and with in each combination is a
* package name followed by 0 or more attribution tags, separated by semicolons (";"). If a
* package is followed by 0 attribution tags, this is interpreted the same as the wildcard
* value. There are two special interpreted values for attribution tags, the wildcard value
* ("*") which represents all attribution tags, and the null value ("null"), which is converted
* to the null string (since attribution tags may be null). This format implies that attribution
* tags which should be on this list may not contain semicolons.
*
* <p>Examples of valid entries:
*
* <ul>
* <li>android</li>
* <li>android;*</li>
* <li>android;*,com.example.app;null;my_attr</li>
* <li>android;*,com.example.app;null;my_attr,com.example.otherapp;my_attr</li>
* </ul>
*/
public static final String IGNORE_SETTINGS_ALLOWLIST = "ignore_settings_allowlist";
private LocationDeviceConfig() {}
}

View File

@@ -58,6 +58,7 @@ import android.os.HandlerExecutor;
import android.os.ICancellationSignal;
import android.os.IRemoteCallback;
import android.os.Looper;
import android.os.PackageTagsList;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -447,12 +448,23 @@ public class LocationManager {
}
/**
* @deprecated Do not use.
* @hide
*/
@Deprecated
@TestApi
public @NonNull String[] getIgnoreSettingsWhitelist() {
return new String[0];
}
/**
* For testing purposes only.
* @hide
*/
@TestApi
public @NonNull String[] getIgnoreSettingsWhitelist() {
public @NonNull PackageTagsList getIgnoreSettingsAllowlist() {
try {
return mService.getIgnoreSettingsWhitelist();
return mService.getIgnoreSettingsAllowlist();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

View File

@@ -896,9 +896,6 @@ class SettingsProtoDumpUtil {
dumpSetting(s, p,
Settings.Global.GNSS_HAL_LOCATION_REQUEST_DURATION_MILLIS,
GlobalSettingsProto.Location.GNSS_HAL_LOCATION_REQUEST_DURATION_MILLIS);
dumpSetting(s, p,
Settings.Global.LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST,
GlobalSettingsProto.Location.IGNORE_SETTINGS_PACKAGE_WHITELIST);
p.end(locationToken);
final long lpmToken = p.start(GlobalSettingsProto.LOW_POWER_MODE);

View File

@@ -321,7 +321,6 @@ public class SettingsBackupTest {
Settings.Global.LOCATION_BACKGROUND_THROTTLE_PROXIMITY_ALERT_INTERVAL_MS,
Settings.Global.LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST,
Settings.Global.LOCATION_ENABLE_STATIONARY_THROTTLE,
Settings.Global.LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST,
Settings.Global.LOCATION_SETTINGS_LINK_TO_PERMISSIONS_ENABLED,
Settings.Global.LOCK_SOUND,
Settings.Global.LOOPER_STATS,

View File

@@ -116,6 +116,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.PackageTagsList;
import android.os.Process;
import android.os.RemoteCallback;
import android.os.RemoteCallbackList;
@@ -132,6 +133,7 @@ import android.provider.Settings;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.IndentingPrintWriter;
import android.util.KeyValueListParser;
import android.util.LongSparseArray;
import android.util.Pair;
@@ -6194,17 +6196,19 @@ public class AppOpsService extends IAppOpsService.Stub {
final int excludedPackageCount = restrictionState.perUserExcludedPackageTags != null
? restrictionState.perUserExcludedPackageTags.size() : 0;
if (excludedPackageCount > 0 && dumpOp < 0) {
IndentingPrintWriter ipw = new IndentingPrintWriter(pw);
ipw.increaseIndent();
boolean printedPackagesHeader = false;
for (int j = 0; j < excludedPackageCount; j++) {
int userId = restrictionState.perUserExcludedPackageTags.keyAt(j);
Map<String, String[]> packageNames =
PackageTagsList packageNames =
restrictionState.perUserExcludedPackageTags.valueAt(j);
if (packageNames == null) {
continue;
}
boolean hasPackage;
if (dumpPackage != null) {
hasPackage = packageNames.containsKey(dumpPackage);
hasPackage = packageNames.includes(dumpPackage);
} else {
hasPackage = true;
}
@@ -6212,32 +6216,29 @@ public class AppOpsService extends IAppOpsService.Stub {
continue;
}
if (!printedTokenHeader) {
pw.println(" User restrictions for token " + token + ":");
ipw.println("User restrictions for token " + token + ":");
printedTokenHeader = true;
}
ipw.increaseIndent();
if (!printedPackagesHeader) {
pw.println(" Excluded packages:");
ipw.println("Excluded packages:");
printedPackagesHeader = true;
}
pw.print(" ");
pw.print("user: ");
pw.print(userId);
pw.println(" packages: ");
for (Map.Entry<String, String[]> entry : packageNames.entrySet()) {
if (entry.getValue() == null) {
continue;
}
pw.print(" ");
pw.print(entry.getKey());
pw.print(": ");
if (entry.getValue().length == 0) {
pw.print("*");
} else {
pw.print(Arrays.toString(entry.getValue()));
}
pw.println();
}
ipw.increaseIndent();
ipw.print("user: ");
ipw.print(userId);
ipw.println(" packages: ");
ipw.increaseIndent();
packageNames.dump(ipw);
ipw.decreaseIndent();
ipw.decreaseIndent();
ipw.decreaseIndent();
}
ipw.decreaseIndent();
}
}
}
@@ -6270,7 +6271,7 @@ public class AppOpsService extends IAppOpsService.Stub {
@Override
public void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle,
Map<String, String[]> excludedPackageTags) {
PackageTagsList excludedPackageTags) {
if (Binder.getCallingPid() != Process.myPid()) {
mContext.enforcePermission(Manifest.permission.MANAGE_APP_OPS_RESTRICTIONS,
Binder.getCallingPid(), Binder.getCallingUid(), null);
@@ -6290,7 +6291,7 @@ public class AppOpsService extends IAppOpsService.Stub {
}
private void setUserRestrictionNoCheck(int code, boolean restricted, IBinder token,
int userHandle, Map<String, String[]> excludedPackageTags) {
int userHandle, PackageTagsList excludedPackageTags) {
synchronized (AppOpsService.this) {
ClientRestrictionState restrictionState = mOpUserRestrictions.get(token);
@@ -6835,7 +6836,7 @@ public class AppOpsService extends IAppOpsService.Stub {
private final class ClientRestrictionState implements DeathRecipient {
private final IBinder token;
SparseArray<boolean[]> perUserRestrictions;
SparseArray<Map<String, String[]>> perUserExcludedPackageTags;
SparseArray<PackageTagsList> perUserExcludedPackageTags;
public ClientRestrictionState(IBinder token)
throws RemoteException {
@@ -6844,7 +6845,7 @@ public class AppOpsService extends IAppOpsService.Stub {
}
public boolean setRestriction(int code, boolean restricted,
Map<String, String[]> excludedPackageTags, int userId) {
PackageTagsList excludedPackageTags, int userId) {
boolean changed = false;
if (perUserRestrictions == null && restricted) {
@@ -6886,7 +6887,8 @@ public class AppOpsService extends IAppOpsService.Stub {
}
if (userRestrictions != null) {
final boolean noExcludedPackages = ArrayUtils.isEmpty(excludedPackageTags);
final boolean noExcludedPackages =
excludedPackageTags == null || excludedPackageTags.isEmpty();
if (perUserExcludedPackageTags == null && !noExcludedPackages) {
perUserExcludedPackageTags = new SparseArray<>();
}
@@ -6897,16 +6899,7 @@ public class AppOpsService extends IAppOpsService.Stub {
perUserExcludedPackageTags = null;
}
} else {
Map<String, String[]> userExcludedPackageTags =
perUserExcludedPackageTags.get(thisUserId);
if (userExcludedPackageTags == null) {
userExcludedPackageTags = new ArrayMap<>(
excludedPackageTags.size());
perUserExcludedPackageTags.put(thisUserId,
userExcludedPackageTags);
}
userExcludedPackageTags.clear();
userExcludedPackageTags.putAll(excludedPackageTags);
perUserExcludedPackageTags.put(thisUserId, excludedPackageTags);
}
changed = true;
}
@@ -6932,19 +6925,11 @@ public class AppOpsService extends IAppOpsService.Stub {
if (perUserExcludedPackageTags == null) {
return true;
}
Map<String, String[]> perUserExclusions = perUserExcludedPackageTags.get(userId);
PackageTagsList perUserExclusions = perUserExcludedPackageTags.get(userId);
if (perUserExclusions == null) {
return true;
}
String[] excludedTags = perUserExclusions.get(packageName);
if (excludedTags == null) {
return true;
}
if (excludedTags.length == 0) {
// all attribution tags within the package are excluded
return false;
}
return !ArrayUtils.contains(excludedTags, attributionTag);
return !perUserExclusions.contains(packageName, attributionTag);
}
public void removeUser(int userId) {

View File

@@ -76,6 +76,7 @@ import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.ICancellationSignal;
import android.os.PackageTagsList;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
@@ -139,7 +140,6 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -271,7 +271,7 @@ public class LocationManagerService extends ILocationManager.Stub implements
mInjector.getSettingsHelper().addOnLocationEnabledChangedListener(
this::onLocationModeChanged);
mInjector.getSettingsHelper().addOnIgnoreSettingsPackageWhitelistChangedListener(
mInjector.getSettingsHelper().addIgnoreSettingsAllowlistChangedListener(
() -> refreshAppOpsRestrictions(UserHandle.USER_ALL));
mInjector.getUserInfoHelper().addListener((userId, change) -> {
if (change == UserInfoHelper.UserListener.USER_STARTED) {
@@ -641,9 +641,8 @@ public class LocationManagerService extends ILocationManager.Stub implements
}
@Override
public String[] getIgnoreSettingsWhitelist() {
return mInjector.getSettingsHelper().getIgnoreSettingsPackageWhitelist().toArray(
new String[0]);
public PackageTagsList getIgnoreSettingsAllowlist() {
return mInjector.getSettingsHelper().getIgnoreSettingsAllowlist();
}
@Nullable
@@ -1408,26 +1407,17 @@ public class LocationManagerService extends ILocationManager.Stub implements
boolean enabled = mInjector.getSettingsHelper().isLocationEnabled(userId);
ArrayMap<String, String[]> allowedPackages = null;
PackageTagsList allowedPackages = null;
if (!enabled) {
ArrayMap<String, ArraySet<String>> packages = new ArrayMap<>();
PackageTagsList.Builder builder = new PackageTagsList.Builder();
for (LocationProviderManager manager : mProviderManagers) {
CallerIdentity identity = manager.getIdentity();
if (identity != null) {
packages.computeIfAbsent(identity.getPackageName(), k -> new ArraySet<>()).add(
identity.getAttributionTag());
builder.add(identity.getPackageName(), identity.getAttributionTag());
}
}
for (String packageName :
mInjector.getSettingsHelper().getIgnoreSettingsPackageWhitelist()) {
packages.computeIfAbsent(packageName, k -> new ArraySet<>()).clear();
}
packages.computeIfAbsent(mContext.getPackageName(), k -> new ArraySet<>()).clear();
allowedPackages = new ArrayMap<>();
for (Map.Entry<String, ArraySet<String>> entry : packages.entrySet()) {
allowedPackages.put(entry.getKey(), entry.getValue().toArray(new String[0]));
}
builder.add(mInjector.getSettingsHelper().getIgnoreSettingsAllowlist());
allowedPackages = builder.build();
}
AppOpsManager appOpsManager = Objects.requireNonNull(

View File

@@ -16,6 +16,7 @@
package com.android.server.location.injector;
import android.os.PackageTagsList;
import android.util.IndentingPrintWriter;
import java.io.FileDescriptor;
@@ -146,21 +147,21 @@ public abstract class SettingsHelper {
GlobalSettingChangedListener listener);
/**
* Retrieve the ignore settings package whitelist.
* Retrieve the ignore location settings package+tags allowlist setting.
*/
public abstract Set<String> getIgnoreSettingsPackageWhitelist();
public abstract PackageTagsList getIgnoreSettingsAllowlist();
/**
* Add a listener for changes to the ignore settings package whitelist. Callbacks occur on an
* unspecified thread.
*/
public abstract void addOnIgnoreSettingsPackageWhitelistChangedListener(
public abstract void addIgnoreSettingsAllowlistChangedListener(
GlobalSettingChangedListener listener);
/**
* Remove a listener for changes to the ignore settings package whitelist.
*/
public abstract void removeOnIgnoreSettingsPackageWhitelistChangedListener(
public abstract void removeIgnoreSettingsAllowlistChangedListener(
GlobalSettingChangedListener listener);
/**

View File

@@ -16,11 +16,11 @@
package com.android.server.location.injector;
import static android.location.LocationDeviceConfig.IGNORE_SETTINGS_ALLOWLIST;
import static android.provider.Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING;
import static android.provider.Settings.Global.LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS;
import static android.provider.Settings.Global.LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST;
import static android.provider.Settings.Global.LOCATION_BACKGROUND_THROTTLE_PROXIMITY_ALERT_INTERVAL_MS;
import static android.provider.Settings.Global.LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST;
import static android.provider.Settings.Secure.LOCATION_COARSE_ACCURACY_M;
import static android.provider.Settings.Secure.LOCATION_MODE;
import static android.provider.Settings.Secure.LOCATION_MODE_OFF;
@@ -35,10 +35,13 @@ import android.database.ContentObserver;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
import android.os.PackageTagsList;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import android.util.Log;
@@ -77,7 +80,7 @@ public class SystemSettingsHelper extends SettingsHelper {
private final StringListCachedSecureSetting mLocationPackageBlacklist;
private final StringListCachedSecureSetting mLocationPackageWhitelist;
private final StringSetCachedGlobalSetting mBackgroundThrottlePackageWhitelist;
private final StringSetCachedGlobalSetting mIgnoreSettingsPackageWhitelist;
private final PackageTagsListSetting mIgnoreSettingsPackageAllowlist;
public SystemSettingsHelper(Context context) {
mContext = context;
@@ -95,10 +98,9 @@ public class SystemSettingsHelper extends SettingsHelper {
LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST,
() -> SystemConfig.getInstance().getAllowUnthrottledLocation(),
FgThread.getHandler());
mIgnoreSettingsPackageWhitelist = new StringSetCachedGlobalSetting(context,
LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST,
() -> SystemConfig.getInstance().getAllowIgnoreLocationSettings(),
FgThread.getHandler());
mIgnoreSettingsPackageAllowlist = new PackageTagsListSetting(
IGNORE_SETTINGS_ALLOWLIST,
() -> SystemConfig.getInstance().getAllowIgnoreLocationSettings());
}
/** Called when system is ready. */
@@ -108,20 +110,14 @@ public class SystemSettingsHelper extends SettingsHelper {
mLocationPackageBlacklist.register();
mLocationPackageWhitelist.register();
mBackgroundThrottlePackageWhitelist.register();
mIgnoreSettingsPackageWhitelist.register();
mIgnoreSettingsPackageAllowlist.register();
}
/**
* Retrieve if location is enabled or not.
*/
@Override
public boolean isLocationEnabled(int userId) {
return mLocationMode.getValueForUser(LOCATION_MODE_OFF, userId) != LOCATION_MODE_OFF;
}
/**
* Set location enabled for a user.
*/
@Override
public void setLocationEnabled(boolean enabled, int userId) {
final long identity = Binder.clearCallingIdentity();
@@ -138,53 +134,33 @@ public class SystemSettingsHelper extends SettingsHelper {
}
}
/**
* Add a listener for changes to the location enabled setting. Callbacks occur on an unspecified
* thread.
*/
@Override
public void addOnLocationEnabledChangedListener(UserSettingChangedListener listener) {
mLocationMode.addListener(listener);
}
/**
* Remove a listener for changes to the location enabled setting.
*/
@Override
public void removeOnLocationEnabledChangedListener(UserSettingChangedListener listener) {
mLocationMode.removeListener(listener);
}
/**
* Retrieve the background throttle interval.
*/
@Override
public long getBackgroundThrottleIntervalMs() {
return mBackgroundThrottleIntervalMs.getValue(DEFAULT_BACKGROUND_THROTTLE_INTERVAL_MS);
}
/**
* Add a listener for changes to the background throttle interval. Callbacks occur on an
* unspecified thread.
*/
@Override
public void addOnBackgroundThrottleIntervalChangedListener(
GlobalSettingChangedListener listener) {
mBackgroundThrottleIntervalMs.addListener(listener);
}
/**
* Remove a listener for changes to the background throttle interval.
*/
@Override
public void removeOnBackgroundThrottleIntervalChangedListener(
GlobalSettingChangedListener listener) {
mBackgroundThrottleIntervalMs.removeListener(listener);
}
/**
* Check if the given package is blacklisted for location access.
*/
@Override
public boolean isLocationPackageBlacklisted(int userId, String packageName) {
List<String> locationPackageBlacklist = mLocationPackageBlacklist.getValueForUser(userId);
@@ -208,10 +184,6 @@ public class SystemSettingsHelper extends SettingsHelper {
return false;
}
/**
* Add a listener for changes to the location package blacklist. Callbacks occur on an
* unspecified thread.
*/
@Override
public void addOnLocationPackageBlacklistChangedListener(
UserSettingChangedListener listener) {
@@ -219,9 +191,6 @@ public class SystemSettingsHelper extends SettingsHelper {
mLocationPackageWhitelist.addListener(listener);
}
/**
* Remove a listener for changes to the location package blacklist.
*/
@Override
public void removeOnLocationPackageBlacklistChangedListener(
UserSettingChangedListener listener) {
@@ -229,90 +198,57 @@ public class SystemSettingsHelper extends SettingsHelper {
mLocationPackageWhitelist.removeListener(listener);
}
/**
* Retrieve the background throttle package whitelist.
*/
@Override
public Set<String> getBackgroundThrottlePackageWhitelist() {
return mBackgroundThrottlePackageWhitelist.getValue();
}
/**
* Add a listener for changes to the background throttle package whitelist. Callbacks occur on
* an unspecified thread.
*/
@Override
public void addOnBackgroundThrottlePackageWhitelistChangedListener(
GlobalSettingChangedListener listener) {
mBackgroundThrottlePackageWhitelist.addListener(listener);
}
/**
* Remove a listener for changes to the background throttle package whitelist.
*/
@Override
public void removeOnBackgroundThrottlePackageWhitelistChangedListener(
GlobalSettingChangedListener listener) {
mBackgroundThrottlePackageWhitelist.removeListener(listener);
}
/**
* Retrieve the gnss measurements full tracking enabled setting.
*/
@Override
public boolean isGnssMeasurementsFullTrackingEnabled() {
return mGnssMeasurementFullTracking.getValue(false);
}
/**
* Add a listener for changes to the background throttle package whitelist. Callbacks occur on
* an unspecified thread.
*/
@Override
public void addOnGnssMeasurementsFullTrackingEnabledChangedListener(
GlobalSettingChangedListener listener) {
mGnssMeasurementFullTracking.addListener(listener);
}
/**
* Remove a listener for changes to the background throttle package whitelist.
*/
@Override
public void removeOnGnssMeasurementsFullTrackingEnabledChangedListener(
GlobalSettingChangedListener listener) {
mGnssMeasurementFullTracking.removeListener(listener);
}
/**
* Retrieve the ignore settings package whitelist.
*/
@Override
public Set<String> getIgnoreSettingsPackageWhitelist() {
return mIgnoreSettingsPackageWhitelist.getValue();
public PackageTagsList getIgnoreSettingsAllowlist() {
return mIgnoreSettingsPackageAllowlist.getValue();
}
/**
* Add a listener for changes to the ignore settings package whitelist. Callbacks occur on an
* unspecified thread.
*/
@Override
public void addOnIgnoreSettingsPackageWhitelistChangedListener(
public void addIgnoreSettingsAllowlistChangedListener(
GlobalSettingChangedListener listener) {
mIgnoreSettingsPackageWhitelist.addListener(listener);
mIgnoreSettingsPackageAllowlist.addListener(listener);
}
/**
* Remove a listener for changes to the ignore settings package whitelist.
*/
@Override
public void removeOnIgnoreSettingsPackageWhitelistChangedListener(
public void removeIgnoreSettingsAllowlistChangedListener(
GlobalSettingChangedListener listener) {
mIgnoreSettingsPackageWhitelist.removeListener(listener);
mIgnoreSettingsPackageAllowlist.removeListener(listener);
}
/**
* Retrieve the background throttling proximity alert interval.
*/
@Override
public long getBackgroundThrottleProximityAlertIntervalMs() {
final long identity = Binder.clearCallingIdentity();
@@ -325,10 +261,6 @@ public class SystemSettingsHelper extends SettingsHelper {
}
}
/**
* Retrieve the accuracy for coarsening location, ie, the grid size used for snap-to-grid
* coarsening.
*/
@Override
public float getCoarseLocationAccuracyM() {
final long identity = Binder.clearCallingIdentity();
@@ -344,9 +276,6 @@ public class SystemSettingsHelper extends SettingsHelper {
}
}
/**
* Dump info for debugging.
*/
@Override
public void dump(FileDescriptor fd, IndentingPrintWriter ipw, String[] args) {
int[] userIds;
@@ -428,13 +357,11 @@ public class SystemSettingsHelper extends SettingsHelper {
ipw.decreaseIndent();
}
Set<String> ignoreSettingsPackageWhitelist = mIgnoreSettingsPackageWhitelist.getValue();
if (!ignoreSettingsPackageWhitelist.isEmpty()) {
PackageTagsList ignoreSettingsAllowlist = mIgnoreSettingsPackageAllowlist.getValue();
if (!ignoreSettingsAllowlist.isEmpty()) {
ipw.println("Bypass Allow Packages:");
ipw.increaseIndent();
for (String packageName : ignoreSettingsPackageWhitelist) {
ipw.println(packageName);
}
ignoreSettingsAllowlist.dump(ipw);
ipw.decreaseIndent();
}
}
@@ -687,4 +614,139 @@ public class SystemSettingsHelper extends SettingsHelper {
super.onChange(selfChange, uri, userId);
}
}
private static class DeviceConfigSetting implements DeviceConfig.OnPropertiesChangedListener {
protected final String mName;
private final CopyOnWriteArrayList<GlobalSettingChangedListener> mListeners;
@GuardedBy("this")
private boolean mRegistered;
DeviceConfigSetting(String name) {
mName = name;
mListeners = new CopyOnWriteArrayList<>();
}
protected synchronized boolean isRegistered() {
return mRegistered;
}
protected synchronized void register() {
if (mRegistered) {
return;
}
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_LOCATION,
FgThread.getExecutor(), this);
mRegistered = true;
}
public void addListener(GlobalSettingChangedListener listener) {
mListeners.add(listener);
}
public void removeListener(GlobalSettingChangedListener listener) {
mListeners.remove(listener);
}
@Override
public final void onPropertiesChanged(DeviceConfig.Properties properties) {
if (!properties.getKeyset().contains(mName)) {
return;
}
onPropertiesChanged();
}
public void onPropertiesChanged() {
if (D) {
Log.d(TAG, "location device config setting changed: " + mName);
}
for (UserSettingChangedListener listener : mListeners) {
listener.onSettingChanged(UserHandle.USER_ALL);
}
}
}
private static class PackageTagsListSetting extends DeviceConfigSetting {
private final Supplier<ArrayMap<String, ArraySet<String>>> mBaseValuesSupplier;
@GuardedBy("this")
private boolean mValid;
@GuardedBy("this")
private PackageTagsList mCachedValue;
PackageTagsListSetting(String name,
Supplier<ArrayMap<String, ArraySet<String>>> baseValuesSupplier) {
super(name);
mBaseValuesSupplier = baseValuesSupplier;
}
public synchronized PackageTagsList getValue() {
PackageTagsList value = mCachedValue;
if (!mValid) {
final long identity = Binder.clearCallingIdentity();
try {
PackageTagsList.Builder builder = new PackageTagsList.Builder().add(
mBaseValuesSupplier.get());
String setting = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_LOCATION,
mName);
if (!TextUtils.isEmpty(setting)) {
for (String packageAndTags : setting.split(",")) {
if (TextUtils.isEmpty(packageAndTags)) {
continue;
}
String[] packageThenTags = packageAndTags.split(";");
String packageName = packageThenTags[0];
if (packageThenTags.length == 1) {
builder.add(packageName);
} else {
for (int i = 1; i < packageThenTags.length; i++) {
String attributionTag = packageThenTags[i];
if ("null".equals(attributionTag)) {
attributionTag = null;
}
if ("*".equals(attributionTag)) {
builder.add(packageName);
} else {
builder.add(packageName, attributionTag);
}
}
}
}
}
value = builder.build();
} finally {
Binder.restoreCallingIdentity(identity);
}
if (isRegistered()) {
mValid = true;
mCachedValue = value;
}
}
return value;
}
public synchronized void invalidate() {
mValid = false;
mCachedValue = null;
}
@Override
public void onPropertiesChanged() {
invalidate();
super.onPropertiesChanged();
}
}
}

View File

@@ -613,9 +613,9 @@ public class LocationProviderManager extends
boolean locationSettingsIgnored = baseRequest.isLocationSettingsIgnored();
if (locationSettingsIgnored) {
// if we are not currently allowed use location settings ignored, disable it
if (!mSettingsHelper.getIgnoreSettingsPackageWhitelist().contains(
getIdentity().getPackageName()) && !mLocationManagerInternal.isProvider(
null, getIdentity())) {
if (!mSettingsHelper.getIgnoreSettingsAllowlist().contains(
getIdentity().getPackageName(), getIdentity().getAttributionTag())
&& !mLocationManagerInternal.isProvider(null, getIdentity())) {
builder.setLocationSettingsIgnored(false);
locationSettingsIgnored = false;
}
@@ -1820,7 +1820,7 @@ public class LocationProviderManager extends
mBackgroundThrottlePackageWhitelistChangedListener);
mSettingsHelper.addOnLocationPackageBlacklistChangedListener(
mLocationPackageBlacklistChangedListener);
mSettingsHelper.addOnIgnoreSettingsPackageWhitelistChangedListener(
mSettingsHelper.addIgnoreSettingsAllowlistChangedListener(
mIgnoreSettingsPackageWhitelistChangedListener);
mLocationPermissionsHelper.addListener(mLocationPermissionsListener);
mAppForegroundHelper.addListener(mAppForegroundChangedListener);
@@ -1841,7 +1841,7 @@ public class LocationProviderManager extends
mBackgroundThrottlePackageWhitelistChangedListener);
mSettingsHelper.removeOnLocationPackageBlacklistChangedListener(
mLocationPackageBlacklistChangedListener);
mSettingsHelper.removeOnIgnoreSettingsPackageWhitelistChangedListener(
mSettingsHelper.removeIgnoreSettingsAllowlistChangedListener(
mIgnoreSettingsPackageWhitelistChangedListener);
mLocationPermissionsHelper.removeListener(mLocationPermissionsListener);
mAppForegroundHelper.removeListener(mAppForegroundChangedListener);

View File

@@ -42,6 +42,7 @@ import android.os.IBinder;
import android.os.IInterface;
import android.os.Looper;
import android.os.Message;
import android.os.PackageTagsList;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -85,7 +86,6 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
@@ -856,14 +856,13 @@ public class VrManagerService extends SystemService
// If user changed drop restrictions for the old user.
if (oldUserId != newUserId) {
appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
false, mOverlayToken, (Map<String, String[]>) null, oldUserId);
false, mOverlayToken, null, oldUserId);
}
// Apply the restrictions for the current user based on vr state
ArrayMap<String, String[]> exemptions = null;
PackageTagsList exemptions = null;
if (exemptedPackage != null) {
exemptions = new ArrayMap<>(1);
exemptions.put(exemptedPackage, new String[0]);
exemptions = new PackageTagsList.Builder(1).add(exemptedPackage).build();
}
appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,

View File

@@ -16,6 +16,7 @@
package com.android.server.location.injector;
import android.os.PackageTagsList;
import android.os.UserHandle;
import android.util.IndentingPrintWriter;
import android.util.SparseArray;
@@ -40,7 +41,7 @@ public class FakeSettingsHelper extends SettingsHelper {
private final CopyOnWriteArrayList<UserSettingChangedListener> mListeners;
private Setting(Object defaultValue) {
Setting(Object defaultValue) {
mValues = new SparseArray<>();
mDefaultValue = defaultValue;
mListeners = new CopyOnWriteArrayList<>();
@@ -83,7 +84,8 @@ public class FakeSettingsHelper extends SettingsHelper {
private final Setting mBackgroundThrottlePackageWhitelistSetting = new Setting(
Collections.emptySet());
private final Setting mGnssMeasurementsFullTrackingSetting = new Setting(Boolean.FALSE);
private final Setting mIgnoreSettingsPackageWhitelist = new Setting(Collections.emptySet());
private final Setting mIgnoreSettingsAllowlist = new Setting(
new PackageTagsList.Builder().build());
private final Setting mBackgroundThrottleProximityAlertIntervalSetting = new Setting(
30 * 60 * 1000L);
private final Setting mCoarseLocationAccuracySetting = new Setting(2000.0f);
@@ -192,24 +194,24 @@ public class FakeSettingsHelper extends SettingsHelper {
}
@Override
public Set<String> getIgnoreSettingsPackageWhitelist() {
return mIgnoreSettingsPackageWhitelist.getValue(Set.class);
public PackageTagsList getIgnoreSettingsAllowlist() {
return mIgnoreSettingsAllowlist.getValue(PackageTagsList.class);
}
public void setIgnoreSettingsPackageWhitelist(Set<String> newValue) {
mIgnoreSettingsPackageWhitelist.setValue(newValue);
public void setIgnoreSettingsAllowlist(PackageTagsList newValue) {
mIgnoreSettingsAllowlist.setValue(newValue);
}
@Override
public void addOnIgnoreSettingsPackageWhitelistChangedListener(
public void addIgnoreSettingsAllowlistChangedListener(
GlobalSettingChangedListener listener) {
mIgnoreSettingsPackageWhitelist.addListener(listener);
mIgnoreSettingsAllowlist.addListener(listener);
}
@Override
public void removeOnIgnoreSettingsPackageWhitelistChangedListener(
public void removeIgnoreSettingsAllowlistChangedListener(
GlobalSettingChangedListener listener) {
mIgnoreSettingsPackageWhitelist.removeListener(listener);
mIgnoreSettingsAllowlist.removeListener(listener);
}
@Override

View File

@@ -71,6 +71,7 @@ import android.location.util.identity.CallerIdentity;
import android.os.Bundle;
import android.os.ICancellationSignal;
import android.os.IRemoteCallback;
import android.os.PackageTagsList;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
@@ -923,8 +924,9 @@ public class LocationProviderManagerTest {
@Test
public void testProviderRequest_IgnoreLocationSettings() {
mInjector.getSettingsHelper().setIgnoreSettingsPackageWhitelist(
Collections.singleton(IDENTITY.getPackageName()));
mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
new PackageTagsList.Builder().add(
IDENTITY.getPackageName()).build());
ILocationListener listener1 = createMockLocationListener();
LocationRequest request1 = new LocationRequest.Builder(5)
@@ -950,8 +952,9 @@ public class LocationProviderManagerTest {
@Test
public void testProviderRequest_IgnoreLocationSettings_ProviderDisabled() {
mInjector.getSettingsHelper().setIgnoreSettingsPackageWhitelist(
Collections.singleton(IDENTITY.getPackageName()));
mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
new PackageTagsList.Builder().add(
IDENTITY.getPackageName()).build());
ILocationListener listener1 = createMockLocationListener();
LocationRequest request1 = new LocationRequest.Builder(1)
@@ -975,8 +978,9 @@ public class LocationProviderManagerTest {
@Test
public void testProviderRequest_IgnoreLocationSettings_NoAllowlist() {
mInjector.getSettingsHelper().setIgnoreSettingsPackageWhitelist(
Collections.singleton(IDENTITY.getPackageName()));
mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
new PackageTagsList.Builder().add(
IDENTITY.getPackageName()).build());
ILocationListener listener = createMockLocationListener();
LocationRequest request = new LocationRequest.Builder(1)
@@ -985,7 +989,8 @@ public class LocationProviderManagerTest {
.build();
mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
mInjector.getSettingsHelper().setIgnoreSettingsPackageWhitelist(Collections.emptySet());
mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
new PackageTagsList.Builder().build());
assertThat(mProvider.getRequest().isActive()).isTrue();
assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1);
@@ -994,8 +999,9 @@ public class LocationProviderManagerTest {
@Test
public void testProviderRequest_BackgroundThrottle_IgnoreLocationSettings() {
mInjector.getSettingsHelper().setIgnoreSettingsPackageWhitelist(
Collections.singleton(IDENTITY.getPackageName()));
mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
new PackageTagsList.Builder().add(
IDENTITY.getPackageName()).build());
ILocationListener listener1 = createMockLocationListener();
LocationRequest request1 = new LocationRequest.Builder(5)