Merge "Introduce per-app API for installer whitelisting" into rvc-dev am: 41b448e39b
Change-Id: I5008f9b0355161033769da4182cc1ac0894f6acf
This commit is contained in:
@@ -11896,6 +11896,7 @@ package android.content.pm {
|
||||
method public void setAppIcon(@Nullable android.graphics.Bitmap);
|
||||
method public void setAppLabel(@Nullable CharSequence);
|
||||
method public void setAppPackageName(@Nullable String);
|
||||
method public void setAutoRevokePermissionsMode(boolean);
|
||||
method public void setInstallLocation(int);
|
||||
method public void setInstallReason(int);
|
||||
method public void setMultiPackage();
|
||||
@@ -12025,6 +12026,7 @@ package android.content.pm {
|
||||
method public boolean hasSigningCertificate(int, @NonNull byte[], int);
|
||||
method public abstract boolean hasSystemFeature(@NonNull String);
|
||||
method public abstract boolean hasSystemFeature(@NonNull String, int);
|
||||
method @RequiresPermission(value="android.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS", conditional=true) public boolean isAutoRevokeWhitelisted(@NonNull String);
|
||||
method public boolean isAutoRevokeWhitelisted();
|
||||
method public boolean isDefaultApplicationIcon(@NonNull android.graphics.drawable.Drawable);
|
||||
method public boolean isDeviceUpgrading();
|
||||
@@ -12050,6 +12052,7 @@ package android.content.pm {
|
||||
method @Nullable public abstract android.content.pm.ResolveInfo resolveService(@NonNull android.content.Intent, int);
|
||||
method public abstract void setApplicationCategoryHint(@NonNull String, int);
|
||||
method @RequiresPermission(value=android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE, conditional=true) public abstract void setApplicationEnabledSetting(@NonNull String, int, int);
|
||||
method @RequiresPermission(value="android.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS", conditional=true) public boolean setAutoRevokeWhitelisted(@NonNull String, boolean);
|
||||
method @RequiresPermission(value=android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE, conditional=true) public abstract void setComponentEnabledSetting(@NonNull android.content.ComponentName, int, int);
|
||||
method public abstract void setInstallerPackageName(@NonNull String, @Nullable String);
|
||||
method public void setMimeGroup(@NonNull String, @NonNull java.util.Set<java.lang.String>);
|
||||
|
||||
@@ -235,6 +235,7 @@ package android {
|
||||
field public static final String UPGRADE_RUNTIME_PERMISSIONS = "android.permission.UPGRADE_RUNTIME_PERMISSIONS";
|
||||
field public static final String USER_ACTIVITY = "android.permission.USER_ACTIVITY";
|
||||
field public static final String USE_RESERVED_DISK = "android.permission.USE_RESERVED_DISK";
|
||||
field public static final String WHITELIST_AUTO_REVOKE_PERMISSIONS = "android.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS";
|
||||
field public static final String WHITELIST_RESTRICTED_PERMISSIONS = "android.permission.WHITELIST_RESTRICTED_PERMISSIONS";
|
||||
field public static final String WIFI_SET_DEVICE_MOBILITY_STATE = "android.permission.WIFI_SET_DEVICE_MOBILITY_STATE";
|
||||
field public static final String WIFI_UPDATE_USABILITY_STATS_SCORE = "android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE";
|
||||
@@ -2132,6 +2133,7 @@ package android.content.pm {
|
||||
public static class PackageInstaller.SessionInfo implements android.os.Parcelable {
|
||||
method public boolean getAllocateAggressive();
|
||||
method @Deprecated public boolean getAllowDowngrade();
|
||||
method public int getAutoRevokePermissionsMode();
|
||||
method public boolean getDontKillApp();
|
||||
method public boolean getEnableRollback();
|
||||
method @Nullable public String[] getGrantedRuntimePermissions();
|
||||
|
||||
@@ -933,6 +933,7 @@ package android.content.pm {
|
||||
}
|
||||
|
||||
public static class PackageInstaller.SessionInfo implements android.os.Parcelable {
|
||||
method public int getAutoRevokePermissionsMode();
|
||||
method public int getRollbackDataPolicy();
|
||||
method @NonNull public java.util.Set<java.lang.String> getWhitelistedRestrictedPermissions();
|
||||
}
|
||||
|
||||
@@ -1071,9 +1071,17 @@ public class AppOpsManager {
|
||||
/** @hide Auto-revoke app permissions if app is unused for an extended period */
|
||||
public static final int OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED = 97;
|
||||
|
||||
/**
|
||||
* Whether {@link #OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED} is allowed to be changed by
|
||||
* the installer
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int OP_AUTO_REVOKE_MANAGED_BY_INSTALLER = 98;
|
||||
|
||||
/** @hide */
|
||||
@UnsupportedAppUsage
|
||||
public static final int _NUM_OP = 98;
|
||||
public static final int _NUM_OP = 99;
|
||||
|
||||
/** Access to coarse location information. */
|
||||
public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
|
||||
@@ -1463,6 +1471,7 @@ public class AppOpsManager {
|
||||
OP_LOADER_USAGE_STATS,
|
||||
OP_ACCESS_CALL_AUDIO,
|
||||
OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
|
||||
OP_AUTO_REVOKE_MANAGED_BY_INSTALLER,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1572,6 +1581,7 @@ public class AppOpsManager {
|
||||
OP_LOADER_USAGE_STATS, // LOADER_USAGE_STATS
|
||||
OP_ACCESS_CALL_AUDIO, // ACCESS_CALL_AUDIO
|
||||
OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, //AUTO_REVOKE_PERMISSIONS_IF_UNUSED
|
||||
OP_AUTO_REVOKE_MANAGED_BY_INSTALLER, //OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1887,6 +1897,7 @@ public class AppOpsManager {
|
||||
android.Manifest.permission.LOADER_USAGE_STATS,
|
||||
Manifest.permission.ACCESS_CALL_AUDIO,
|
||||
null, // no permission for OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED
|
||||
null, // no permission for OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2202,6 +2213,7 @@ public class AppOpsManager {
|
||||
AppOpsManager.MODE_DEFAULT, // LOADER_USAGE_STATS
|
||||
AppOpsManager.MODE_DEFAULT, // ACCESS_CALL_AUDIO
|
||||
AppOpsManager.MODE_DEFAULT, // OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED
|
||||
AppOpsManager.MODE_ALLOWED, // OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -839,6 +839,27 @@ public class ApplicationPackageManager extends PackageManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setAutoRevokeWhitelisted(
|
||||
@NonNull String packageName, boolean whitelisted) {
|
||||
try {
|
||||
final int userId = getUserId();
|
||||
return mPermissionManager.setAutoRevokeWhitelisted(packageName, whitelisted, userId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoRevokeWhitelisted(@NonNull String packageName) {
|
||||
try {
|
||||
final int userId = getUserId();
|
||||
return mPermissionManager.isAutoRevokeWhitelisted(packageName, userId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
|
||||
@NonNull String permName, @PermissionWhitelistFlags int flags) {
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
package android.content.pm;
|
||||
|
||||
import static android.app.AppOpsManager.MODE_ALLOWED;
|
||||
import static android.app.AppOpsManager.MODE_DEFAULT;
|
||||
import static android.app.AppOpsManager.MODE_IGNORED;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.CurrentTimeMillisLong;
|
||||
import android.annotation.IntDef;
|
||||
@@ -1456,6 +1460,8 @@ public class PackageInstaller {
|
||||
/** {@hide} */
|
||||
public List<String> whitelistedRestrictedPermissions;
|
||||
/** {@hide} */
|
||||
public int autoRevokePermissionsMode = MODE_DEFAULT;
|
||||
/** {@hide} */
|
||||
public String installerPackageName;
|
||||
/** {@hide} */
|
||||
public boolean isMultiPackage;
|
||||
@@ -1498,6 +1504,7 @@ public class PackageInstaller {
|
||||
volumeUuid = source.readString();
|
||||
grantedRuntimePermissions = source.readStringArray();
|
||||
whitelistedRestrictedPermissions = source.createStringArrayList();
|
||||
autoRevokePermissionsMode = source.readInt();
|
||||
installerPackageName = source.readString();
|
||||
isMultiPackage = source.readBoolean();
|
||||
isStaged = source.readBoolean();
|
||||
@@ -1528,6 +1535,7 @@ public class PackageInstaller {
|
||||
ret.volumeUuid = volumeUuid;
|
||||
ret.grantedRuntimePermissions = grantedRuntimePermissions;
|
||||
ret.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
|
||||
ret.autoRevokePermissionsMode = autoRevokePermissionsMode;
|
||||
ret.installerPackageName = installerPackageName;
|
||||
ret.isMultiPackage = isMultiPackage;
|
||||
ret.isStaged = isStaged;
|
||||
@@ -1690,6 +1698,22 @@ public class PackageInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether permissions should be auto-revoked if this package is unused for an
|
||||
* extended periodd of time.
|
||||
*
|
||||
* It's disabled by default but generally the installer should enable it for most packages,
|
||||
* excluding only those where doing so might cause breakage that cannot be easily addressed
|
||||
* by simply re-requesting the permission(s).
|
||||
*
|
||||
* If user explicitly enabled or disabled it via settings, this call is ignored.
|
||||
*
|
||||
* @param shouldAutoRevoke whether permissions should be auto-revoked.
|
||||
*/
|
||||
public void setAutoRevokePermissionsMode(boolean shouldAutoRevoke) {
|
||||
autoRevokePermissionsMode = shouldAutoRevoke ? MODE_ALLOWED : MODE_IGNORED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request that rollbacks be enabled or disabled for the given upgrade with rollback data
|
||||
* policy set to RESTORE.
|
||||
@@ -1932,6 +1956,7 @@ public class PackageInstaller {
|
||||
pw.printPair("volumeUuid", volumeUuid);
|
||||
pw.printPair("grantedRuntimePermissions", grantedRuntimePermissions);
|
||||
pw.printPair("whitelistedRestrictedPermissions", whitelistedRestrictedPermissions);
|
||||
pw.printPair("autoRevokePermissions", autoRevokePermissionsMode);
|
||||
pw.printPair("installerPackageName", installerPackageName);
|
||||
pw.printPair("isMultiPackage", isMultiPackage);
|
||||
pw.printPair("isStaged", isStaged);
|
||||
@@ -1964,6 +1989,7 @@ public class PackageInstaller {
|
||||
dest.writeString(volumeUuid);
|
||||
dest.writeStringArray(grantedRuntimePermissions);
|
||||
dest.writeStringList(whitelistedRestrictedPermissions);
|
||||
dest.writeInt(autoRevokePermissionsMode);
|
||||
dest.writeString(installerPackageName);
|
||||
dest.writeBoolean(isMultiPackage);
|
||||
dest.writeBoolean(isStaged);
|
||||
@@ -2085,6 +2111,8 @@ public class PackageInstaller {
|
||||
public String[] grantedRuntimePermissions;
|
||||
/** {@hide}*/
|
||||
public List<String> whitelistedRestrictedPermissions;
|
||||
/** {@hide}*/
|
||||
public int autoRevokePermissionsMode = MODE_DEFAULT;
|
||||
/** {@hide} */
|
||||
public int installFlags;
|
||||
/** {@hide} */
|
||||
@@ -2147,6 +2175,7 @@ public class PackageInstaller {
|
||||
referrerUri = source.readParcelable(null);
|
||||
grantedRuntimePermissions = source.readStringArray();
|
||||
whitelistedRestrictedPermissions = source.createStringArrayList();
|
||||
autoRevokePermissionsMode = source.readInt();
|
||||
|
||||
installFlags = source.readInt();
|
||||
isMultiPackage = source.readBoolean();
|
||||
@@ -2373,6 +2402,24 @@ public class PackageInstaller {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status of whether permission auto-revocation should be allowed, ignored, or
|
||||
* deferred to manifest data.
|
||||
*
|
||||
* @see android.app.AppOpsManager#MODE_ALLOWED
|
||||
* @see android.app.AppOpsManager#MODE_IGNORED
|
||||
* @see android.app.AppOpsManager#MODE_DEFAULT
|
||||
*
|
||||
* @return the status of auto-revoke for this package
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
@SystemApi
|
||||
public int getAutoRevokePermissionsMode() {
|
||||
return autoRevokePermissionsMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value set in {@link SessionParams#setAllowDowngrade(boolean)}.
|
||||
*
|
||||
@@ -2660,6 +2707,7 @@ public class PackageInstaller {
|
||||
dest.writeParcelable(referrerUri, flags);
|
||||
dest.writeStringArray(grantedRuntimePermissions);
|
||||
dest.writeStringList(whitelistedRestrictedPermissions);
|
||||
dest.writeInt(autoRevokePermissionsMode);
|
||||
dest.writeInt(installFlags);
|
||||
dest.writeBoolean(isMultiPackage);
|
||||
dest.writeBoolean(isStaged);
|
||||
|
||||
@@ -4575,6 +4575,53 @@ public abstract class PackageManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks an application exempt from having its permissions be automatically revoked when
|
||||
* the app is unused for an extended period of time.
|
||||
*
|
||||
* Only the installer on record that installed the given package, or a holder of
|
||||
* {@code WHITELIST_AUTO_REVOKE_PERMISSIONS} is allowed to call this.
|
||||
*
|
||||
* Packages start in whitelisted state, and it is the installer's responsibility to
|
||||
* un-whitelist the packages it installs, unless auto-revoking permissions from that package
|
||||
* would cause breakages beyond having to re-request the permission(s).
|
||||
*
|
||||
* @param packageName The app for which to set exemption.
|
||||
* @param whitelisted Whether the app should be whitelisted.
|
||||
*
|
||||
* @return whether any change took effect.
|
||||
*
|
||||
* @see #isAutoRevokeWhitelisted
|
||||
*
|
||||
* @throws SecurityException if you you have no access to modify this.
|
||||
*/
|
||||
@RequiresPermission(value = Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS,
|
||||
conditional = true)
|
||||
public boolean setAutoRevokeWhitelisted(@NonNull String packageName, boolean whitelisted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether an application is exempt from having its permissions be automatically revoked
|
||||
* when the app is unused for an extended period of time.
|
||||
*
|
||||
* Only the installer on record that installed the given package, or a holder of
|
||||
* {@code WHITELIST_AUTO_REVOKE_PERMISSIONS} is allowed to call this.
|
||||
* @param packageName The app for which to set exemption.
|
||||
*
|
||||
* @return Whether the app is whitelisted.
|
||||
*
|
||||
* @see #setAutoRevokeWhitelisted
|
||||
*
|
||||
* @throws SecurityException if you you have no access to this.
|
||||
*/
|
||||
@RequiresPermission(value = Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS,
|
||||
conditional = true)
|
||||
public boolean isAutoRevokeWhitelisted(@NonNull String packageName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets whether you should show UI with rationale for requesting a permission.
|
||||
* You should do this only if you do not have the permission and the context in
|
||||
|
||||
@@ -110,4 +110,8 @@ interface IPermissionManager {
|
||||
List<String> getAutoRevokeExemptionRequestedPackages(int userId);
|
||||
|
||||
List<String> getAutoRevokeExemptionGrantedPackages(int userId);
|
||||
|
||||
boolean setAutoRevokeWhitelisted(String packageName, boolean whitelisted, int userId);
|
||||
|
||||
boolean isAutoRevokeWhitelisted(String packageName, int userId);
|
||||
}
|
||||
|
||||
@@ -3756,6 +3756,12 @@
|
||||
<permission android:name="android.permission.WHITELIST_RESTRICTED_PERMISSIONS"
|
||||
android:protectionLevel="signature|installer" />
|
||||
|
||||
<!-- @SystemApi Allows an application to an exempt an app from having its permission be
|
||||
auto-revoked when unused for an extended period of time.
|
||||
@hide -->
|
||||
<permission android:name="android.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS"
|
||||
android:protectionLevel="signature|installer" />
|
||||
|
||||
<!-- @hide Allows an application to observe permission changes. -->
|
||||
<permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS"
|
||||
android:protectionLevel="signature|privileged" />
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.pm;
|
||||
|
||||
import static android.app.AppOpsManager.MODE_DEFAULT;
|
||||
import static android.content.pm.DataLoaderType.INCREMENTAL;
|
||||
import static android.content.pm.DataLoaderType.STREAMING;
|
||||
import static android.content.pm.PackageInstaller.LOCATION_DATA_APP;
|
||||
@@ -166,6 +167,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
private static final String TAG_GRANTED_RUNTIME_PERMISSION = "granted-runtime-permission";
|
||||
private static final String TAG_WHITELISTED_RESTRICTED_PERMISSION =
|
||||
"whitelisted-restricted-permission";
|
||||
private static final String TAG_AUTO_REVOKE_PERMISSIONS_MODE =
|
||||
"auto-revoke-permissions-mode";
|
||||
private static final String ATTR_SESSION_ID = "sessionId";
|
||||
private static final String ATTR_USER_ID = "userId";
|
||||
private static final String ATTR_INSTALLER_PACKAGE_NAME = "installerPackageName";
|
||||
@@ -623,6 +626,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
}
|
||||
info.grantedRuntimePermissions = params.grantedRuntimePermissions;
|
||||
info.whitelistedRestrictedPermissions = params.whitelistedRestrictedPermissions;
|
||||
info.autoRevokePermissionsMode = params.autoRevokePermissionsMode;
|
||||
info.installFlags = params.installFlags;
|
||||
info.isMultiPackage = params.isMultiPackage;
|
||||
info.isStaged = params.isStaged;
|
||||
@@ -2889,6 +2893,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeAutoRevokePermissionsMode(@NonNull XmlSerializer out, int mode)
|
||||
throws IOException {
|
||||
out.startTag(null, TAG_AUTO_REVOKE_PERMISSIONS_MODE);
|
||||
writeIntAttribute(out, ATTR_MODE, mode);
|
||||
out.endTag(null, TAG_AUTO_REVOKE_PERMISSIONS_MODE);
|
||||
}
|
||||
|
||||
|
||||
private static File buildAppIconFile(int sessionId, @NonNull File sessionsDir) {
|
||||
return new File(sessionsDir, "app_icon." + sessionId + ".png");
|
||||
@@ -2969,6 +2980,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
writeGrantedRuntimePermissionsLocked(out, params.grantedRuntimePermissions);
|
||||
writeWhitelistedRestrictedPermissionsLocked(out,
|
||||
params.whitelistedRestrictedPermissions);
|
||||
writeAutoRevokePermissionsMode(out, params.autoRevokePermissionsMode);
|
||||
|
||||
// Persist app icon if changed since last written
|
||||
File appIconFile = buildAppIconFile(sessionId, sessionsDir);
|
||||
@@ -3112,6 +3124,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
// depth.
|
||||
List<String> grantedRuntimePermissions = new ArrayList<>();
|
||||
List<String> whitelistedRestrictedPermissions = new ArrayList<>();
|
||||
int autoRevokePermissionsMode = MODE_DEFAULT;
|
||||
List<Integer> childSessionIds = new ArrayList<>();
|
||||
List<InstallationFile> files = new ArrayList<>();
|
||||
int outerDepth = in.getDepth();
|
||||
@@ -3128,6 +3141,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
whitelistedRestrictedPermissions.add(readStringAttribute(in, ATTR_NAME));
|
||||
|
||||
}
|
||||
if (TAG_AUTO_REVOKE_PERMISSIONS_MODE.equals(in.getName())) {
|
||||
autoRevokePermissionsMode = readIntAttribute(in, ATTR_MODE);
|
||||
}
|
||||
if (TAG_CHILD_SESSION.equals(in.getName())) {
|
||||
childSessionIds.add(readIntAttribute(in, ATTR_SESSION_ID, SessionInfo.INVALID_ID));
|
||||
}
|
||||
@@ -3150,6 +3166,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
params.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
|
||||
}
|
||||
|
||||
params.autoRevokePermissionsMode = autoRevokePermissionsMode;
|
||||
|
||||
int[] childSessionIdsArray;
|
||||
if (childSessionIds.size() > 0) {
|
||||
childSessionIdsArray = new int[childSessionIds.size()];
|
||||
|
||||
@@ -25,6 +25,7 @@ import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
|
||||
import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS;
|
||||
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
|
||||
import static android.app.AppOpsManager.MODE_ALLOWED;
|
||||
import static android.app.AppOpsManager.MODE_DEFAULT;
|
||||
import static android.app.AppOpsManager.MODE_IGNORED;
|
||||
import static android.content.Intent.ACTION_MAIN;
|
||||
import static android.content.Intent.CATEGORY_DEFAULT;
|
||||
@@ -1656,12 +1657,13 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
&& parentRes.pkg != null)
|
||||
? parentRes.pkg.getRequestedPermissions()
|
||||
: args.whitelistedRestrictedPermissions;
|
||||
int autoRevokePermissionsMode = args.autoRevokePermissionsMode;
|
||||
|
||||
// Handle the parent package
|
||||
handlePackagePostInstall(parentRes, grantPermissions,
|
||||
killApp, virtualPreload, grantedPermissions,
|
||||
whitelistedRestrictedPermissions, didRestore,
|
||||
args.installSource.installerPackageName, args.observer,
|
||||
whitelistedRestrictedPermissions, autoRevokePermissionsMode,
|
||||
didRestore, args.installSource.installerPackageName, args.observer,
|
||||
args.mDataLoaderType);
|
||||
|
||||
// Handle the child packages
|
||||
@@ -1671,7 +1673,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
|
||||
handlePackagePostInstall(childRes, grantPermissions,
|
||||
killApp, virtualPreload, grantedPermissions,
|
||||
whitelistedRestrictedPermissions, false /*didRestore*/,
|
||||
whitelistedRestrictedPermissions, autoRevokePermissionsMode,
|
||||
false /*didRestore*/,
|
||||
args.installSource.installerPackageName, args.observer,
|
||||
args.mDataLoaderType);
|
||||
}
|
||||
@@ -2000,6 +2003,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
|
||||
boolean killApp, boolean virtualPreload,
|
||||
String[] grantedPermissions, List<String> whitelistedRestrictedPermissions,
|
||||
int autoRevokePermissionsMode,
|
||||
boolean launchedForRestore, String installerPackage,
|
||||
IPackageInstallObserver2 installObserver, int dataLoaderType) {
|
||||
final boolean succeeded = res.returnCode == PackageManager.INSTALL_SUCCEEDED;
|
||||
@@ -2020,6 +2024,11 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
Process.myUid(), FLAG_PERMISSION_WHITELIST_INSTALLER);
|
||||
}
|
||||
|
||||
if (autoRevokePermissionsMode == MODE_ALLOWED || autoRevokePermissionsMode == MODE_IGNORED) {
|
||||
mPermissionManager.setAutoRevokeWhitelisted(res.pkg.getPackageName(),
|
||||
autoRevokePermissionsMode == MODE_IGNORED, UserHandle.myUserId());
|
||||
}
|
||||
|
||||
// Now that we successfully installed the package, grant runtime
|
||||
// permissions if requested before broadcasting the install. Also
|
||||
// for legacy apps in permission review mode we clear the permission
|
||||
@@ -14297,6 +14306,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
final String packageAbiOverride;
|
||||
final String[] grantedRuntimePermissions;
|
||||
final List<String> whitelistedRestrictedPermissions;
|
||||
final int autoRevokePermissionsMode;
|
||||
final VerificationInfo verificationInfo;
|
||||
final PackageParser.SigningDetails signingDetails;
|
||||
final int installReason;
|
||||
@@ -14311,6 +14321,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
int installFlags, InstallSource installSource, String volumeUuid,
|
||||
VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
|
||||
String[] grantedPermissions, List<String> whitelistedRestrictedPermissions,
|
||||
int autoRevokePermissionsMode,
|
||||
SigningDetails signingDetails, int installReason,
|
||||
long requiredInstalledVersionCode, int dataLoaderType) {
|
||||
super(user);
|
||||
@@ -14324,6 +14335,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
this.packageAbiOverride = packageAbiOverride;
|
||||
this.grantedRuntimePermissions = grantedPermissions;
|
||||
this.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
|
||||
this.autoRevokePermissionsMode = autoRevokePermissionsMode;
|
||||
this.signingDetails = signingDetails;
|
||||
this.installReason = installReason;
|
||||
this.requiredInstalledVersionCode = requiredInstalledVersionCode;
|
||||
@@ -14360,6 +14372,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
packageAbiOverride = sessionParams.abiOverride;
|
||||
grantedRuntimePermissions = sessionParams.grantedRuntimePermissions;
|
||||
whitelistedRestrictedPermissions = sessionParams.whitelistedRestrictedPermissions;
|
||||
autoRevokePermissionsMode = sessionParams.autoRevokePermissionsMode;
|
||||
signingDetails = activeInstallSession.getSigningDetails();
|
||||
requiredInstalledVersionCode = sessionParams.requiredInstalledVersionCode;
|
||||
forceQueryableOverride = sessionParams.forceQueryableOverride;
|
||||
@@ -14956,6 +14969,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
final String abiOverride;
|
||||
final String[] installGrantPermissions;
|
||||
final List<String> whitelistedRestrictedPermissions;
|
||||
final int autoRevokePermissionsMode;
|
||||
/** If non-null, drop an async trace when the install completes */
|
||||
final String traceMethod;
|
||||
final int traceCookie;
|
||||
@@ -14975,6 +14989,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
UserHandle user, String[] instructionSets,
|
||||
String abiOverride, String[] installGrantPermissions,
|
||||
List<String> whitelistedRestrictedPermissions,
|
||||
int autoRevokePermissionsMode,
|
||||
String traceMethod, int traceCookie, SigningDetails signingDetails,
|
||||
int installReason, boolean forceQueryableOverride,
|
||||
MultiPackageInstallParams multiPackageInstallParams, int dataLoaderType) {
|
||||
@@ -14989,6 +15004,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
this.abiOverride = abiOverride;
|
||||
this.installGrantPermissions = installGrantPermissions;
|
||||
this.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
|
||||
this.autoRevokePermissionsMode = autoRevokePermissionsMode;
|
||||
this.traceMethod = traceMethod;
|
||||
this.traceCookie = traceCookie;
|
||||
this.signingDetails = signingDetails;
|
||||
@@ -15004,6 +15020,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
params.installSource, params.volumeUuid,
|
||||
params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
|
||||
params.grantedRuntimePermissions, params.whitelistedRestrictedPermissions,
|
||||
params.autoRevokePermissionsMode,
|
||||
params.traceMethod, params.traceCookie, params.signingDetails,
|
||||
params.installReason, params.forceQueryableOverride,
|
||||
params.mParentInstallParams, params.mDataLoaderType);
|
||||
@@ -15095,7 +15112,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
/** Existing install */
|
||||
FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
|
||||
super(OriginInfo.fromNothing(), null, null, 0, InstallSource.EMPTY,
|
||||
null, null, instructionSets, null, null, null, null, 0,
|
||||
null, null, instructionSets, null, null, null, MODE_DEFAULT, null, 0,
|
||||
PackageParser.SigningDetails.UNKNOWN,
|
||||
PackageManager.INSTALL_REASON_UNKNOWN, false, null /* parent */,
|
||||
DataLoaderType.NONE);
|
||||
@@ -22471,7 +22488,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
|
||||
installSource, volumeUuid, null /*verificationInfo*/, user,
|
||||
packageAbiOverride, null /*grantedPermissions*/,
|
||||
null /*whitelistedRestrictedPermissions*/, PackageParser.SigningDetails.UNKNOWN,
|
||||
null /*whitelistedRestrictedPermissions*/, MODE_DEFAULT /* autoRevokePermissions */,
|
||||
PackageParser.SigningDetails.UNKNOWN,
|
||||
PackageManager.INSTALL_REASON_UNKNOWN, PackageManager.VERSION_CODE_HIGHEST,
|
||||
DataLoaderType.NONE);
|
||||
params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
|
||||
|
||||
@@ -19,6 +19,8 @@ package com.android.server.pm.permission;
|
||||
import static android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY;
|
||||
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
|
||||
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
|
||||
import static android.app.AppOpsManager.MODE_ALLOWED;
|
||||
import static android.app.AppOpsManager.MODE_IGNORED;
|
||||
import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT;
|
||||
import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
|
||||
import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
|
||||
@@ -53,6 +55,7 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.UserIdInt;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.ApplicationPackageManager;
|
||||
import android.app.IActivityManager;
|
||||
import android.app.admin.DeviceAdminInfo;
|
||||
@@ -217,6 +220,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
/** Default permission policy to provide proper behaviour out-of-the-box */
|
||||
private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
|
||||
|
||||
/** App ops manager */
|
||||
private final AppOpsManager mAppOpsManager;
|
||||
|
||||
/**
|
||||
* Built-in permissions. Read from system configuration files. Mapping is from
|
||||
* UID to permission name.
|
||||
@@ -356,6 +362,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
|
||||
mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
|
||||
mSettings = new PermissionSettings(mLock);
|
||||
mAppOpsManager = context.getSystemService(AppOpsManager.class);
|
||||
|
||||
mHandlerThread = new ServiceThread(TAG,
|
||||
Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
|
||||
@@ -1198,6 +1205,77 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setAutoRevokeWhitelisted(
|
||||
@NonNull String packageName, boolean whitelisted, int userId) {
|
||||
Objects.requireNonNull(packageName);
|
||||
|
||||
final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
|
||||
if (!checkAutoRevokeAccess(pkg, callingUid)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mAppOpsManager
|
||||
.checkOpNoThrow(AppOpsManager.OP_AUTO_REVOKE_MANAGED_BY_INSTALLER,
|
||||
callingUid, packageName)
|
||||
!= MODE_ALLOWED) {
|
||||
// Whitelist user set - don't override
|
||||
return false;
|
||||
}
|
||||
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mAppOpsManager.setMode(AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
|
||||
callingUid, packageName,
|
||||
whitelisted ? MODE_IGNORED : MODE_ALLOWED);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean checkAutoRevokeAccess(AndroidPackage pkg, int callingUid) {
|
||||
if (pkg == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
|
||||
Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS)
|
||||
== PackageManager.PERMISSION_GRANTED;
|
||||
final boolean isCallerInstallerOnRecord =
|
||||
mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);
|
||||
|
||||
if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
|
||||
throw new SecurityException("Caller must either hold "
|
||||
+ Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS
|
||||
+ " or be the installer on record");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoRevokeWhitelisted(@NonNull String packageName, int userId) {
|
||||
Objects.requireNonNull(packageName);
|
||||
|
||||
final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
|
||||
if (!checkAutoRevokeAccess(pkg, callingUid)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return mAppOpsManager.checkOpNoThrow(
|
||||
AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, callingUid, packageName)
|
||||
== MODE_IGNORED;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void grantRuntimePermission(String packageName, String permName, final int userId) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
@@ -4377,6 +4455,12 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
packageName, permissions, flags, userId);
|
||||
}
|
||||
@Override
|
||||
public void setAutoRevokeWhitelisted(
|
||||
@NonNull String packageName, boolean whitelisted, int userId) {
|
||||
PermissionManagerService.this.setAutoRevokeWhitelisted(
|
||||
packageName, whitelisted, userId);
|
||||
}
|
||||
@Override
|
||||
public void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg) {
|
||||
PermissionManagerService.this
|
||||
.updatePermissions(packageName, pkg, mDefaultPermissionCallback);
|
||||
|
||||
@@ -189,7 +189,9 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager
|
||||
/** Sets the whitelisted, restricted permissions for the given package. */
|
||||
public abstract void setWhitelistedRestrictedPermissions(
|
||||
@NonNull String packageName, @NonNull List<String> permissions,
|
||||
@PackageManager.PermissionWhitelistFlags int flags, @NonNull int userId);
|
||||
@PackageManager.PermissionWhitelistFlags int flags, int userId);
|
||||
public abstract void setAutoRevokeWhitelisted(
|
||||
@NonNull String packageName, boolean whitelisted, int userId);
|
||||
|
||||
/**
|
||||
* Update permissions when a package changed.
|
||||
|
||||
Reference in New Issue
Block a user