Merge "Refactor PermissionManager.SPLIT_PERMISSIONS" into qt-qpr1-dev

am: fcb2ce1503

Change-Id: I830c2580f3d141a3641e023c189c148a0a1737d0
This commit is contained in:
Anthony Hugh
2019-09-09 19:24:39 -07:00
committed by android-build-merger
8 changed files with 312 additions and 33 deletions

View File

@@ -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();
}

View File

@@ -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)) {

View File

@@ -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;

View File

@@ -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);
}
};
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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;