Merge "cleanup up appRestrictions policy in the policy engine" into udc-dev am: 9088ec46f5
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22673946 Change-Id: Ib7cc427d3748da289c0bb26dbd4e87ab8831b712 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -17,50 +17,28 @@
|
|||||||
package com.android.server.devicepolicy;
|
package com.android.server.devicepolicy;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
|
||||||
import android.app.admin.BundlePolicyValue;
|
import android.app.admin.BundlePolicyValue;
|
||||||
import android.app.admin.PackagePolicyKey;
|
import android.app.admin.PackagePolicyKey;
|
||||||
import android.app.admin.PolicyKey;
|
import android.app.admin.PolicyKey;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Environment;
|
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.util.AtomicFile;
|
import android.util.Log;
|
||||||
import android.util.Slog;
|
|
||||||
import android.util.Xml;
|
|
||||||
|
|
||||||
import com.android.internal.annotations.GuardedBy;
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
|
||||||
import com.android.internal.util.XmlUtils;
|
import com.android.internal.util.XmlUtils;
|
||||||
import com.android.modules.utils.TypedXmlPullParser;
|
import com.android.modules.utils.TypedXmlPullParser;
|
||||||
import com.android.modules.utils.TypedXmlSerializer;
|
import com.android.modules.utils.TypedXmlSerializer;
|
||||||
|
|
||||||
import libcore.io.IoUtils;
|
|
||||||
|
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
// TODO(b/266704763): clean this up and stop creating separate files for each value, the code here
|
|
||||||
// is copied from UserManagerService, however it doesn't currently handle setting different
|
|
||||||
// restrictions for the same package in different users, it also will not remove the files for
|
|
||||||
// outdated restrictions, this will all get fixed when we save it as part of the policies file
|
|
||||||
// rather than in its own files.
|
|
||||||
final class BundlePolicySerializer extends PolicySerializer<Bundle> {
|
final class BundlePolicySerializer extends PolicySerializer<Bundle> {
|
||||||
|
|
||||||
private static final String TAG = "BundlePolicySerializer";
|
private static final String TAG = "BundlePolicySerializer";
|
||||||
|
|
||||||
private static final String ATTR_FILE_NAME = "file-name";
|
|
||||||
|
|
||||||
private static final String RESTRICTIONS_FILE_PREFIX = "AppRestrictions_";
|
|
||||||
private static final String XML_SUFFIX = ".xml";
|
|
||||||
|
|
||||||
private static final String TAG_RESTRICTIONS = "restrictions";
|
|
||||||
private static final String TAG_ENTRY = "entry";
|
private static final String TAG_ENTRY = "entry";
|
||||||
private static final String TAG_VALUE = "value";
|
private static final String TAG_VALUE = "value";
|
||||||
private static final String ATTR_KEY = "key";
|
private static final String ATTR_KEY = "key";
|
||||||
@@ -83,62 +61,26 @@ final class BundlePolicySerializer extends PolicySerializer<Bundle> {
|
|||||||
throw new IllegalArgumentException("policyKey is not of type "
|
throw new IllegalArgumentException("policyKey is not of type "
|
||||||
+ "PackagePolicyKey");
|
+ "PackagePolicyKey");
|
||||||
}
|
}
|
||||||
String packageName = ((PackagePolicyKey) policyKey).getPackageName();
|
writeBundle(value, serializer);
|
||||||
String fileName = packageToRestrictionsFileName(packageName, value);
|
|
||||||
writeApplicationRestrictionsLAr(fileName, value);
|
|
||||||
serializer.attribute(/* namespace= */ null, ATTR_FILE_NAME, fileName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
BundlePolicyValue readFromXml(TypedXmlPullParser parser) {
|
BundlePolicyValue readFromXml(TypedXmlPullParser parser) {
|
||||||
String fileName = parser.getAttributeValue(/* namespace= */ null, ATTR_FILE_NAME);
|
Bundle bundle = new Bundle();
|
||||||
|
ArrayList<String> values = new ArrayList<>();
|
||||||
return new BundlePolicyValue(readApplicationRestrictions(fileName));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String packageToRestrictionsFileName(String packageName, Bundle restrictions) {
|
|
||||||
return RESTRICTIONS_FILE_PREFIX + packageName + Objects.hash(restrictions) + XML_SUFFIX;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GuardedBy("mAppRestrictionsLock")
|
|
||||||
private static Bundle readApplicationRestrictions(String fileName) {
|
|
||||||
AtomicFile restrictionsFile =
|
|
||||||
new AtomicFile(new File(Environment.getDataSystemDirectory(), fileName));
|
|
||||||
return readApplicationRestrictions(restrictionsFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
@GuardedBy("mAppRestrictionsLock")
|
|
||||||
static Bundle readApplicationRestrictions(AtomicFile restrictionsFile) {
|
|
||||||
final Bundle restrictions = new Bundle();
|
|
||||||
final ArrayList<String> values = new ArrayList<>();
|
|
||||||
if (!restrictionsFile.getBaseFile().exists()) {
|
|
||||||
return restrictions;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileInputStream fis = null;
|
|
||||||
try {
|
try {
|
||||||
fis = restrictionsFile.openRead();
|
final int outerDepth = parser.getDepth();
|
||||||
final TypedXmlPullParser parser = Xml.resolvePullParser(fis);
|
while (XmlUtils.nextElementWithin(parser, outerDepth)) {
|
||||||
XmlUtils.nextElement(parser);
|
readBundle(bundle, values, parser);
|
||||||
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
|
||||||
Slog.e(TAG, "Unable to read restrictions file "
|
|
||||||
+ restrictionsFile.getBaseFile());
|
|
||||||
return restrictions;
|
|
||||||
}
|
}
|
||||||
while (parser.next() != XmlPullParser.END_DOCUMENT) {
|
} catch (XmlPullParserException | IOException e) {
|
||||||
readEntry(restrictions, values, parser);
|
Log.e(TAG, "Error parsing Bundle policy.", e);
|
||||||
}
|
return null;
|
||||||
} catch (IOException | XmlPullParserException e) {
|
|
||||||
Slog.w(TAG, "Error parsing " + restrictionsFile.getBaseFile(), e);
|
|
||||||
} finally {
|
|
||||||
IoUtils.closeQuietly(fis);
|
|
||||||
}
|
}
|
||||||
return restrictions;
|
return new BundlePolicyValue(bundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void readEntry(Bundle restrictions, ArrayList<String> values,
|
private static void readBundle(Bundle restrictions, ArrayList<String> values,
|
||||||
TypedXmlPullParser parser) throws XmlPullParserException, IOException {
|
TypedXmlPullParser parser) throws XmlPullParserException, IOException {
|
||||||
int type = parser.getEventType();
|
int type = parser.getEventType();
|
||||||
if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_ENTRY)) {
|
if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_ENTRY)) {
|
||||||
@@ -186,37 +128,11 @@ final class BundlePolicySerializer extends PolicySerializer<Bundle> {
|
|||||||
Bundle childBundle = new Bundle();
|
Bundle childBundle = new Bundle();
|
||||||
int outerDepth = parser.getDepth();
|
int outerDepth = parser.getDepth();
|
||||||
while (XmlUtils.nextElementWithin(parser, outerDepth)) {
|
while (XmlUtils.nextElementWithin(parser, outerDepth)) {
|
||||||
readEntry(childBundle, values, parser);
|
readBundle(childBundle, values, parser);
|
||||||
}
|
}
|
||||||
return childBundle;
|
return childBundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void writeApplicationRestrictionsLAr(String fileName, Bundle restrictions) {
|
|
||||||
AtomicFile restrictionsFile = new AtomicFile(
|
|
||||||
new File(Environment.getDataSystemDirectory(), fileName));
|
|
||||||
writeApplicationRestrictionsLAr(restrictions, restrictionsFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void writeApplicationRestrictionsLAr(Bundle restrictions, AtomicFile restrictionsFile) {
|
|
||||||
FileOutputStream fos = null;
|
|
||||||
try {
|
|
||||||
fos = restrictionsFile.startWrite();
|
|
||||||
final TypedXmlSerializer serializer = Xml.resolveSerializer(fos);
|
|
||||||
serializer.startDocument(null, true);
|
|
||||||
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
|
|
||||||
|
|
||||||
serializer.startTag(null, TAG_RESTRICTIONS);
|
|
||||||
writeBundle(restrictions, serializer);
|
|
||||||
serializer.endTag(null, TAG_RESTRICTIONS);
|
|
||||||
|
|
||||||
serializer.endDocument();
|
|
||||||
restrictionsFile.finishWrite(fos);
|
|
||||||
} catch (Exception e) {
|
|
||||||
restrictionsFile.failWrite(fos);
|
|
||||||
Slog.e(TAG, "Error writing application restrictions list", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void writeBundle(Bundle restrictions, TypedXmlSerializer serializer)
|
private static void writeBundle(Bundle restrictions, TypedXmlSerializer serializer)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
for (String key : restrictions.keySet()) {
|
for (String key : restrictions.keySet()) {
|
||||||
|
|||||||
@@ -11053,7 +11053,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isPermissionCheckFlagEnabled() && !isPolicyEngineForFinanceFlagEnabled()) {
|
if (!isPermissionCheckFlagEnabled() && !isPolicyEngineForFinanceFlagEnabled()) {
|
||||||
// TODO: Figure out if something like this needs to be restored for policy engine
|
|
||||||
final ComponentName profileOwner = getProfileOwnerAsUser(userId);
|
final ComponentName profileOwner = getProfileOwnerAsUser(userId);
|
||||||
if (profileOwner == null) {
|
if (profileOwner == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -11640,7 +11639,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
caller.getUserId());
|
caller.getUserId());
|
||||||
}
|
}
|
||||||
setBackwardsCompatibleAppRestrictions(
|
setBackwardsCompatibleAppRestrictions(
|
||||||
packageName, restrictions, caller.getUserHandle());
|
caller, packageName, restrictions, caller.getUserHandle());
|
||||||
} else {
|
} else {
|
||||||
Preconditions.checkCallAuthorization((caller.hasAdminComponent()
|
Preconditions.checkCallAuthorization((caller.hasAdminComponent()
|
||||||
&& (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
|
&& (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
|
||||||
@@ -11661,17 +11660,28 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set app restrictions in user manager to keep backwards compatibility for the old
|
* Set app restrictions in user manager for DPC callers only to keep backwards compatibility
|
||||||
* getApplicationRestrictions API.
|
* for the old getApplicationRestrictions API.
|
||||||
*/
|
*/
|
||||||
private void setBackwardsCompatibleAppRestrictions(
|
private void setBackwardsCompatibleAppRestrictions(
|
||||||
String packageName, Bundle restrictions, UserHandle userHandle) {
|
CallerIdentity caller, String packageName, Bundle restrictions, UserHandle userHandle) {
|
||||||
Bundle restrictionsToApply = restrictions == null || restrictions.isEmpty()
|
if ((caller.hasAdminComponent() && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
|
||||||
? getAppRestrictionsSetByAnyAdmin(packageName, userHandle)
|
|| (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_APP_RESTRICTIONS))) {
|
||||||
: restrictions;
|
Bundle restrictionsToApply = restrictions == null || restrictions.isEmpty()
|
||||||
mInjector.binderWithCleanCallingIdentity(() -> {
|
? getAppRestrictionsSetByAnyAdmin(packageName, userHandle)
|
||||||
mUserManager.setApplicationRestrictions(packageName, restrictionsToApply, userHandle);
|
: restrictions;
|
||||||
});
|
mInjector.binderWithCleanCallingIdentity(() -> {
|
||||||
|
mUserManager.setApplicationRestrictions(packageName, restrictionsToApply,
|
||||||
|
userHandle);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Notify package of changes via an intent - only sent to explicitly registered
|
||||||
|
// receivers. Sending here because For DPCs, this is being sent in UMS.
|
||||||
|
final Intent changeIntent = new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
|
||||||
|
changeIntent.setPackage(packageName);
|
||||||
|
changeIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
|
||||||
|
mContext.sendBroadcastAsUser(changeIntent, userHandle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Bundle getAppRestrictionsSetByAnyAdmin(String packageName, UserHandle userHandle) {
|
private Bundle getAppRestrictionsSetByAnyAdmin(String packageName, UserHandle userHandle) {
|
||||||
|
|||||||
Reference in New Issue
Block a user