[CDM] Bypass location setting when scanning for devices

Fixes: 140524365
Test: turn off location in settings and ensure devices still shown in UI
Change-Id: Ifea696c18977fc5e94d93ced4f5d8b916587d0ec
This commit is contained in:
Eugene Susla
2019-07-24 16:30:16 -07:00
parent 0d2e2c2be0
commit 1fa23ed08a
13 changed files with 114 additions and 2 deletions

View File

@@ -2175,6 +2175,7 @@ package android.content.pm {
public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
field public static final int FLAG_REMOVED = 2; // 0x2
field public static final int PROTECTION_FLAG_APP_PREDICTOR = 2097152; // 0x200000
field public static final int PROTECTION_FLAG_COMPANION = 8388608; // 0x800000
field public static final int PROTECTION_FLAG_CONFIGURATOR = 524288; // 0x80000
field public static final int PROTECTION_FLAG_DOCUMENTER = 262144; // 0x40000
field public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 1048576; // 0x100000

View File

@@ -809,6 +809,7 @@ package android.content.pm {
public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
field public static final int FLAG_REMOVED = 2; // 0x2
field public static final int PROTECTION_FLAG_APP_PREDICTOR = 2097152; // 0x200000
field public static final int PROTECTION_FLAG_COMPANION = 8388608; // 0x800000
field public static final int PROTECTION_FLAG_CONFIGURATOR = 524288; // 0x80000
field public static final int PROTECTION_FLAG_DOCUMENTER = 262144; // 0x40000
field public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 1048576; // 0x100000

View File

@@ -248,6 +248,17 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
@TestApi
public static final int PROTECTION_FLAG_TELEPHONY = 0x400000;
/**
* Additional flag for {@link #protectionLevel}, corresponding
* to the <code>companion</code> value of
* {@link android.R.attr#protectionLevel}.
*
* @hide
*/
@SystemApi
@TestApi
public static final int PROTECTION_FLAG_COMPANION = 0x800000;
/** @hide */
@IntDef(flag = true, prefix = { "PROTECTION_FLAG_" }, value = {
PROTECTION_FLAG_PRIVILEGED,
@@ -270,6 +281,7 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
PROTECTION_FLAG_INCIDENT_REPORT_APPROVER,
PROTECTION_FLAG_APP_PREDICTOR,
PROTECTION_FLAG_TELEPHONY,
PROTECTION_FLAG_COMPANION,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ProtectionFlags {}

View File

@@ -135,6 +135,13 @@ public class ArrayUtils {
return (T[]) cache;
}
/**
* Returns the same array or an empty one if it's null.
*/
public static @NonNull <T> T[] emptyIfNull(@Nullable T[] items, Class<T> kind) {
return items != null ? items : emptyArray(kind);
}
/**
* Checks if given array is null or has zero elements.
*/
@@ -751,6 +758,42 @@ public class ArrayUtils {
return result;
}
/**
* Returns an array containing elements from the given one that match the given predicate.
*/
public static @Nullable <T> T[] filter(@Nullable T[] items,
@NonNull IntFunction<T[]> arrayConstructor,
@NonNull java.util.function.Predicate<T> predicate) {
if (isEmpty(items)) {
return items;
}
int matchesCount = 0;
int size = size(items);
for (int i = 0; i < size; i++) {
if (predicate.test(items[i])) {
matchesCount++;
}
}
if (matchesCount == 0) {
return items;
}
if (matchesCount == items.length) {
return items;
}
if (matchesCount == 0) {
return null;
}
T[] result = arrayConstructor.apply(matchesCount);
int outIdx = 0;
for (int i = 0; i < size; i++) {
if (predicate.test(items[i])) {
result[outIdx++] = items[i];
}
}
return result;
}
public static boolean startsWith(byte[] cur, byte[] val) {
if (cur == null || val == null) return false;
if (cur.length < val.length) return false;

View File

@@ -1629,6 +1629,14 @@
<permission android:name="android.permission.NETWORK_SETTINGS"
android:protectionLevel="signature|telephony" />
<!-- Allows holder to request bluetooth/wifi scan bypassing global "use location" setting and
location permissions.
<p>Not for use by third-party or privileged applications.
@hide
-->
<permission android:name="android.permission.RADIO_SCAN_WITHOUT_LOCATION"
android:protectionLevel="signature|companion" />
<!-- Allows SetupWizard to call methods in Networking services
<p>Not for use by any other third-party or privileged applications.
@SystemApi

View File

@@ -298,6 +298,9 @@
<!-- Additional flag from base permission type: this permission can be automatically
granted to the system telephony apps -->
<flag name="telephony" value="0x400000" />
<!-- Additional flag from base permission type: this permission can be automatically
granted to the system companion device manager service -->
<flag name="companion" value="0x800000" />
</attr>
<!-- Flags indicating more context for a permission group. -->

View File

@@ -3572,6 +3572,13 @@
<item>android.ext.services</item>
</string-array>
<!-- The package name for the system companion device manager service.
This service must be trusted, as it can be activated without explicit consent of the user.
Example: "com.android.companiondevicemanager"
See android.companion.CompanionDeviceManager.
-->
<string name="config_companionDeviceManagerPackage" translatable="false"></string>
<!-- The package name for the default wellbeing app.
This package must be trusted, as it has the permissions to control other applications
on the device.

View File

@@ -15,5 +15,6 @@
android_app {
name: "CompanionDeviceManager",
srcs: ["src/**/*.java"],
platform_apis: true,
}

View File

@@ -29,6 +29,7 @@
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.RADIO_SCAN_WITHOUT_LOCATION"/>
<application
android:allowClearUserData="true"

View File

@@ -63,6 +63,9 @@ public abstract class PackageManagerInternal {
public static final int PACKAGE_INCIDENT_REPORT_APPROVER = 10;
public static final int PACKAGE_APP_PREDICTOR = 11;
public static final int PACKAGE_TELEPHONY = 12;
public static final int PACKAGE_WIFI = 13;
public static final int PACKAGE_COMPANION = 14;
@IntDef(value = {
PACKAGE_SYSTEM,
PACKAGE_SETUP_WIZARD,
@@ -77,6 +80,8 @@ public abstract class PackageManagerInternal {
PACKAGE_INCIDENT_REPORT_APPROVER,
PACKAGE_APP_PREDICTOR,
PACKAGE_TELEPHONY,
PACKAGE_WIFI,
PACKAGE_COMPANION,
})
@Retention(RetentionPolicy.SOURCE)
public @interface KnownPackage {}

View File

@@ -96,6 +96,8 @@ import static com.android.internal.annotations.VisibleForTesting.Visibility;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
import static com.android.internal.util.ArrayUtils.emptyIfNull;
import static com.android.internal.util.ArrayUtils.filter;
import static com.android.server.pm.ComponentResolver.RESOLVE_PRIORITY_SORTER;
import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
@@ -249,7 +251,6 @@ import android.os.storage.VolumeInfo;
import android.os.storage.VolumeRecord;
import android.permission.IPermissionManager;
import android.provider.DeviceConfig;
import android.provider.MediaStore;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
import android.security.KeyStore;
@@ -385,6 +386,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
@@ -19261,6 +19263,18 @@ public class PackageManagerService extends IPackageManager.Stub
return ensureSystemPackageName(appPredictionServiceComponentName.getPackageName());
}
private @NonNull String[] dropNonSystemPackages(@NonNull String[] pkgNames) {
return emptyIfNull(filter(pkgNames, String[]::new, mIsSystemPackage), String.class);
}
private Predicate<String> mIsSystemPackage = (pkgName) -> {
if ("android".equals(pkgName)) {
return true;
}
AndroidPackage pkg = mPackages.get(pkgName);
return pkg != null && pkg.isSystem();
};
@Override
public String getSystemCaptionsServicePackageName() {
String flattenedSystemCaptionsServiceComponentName =
@@ -22539,7 +22553,11 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public @NonNull String[] getKnownPackageNames(int knownPackage, int userId) {
switch (knownPackage) {
return dropNonSystemPackages(getKnownPackageNamesInternal(knownPackage, userId));
}
private String[] getKnownPackageNamesInternal(int knownPackage, int userId) {
switch(knownPackage) {
case PackageManagerInternal.PACKAGE_BROWSER:
return new String[]{mPermissionManager.getDefaultBrowser(userId)};
case PackageManagerInternal.PACKAGE_INSTALLER:
@@ -22566,6 +22584,8 @@ public class PackageManagerService extends IPackageManager.Stub
return filterOnlySystemPackages(mAppPredictionServicePackage);
case PackageManagerInternal.PACKAGE_TELEPHONY:
return filterOnlySystemPackages(mTelephonyPackages);
case PackageManagerInternal.PACKAGE_COMPANION:
return filterOnlySystemPackages("com.android.companiondevicemanager");
default:
return ArrayUtils.emptyArray(String.class);
}

View File

@@ -280,6 +280,9 @@ public final class BasePermission {
public boolean isTelephony() {
return (protectionLevel & PermissionInfo.PROTECTION_FLAG_TELEPHONY) != 0;
}
public boolean isCompanion() {
return (protectionLevel & PermissionInfo.PROTECTION_FLAG_COMPANION) != 0;
}
public void transfer(@NonNull String origPackageName, @NonNull String newPackageName) {
if (!origPackageName.equals(sourcePackageName)) {

View File

@@ -3279,6 +3279,13 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// Special permissions for the system telephony apps.
allowed = true;
}
if (!allowed && bp.isCompanion()
&& ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
PackageManagerInternal.PACKAGE_COMPANION, UserHandle.USER_SYSTEM),
pkg.getPackageName())) {
// Special permissions for the system companion device manager.
allowed = true;
}
}
return allowed;
}