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:
Kholoud Mohamed
2023-04-18 12:55:09 +00:00
committed by Automerger Merge Worker
2 changed files with 34 additions and 108 deletions

View File

@@ -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) { return new BundlePolicyValue(bundle);
Slog.w(TAG, "Error parsing " + restrictionsFile.getBaseFile(), e);
} finally {
IoUtils.closeQuietly(fis);
}
return restrictions;
} }
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()) {

View File

@@ -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) {
if ((caller.hasAdminComponent() && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
|| (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_APP_RESTRICTIONS))) {
Bundle restrictionsToApply = restrictions == null || restrictions.isEmpty() Bundle restrictionsToApply = restrictions == null || restrictions.isEmpty()
? getAppRestrictionsSetByAnyAdmin(packageName, userHandle) ? getAppRestrictionsSetByAnyAdmin(packageName, userHandle)
: restrictions; : restrictions;
mInjector.binderWithCleanCallingIdentity(() -> { mInjector.binderWithCleanCallingIdentity(() -> {
mUserManager.setApplicationRestrictions(packageName, restrictionsToApply, userHandle); 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) {