diff options
author | 2023-11-13 14:30:04 -0800 | |
---|---|---|
committer | 2023-11-17 15:46:21 -0800 | |
commit | 83c155a41932d3d81c4a5039dc6bb34c044647e5 (patch) | |
tree | 833ddb792a146c87214ad99f9f3415dfce74e2bf | |
parent | c8d02cd69e3a20fca4c3180f1fd7f5f501a25f6c (diff) |
[Role Logic Move] Access Resources portably
In many places throughout role-controller, we call
context.getResources(). Many of these calls rely on the assumption that
this Context is for the PermissionController app.
But, when we move role-controller to SystemServer, this assumption can
no longer be made; the Context will be a system context. Still, in some
scenarios we'll want to reference framework resources, and in some cases
we'll want to reference PermissionController resources.
To solve this, create utils methods to return 'Resources' objects, for
both scenarios, and don't assume anything about which app is the
current app.
Also, change how we access the roles.xml file. Rather than using a
static initializer, access resourceIds using string-based rather than
android.R.value-based resource names. This simplifies the code somewhat,
and removes the need to ensure we always invoke the static initializer
on startup.
Fix: 308198705
Test: atest CtsRoleTestCases
Change-Id: Ic6812e8ae6c611efd9b4152894a73361cc19ecf1
2 files changed, 76 insertions, 1 deletions
diff --git a/PermissionController/role-controller/java/com/android/role/controller/model/RoleParser.java b/PermissionController/role-controller/java/com/android/role/controller/model/RoleParser.java index 4f59c7b31..3d89e12c0 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/model/RoleParser.java +++ b/PermissionController/role-controller/java/com/android/role/controller/model/RoleParser.java @@ -21,8 +21,10 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.PermissionInfo; +import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.os.Build; +import android.permission.flags.Flags; import android.util.ArrayMap; import android.util.Log; import android.util.Pair; @@ -31,7 +33,9 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import com.android.modules.utils.build.SdkLevel; import com.android.role.controller.behavior.BrowserRoleBehavior; +import com.android.role.controller.util.ResourceUtils; import org.xmlpull.v1.XmlPullParserException; @@ -149,7 +153,7 @@ public class RoleParser { */ @NonNull public ArrayMap<String, Role> parse() { - try (XmlResourceParser parser = sGetRolesXml.apply(mContext)) { + try (XmlResourceParser parser = getRolesXml()) { Pair<ArrayMap<String, PermissionSet>, ArrayMap<String, Role>> xml = parseXml(parser); if (xml == null) { return new ArrayMap<>(); @@ -164,6 +168,20 @@ public class RoleParser { } } + /** + * Retrieves the roles.xml resource from a context + */ + private XmlResourceParser getRolesXml() { + if (SdkLevel.isAtLeastV() && Flags.roleControllerInSystemServer()) { + Resources resources = ResourceUtils.getPermissionControllerResources(mContext); + int resourceId = resources.getIdentifier("roles", "xml", + ResourceUtils.RESOURCE_PACKAGE_NAME_PERMISSION_CONTROLLER); + return resources.getXml(resourceId); + } else { + return sGetRolesXml.apply(mContext); + } + } + @Nullable private Pair<ArrayMap<String, PermissionSet>, ArrayMap<String, Role>> parseXml( @NonNull XmlResourceParser parser) throws IOException, XmlPullParserException { diff --git a/PermissionController/role-controller/java/com/android/role/controller/util/ResourceUtils.java b/PermissionController/role-controller/java/com/android/role/controller/util/ResourceUtils.java new file mode 100644 index 000000000..2617b953a --- /dev/null +++ b/PermissionController/role-controller/java/com/android/role/controller/util/ResourceUtils.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2023 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 com.android.role.controller.util; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.permission.flags.Flags; + +import androidx.annotation.NonNull; + +import com.android.modules.utils.build.SdkLevel; + +public class ResourceUtils { + + private ResourceUtils() {} + + public static String RESOURCE_PACKAGE_NAME_PERMISSION_CONTROLLER = + "com.android.permissioncontroller"; + + /** + * Get a {@link Resources} object to be used to access PermissionController resources. + */ + @NonNull + public static Resources getPermissionControllerResources(@NonNull Context context) { + return getPermissionControllerContext(context).getResources(); + } + + @NonNull + private static Context getPermissionControllerContext(@NonNull Context context) { + if (!SdkLevel.isAtLeastV() || !Flags.roleControllerInSystemServer()) { + // We don't have the getPermissionControllerPackageName() API below V, + // but role controller always runs in PermissionController below V. + return context; + } + String packageName = context.getPackageManager().getPermissionControllerPackageName(); + try { + return context.createPackageContext(packageName, 0); + } catch (PackageManager.NameNotFoundException e) { + throw new RuntimeException("Cannot create PermissionController context", e); + } + } +} |