Merge "Refactor PermissionManager.SPLIT_PERMISSIONS" into qt-qpr1-dev
am: fcb2ce1503
Change-Id: I830c2580f3d141a3641e023c189c148a0a1737d0
This commit is contained in:
@@ -44,6 +44,7 @@ import android.content.pm.PermissionGroupInfo;
|
||||
import android.content.pm.PermissionInfo;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.content.pm.permission.SplitPermissionInfoParcelable;
|
||||
import android.content.pm.SuspendDialogInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.pm.VerifierDeviceIdentity;
|
||||
@@ -772,4 +773,6 @@ interface IPackageManager {
|
||||
void setRuntimePermissionsVersion(int version, int userId);
|
||||
|
||||
void notifyPackagesReplacedReceived(in String[] packages);
|
||||
|
||||
List<SplitPermissionInfoParcelable> getSplitPermissions();
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageParserCacheHelper.ReadHelper;
|
||||
import android.content.pm.PackageParserCacheHelper.WriteHelper;
|
||||
import android.content.pm.permission.SplitPermissionInfoParcelable;
|
||||
import android.content.pm.split.DefaultSplitAssetLoader;
|
||||
import android.content.pm.split.SplitAssetDependencyLoader;
|
||||
import android.content.pm.split.SplitAssetLoader;
|
||||
@@ -103,6 +104,7 @@ import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.os.ClassLoaderFactory;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.internal.util.XmlUtils;
|
||||
import com.android.server.SystemConfig;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
import libcore.util.EmptyArray;
|
||||
@@ -2482,11 +2484,10 @@ public class PackageParser {
|
||||
Slog.i(TAG, newPermsMsg.toString());
|
||||
}
|
||||
|
||||
|
||||
final int NS = PermissionManager.SPLIT_PERMISSIONS.size();
|
||||
for (int is=0; is<NS; is++) {
|
||||
final PermissionManager.SplitPermissionInfo spi =
|
||||
PermissionManager.SPLIT_PERMISSIONS.get(is);
|
||||
List<SplitPermissionInfoParcelable> splitPermissions = getSplitPermissions();
|
||||
final int listSize = splitPermissions.size();
|
||||
for (int is = 0; is < listSize; is++) {
|
||||
final SplitPermissionInfoParcelable spi = splitPermissions.get(is);
|
||||
if (pkg.applicationInfo.targetSdkVersion >= spi.getTargetSdk()
|
||||
|| !pkg.requestedPermissions.contains(spi.getSplitPermission())) {
|
||||
continue;
|
||||
@@ -2540,6 +2541,23 @@ public class PackageParser {
|
||||
return pkg;
|
||||
}
|
||||
|
||||
private List<SplitPermissionInfoParcelable> getSplitPermissions() {
|
||||
// PackageManager runs this code during initialization prior to registering with
|
||||
// ServiceManager, so we can't use the PackageManager API. Instead, just read from
|
||||
// SystemConfig directly when in any SystemProcess and only use PackageManager when not in
|
||||
// one.
|
||||
if (ActivityThread.isSystem()) {
|
||||
return PermissionManager.splitPermissionInfoListToParcelableList(
|
||||
SystemConfig.getInstance().getSplitPermissions());
|
||||
} else {
|
||||
try {
|
||||
return ActivityThread.getPackageManager().getSplitPermissions();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkOverlayRequiredSystemProperty(String propName, String propValue) {
|
||||
|
||||
if (TextUtils.isEmpty(propName) || TextUtils.isEmpty(propValue)) {
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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.content.pm.permission;
|
||||
|
||||
parcelable SplitPermissionInfoParcelable;
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* 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.content.pm.permission;
|
||||
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Parcelable version of {@link android.permission.PermissionManager.SplitPermissionInfo}
|
||||
* @hide
|
||||
*/
|
||||
public class SplitPermissionInfoParcelable implements Parcelable {
|
||||
|
||||
/**
|
||||
* The permission that is split.
|
||||
*/
|
||||
@NonNull
|
||||
private final String mSplitPermission;
|
||||
|
||||
/**
|
||||
* The permissions that are added.
|
||||
*/
|
||||
@NonNull
|
||||
private final List<String> mNewPermissions;
|
||||
|
||||
/**
|
||||
* The target API level when the permission was split.
|
||||
*/
|
||||
@IntRange(from = 0)
|
||||
private final int mTargetSdk;
|
||||
|
||||
private void onConstructed() {
|
||||
Preconditions.checkCollectionElementsNotNull(mNewPermissions, "newPermissions");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Code below generated by codegen v1.0.0.
|
||||
//
|
||||
// DO NOT MODIFY!
|
||||
//
|
||||
// To regenerate run:
|
||||
// $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/SplitPermissionInfoParcelable.java
|
||||
//
|
||||
// CHECKSTYLE:OFF Generated code
|
||||
|
||||
/**
|
||||
* Creates a new SplitPermissionInfoParcelable.
|
||||
*
|
||||
* @param splitPermission
|
||||
* The permission that is split.
|
||||
* @param newPermissions
|
||||
* The permissions that are added.
|
||||
* @param targetSdk
|
||||
* The target API level when the permission was split.
|
||||
*/
|
||||
public SplitPermissionInfoParcelable(
|
||||
@NonNull String splitPermission,
|
||||
@NonNull List<String> newPermissions,
|
||||
@IntRange(from = 0) int targetSdk) {
|
||||
this.mSplitPermission = splitPermission;
|
||||
Preconditions.checkNotNull(mSplitPermission);
|
||||
this.mNewPermissions = newPermissions;
|
||||
Preconditions.checkNotNull(mNewPermissions);
|
||||
this.mTargetSdk = targetSdk;
|
||||
Preconditions.checkArgumentNonnegative(mTargetSdk);
|
||||
|
||||
onConstructed();
|
||||
}
|
||||
|
||||
/**
|
||||
* The permission that is split.
|
||||
*/
|
||||
public @NonNull String getSplitPermission() {
|
||||
return mSplitPermission;
|
||||
}
|
||||
|
||||
/**
|
||||
* The permissions that are added.
|
||||
*/
|
||||
public @NonNull List<String> getNewPermissions() {
|
||||
return mNewPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* The target API level when the permission was split.
|
||||
*/
|
||||
public @IntRange(from = 0) int getTargetSdk() {
|
||||
return mTargetSdk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
// You can override field equality logic by defining either of the methods like:
|
||||
// boolean fieldNameEquals(SplitPermissionInfoParcelable other) { ... }
|
||||
// boolean fieldNameEquals(FieldType otherValue) { ... }
|
||||
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
@SuppressWarnings("unchecked")
|
||||
SplitPermissionInfoParcelable that = (SplitPermissionInfoParcelable) o;
|
||||
//noinspection PointlessBooleanExpression
|
||||
return true
|
||||
&& Objects.equals(mSplitPermission, that.mSplitPermission)
|
||||
&& Objects.equals(mNewPermissions, that.mNewPermissions)
|
||||
&& mTargetSdk == that.mTargetSdk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
// You can override field hashCode logic by defining methods like:
|
||||
// int fieldNameHashCode() { ... }
|
||||
|
||||
int _hash = 1;
|
||||
_hash = 31 * _hash + Objects.hashCode(mSplitPermission);
|
||||
_hash = 31 * _hash + Objects.hashCode(mNewPermissions);
|
||||
_hash = 31 * _hash + mTargetSdk;
|
||||
return _hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
// You can override field parcelling by defining methods like:
|
||||
// void parcelFieldName(Parcel dest, int flags) { ... }
|
||||
|
||||
dest.writeString(mSplitPermission);
|
||||
dest.writeStringList(mNewPermissions);
|
||||
dest.writeInt(mTargetSdk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() { return 0; }
|
||||
|
||||
public static final @NonNull Parcelable.Creator<SplitPermissionInfoParcelable> CREATOR
|
||||
= new Parcelable.Creator<SplitPermissionInfoParcelable>() {
|
||||
@Override
|
||||
public SplitPermissionInfoParcelable[] newArray(int size) {
|
||||
return new SplitPermissionInfoParcelable[size];
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked", "RedundantCast"})
|
||||
public SplitPermissionInfoParcelable createFromParcel(Parcel in) {
|
||||
// You can override field unparcelling by defining methods like:
|
||||
// static FieldType unparcelFieldName(Parcel in) { ... }
|
||||
|
||||
String splitPermission = in.readString();
|
||||
List<String> newPermissions = new java.util.ArrayList<>();
|
||||
in.readStringList(newPermissions);
|
||||
int targetSdk = in.readInt();
|
||||
return new SplitPermissionInfoParcelable(
|
||||
splitPermission,
|
||||
newPermissions,
|
||||
targetSdk);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -26,14 +26,15 @@ import android.annotation.SystemService;
|
||||
import android.annotation.TestApi;
|
||||
import android.content.Context;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.content.pm.permission.SplitPermissionInfoParcelable;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.Immutable;
|
||||
import com.android.server.SystemConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* System level service for accessing the permission capabilities of the platform.
|
||||
@@ -44,18 +45,14 @@ import java.util.Objects;
|
||||
@SystemApi
|
||||
@SystemService(Context.PERMISSION_SERVICE)
|
||||
public final class PermissionManager {
|
||||
/**
|
||||
* {@link android.content.pm.PackageParser} needs access without having a {@link Context}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final ArrayList<SplitPermissionInfo> SPLIT_PERMISSIONS =
|
||||
SystemConfig.getInstance().getSplitPermissions();
|
||||
private static final String TAG = PermissionManager.class.getName();
|
||||
|
||||
private final @NonNull Context mContext;
|
||||
|
||||
private final IPackageManager mPackageManager;
|
||||
|
||||
private List<SplitPermissionInfo> mSplitPermissionInfos;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
@@ -123,7 +120,48 @@ public final class PermissionManager {
|
||||
* @return All permissions that are split.
|
||||
*/
|
||||
public @NonNull List<SplitPermissionInfo> getSplitPermissions() {
|
||||
return SPLIT_PERMISSIONS;
|
||||
if (mSplitPermissionInfos != null) {
|
||||
return mSplitPermissionInfos;
|
||||
}
|
||||
|
||||
List<SplitPermissionInfoParcelable> parcelableList;
|
||||
try {
|
||||
parcelableList = mPackageManager.getSplitPermissions();
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Error getting split permissions", e);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
mSplitPermissionInfos = splitPermissionInfoListToNonParcelableList(parcelableList);
|
||||
|
||||
return mSplitPermissionInfos;
|
||||
}
|
||||
|
||||
private List<SplitPermissionInfo> splitPermissionInfoListToNonParcelableList(
|
||||
List<SplitPermissionInfoParcelable> parcelableList) {
|
||||
final int size = parcelableList.size();
|
||||
List<SplitPermissionInfo> list = new ArrayList<>(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
list.add(new SplitPermissionInfo(parcelableList.get(i)));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link List} of {@link SplitPermissionInfo} into a List of
|
||||
* {@link SplitPermissionInfoParcelable} and returns it.
|
||||
* @hide
|
||||
*/
|
||||
public static List<SplitPermissionInfoParcelable> splitPermissionInfoListToParcelableList(
|
||||
List<SplitPermissionInfo> splitPermissionsList) {
|
||||
final int size = splitPermissionsList.size();
|
||||
List<SplitPermissionInfoParcelable> outList = new ArrayList<>(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
SplitPermissionInfo info = splitPermissionsList.get(i);
|
||||
outList.add(new SplitPermissionInfoParcelable(
|
||||
info.getSplitPermission(), info.getNewPermissions(), info.getTargetSdk()));
|
||||
}
|
||||
return outList;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,44 +170,40 @@ public final class PermissionManager {
|
||||
*/
|
||||
@Immutable
|
||||
public static final class SplitPermissionInfo {
|
||||
private final @NonNull String mSplitPerm;
|
||||
private final @NonNull List<String> mNewPerms;
|
||||
private final int mTargetSdk;
|
||||
private @NonNull final SplitPermissionInfoParcelable mSplitPermissionInfoParcelable;
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
SplitPermissionInfo that = (SplitPermissionInfo) o;
|
||||
return mTargetSdk == that.mTargetSdk
|
||||
&& mSplitPerm.equals(that.mSplitPerm)
|
||||
&& mNewPerms.equals(that.mNewPerms);
|
||||
return mSplitPermissionInfoParcelable.equals(that.mSplitPermissionInfoParcelable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mSplitPerm, mNewPerms, mTargetSdk);
|
||||
return mSplitPermissionInfoParcelable.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the permission that is split.
|
||||
*/
|
||||
public @NonNull String getSplitPermission() {
|
||||
return mSplitPerm;
|
||||
return mSplitPermissionInfoParcelable.getSplitPermission();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the permissions that are added.
|
||||
*/
|
||||
public @NonNull List<String> getNewPermissions() {
|
||||
return mNewPerms;
|
||||
return mSplitPermissionInfoParcelable.getNewPermissions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the target API level when the permission was split.
|
||||
*/
|
||||
public int getTargetSdk() {
|
||||
return mTargetSdk;
|
||||
return mSplitPermissionInfoParcelable.getTargetSdk();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -183,9 +217,11 @@ public final class PermissionManager {
|
||||
*/
|
||||
public SplitPermissionInfo(@NonNull String splitPerm, @NonNull List<String> newPerms,
|
||||
int targetSdk) {
|
||||
mSplitPerm = splitPerm;
|
||||
mNewPerms = newPerms;
|
||||
mTargetSdk = targetSdk;
|
||||
this(new SplitPermissionInfoParcelable(splitPerm, newPerms, targetSdk));
|
||||
}
|
||||
|
||||
private SplitPermissionInfo(@NonNull SplitPermissionInfoParcelable parcelable) {
|
||||
mSplitPermissionInfoParcelable = parcelable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,8 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* Loads global system configuration info.
|
||||
* Note: Initializing this class hits the disk and is slow. This class should generally only be
|
||||
* accessed by the system_server process.
|
||||
*/
|
||||
public class SystemConfig {
|
||||
static final String TAG = "SystemConfig";
|
||||
@@ -209,6 +211,11 @@ public class SystemConfig {
|
||||
private final ArraySet<String> mBugreportWhitelistedPackages = new ArraySet<>();
|
||||
|
||||
public static SystemConfig getInstance() {
|
||||
if (!isSystemProcess()) {
|
||||
Slog.wtf(TAG, "SystemConfig is being accessed by a process other than "
|
||||
+ "system_server.");
|
||||
}
|
||||
|
||||
synchronized (SystemConfig.class) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new SystemConfig();
|
||||
@@ -1154,4 +1161,8 @@ public class SystemConfig {
|
||||
mSplitPermissions.add(new SplitPermissionInfo(splitPerm, newPermissions, targetSdk));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isSystemProcess() {
|
||||
return Process.myUid() == Process.SYSTEM_UID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,6 +198,7 @@ import android.content.pm.VersionedPackage;
|
||||
import android.content.pm.dex.ArtManager;
|
||||
import android.content.pm.dex.DexMetadataHelper;
|
||||
import android.content.pm.dex.IArtManager;
|
||||
import android.content.pm.permission.SplitPermissionInfoParcelable;
|
||||
import android.content.res.Resources;
|
||||
import android.content.rollback.IRollbackManager;
|
||||
import android.database.ContentObserver;
|
||||
@@ -238,6 +239,7 @@ import android.os.storage.StorageManager;
|
||||
import android.os.storage.StorageManagerInternal;
|
||||
import android.os.storage.VolumeInfo;
|
||||
import android.os.storage.VolumeRecord;
|
||||
import android.permission.PermissionManager;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.MediaStore;
|
||||
import android.provider.Settings.Global;
|
||||
@@ -2121,6 +2123,12 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SplitPermissionInfoParcelable> getSplitPermissions() {
|
||||
return PermissionManager.splitPermissionInfoListToParcelableList(
|
||||
SystemConfig.getInstance().getSplitPermissions());
|
||||
}
|
||||
|
||||
private void notifyInstallObserver(String packageName) {
|
||||
Pair<PackageInstalledInfo, IPackageInstallObserver2> pair =
|
||||
mNoKillInstallObservers.remove(packageName);
|
||||
|
||||
@@ -967,10 +967,12 @@ public class PermissionManagerService {
|
||||
// or has updated its target SDK and AR is no longer implicit to it.
|
||||
// This is a compatibility workaround for apps when AR permission was
|
||||
// split in Q.
|
||||
int numSplitPerms = PermissionManager.SPLIT_PERMISSIONS.size();
|
||||
final List<PermissionManager.SplitPermissionInfo> permissionList =
|
||||
getSplitPermissions();
|
||||
int numSplitPerms = permissionList.size();
|
||||
for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
|
||||
PermissionManager.SplitPermissionInfo sp =
|
||||
PermissionManager.SPLIT_PERMISSIONS.get(splitPermNum);
|
||||
permissionList.get(splitPermNum);
|
||||
String splitPermName = sp.getSplitPermission();
|
||||
if (sp.getNewPermissions().contains(permName)
|
||||
&& origPermissions.hasInstallPermission(splitPermName)) {
|
||||
@@ -1537,10 +1539,10 @@ public class PermissionManagerService {
|
||||
String pkgName = pkg.packageName;
|
||||
ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();
|
||||
|
||||
int numSplitPerms = PermissionManager.SPLIT_PERMISSIONS.size();
|
||||
final List<PermissionManager.SplitPermissionInfo> permissionList = getSplitPermissions();
|
||||
int numSplitPerms = permissionList.size();
|
||||
for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
|
||||
PermissionManager.SplitPermissionInfo spi =
|
||||
PermissionManager.SPLIT_PERMISSIONS.get(splitPermNum);
|
||||
PermissionManager.SplitPermissionInfo spi = permissionList.get(splitPermNum);
|
||||
|
||||
List<String> newPerms = spi.getNewPermissions();
|
||||
int numNewPerms = newPerms.size();
|
||||
@@ -1608,6 +1610,10 @@ public class PermissionManagerService {
|
||||
return updatedUserIds;
|
||||
}
|
||||
|
||||
private List<PermissionManager.SplitPermissionInfo> getSplitPermissions() {
|
||||
return SystemConfig.getInstance().getSplitPermissions();
|
||||
}
|
||||
|
||||
private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
|
||||
boolean allowed = false;
|
||||
final int NP = PackageParser.NEW_PERMISSIONS.length;
|
||||
|
||||
Reference in New Issue
Block a user