1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ondevicepersonalization.services.manifest; 18 19 import android.content.Context; 20 import android.content.pm.PackageManager; 21 import android.content.res.Resources; 22 import android.content.res.XmlResourceParser; 23 24 /** 25 * Helper class for parsing and checking app manifest configs 26 */ 27 public final class AppManifestConfigHelper { 28 private static final String ON_DEVICE_PERSONALIZATION_CONFIG_PROPERTY = 29 "android.ondevicepersonalization.ON_DEVICE_PERSONALIZATION_CONFIG"; 30 AppManifestConfigHelper()31 private AppManifestConfigHelper() { 32 } 33 34 /** 35 * Determines if the given package's manifest contains ODP settings 36 * 37 * @param context the context of the API call. 38 * @param packageName the packageName of the package whose manifest config will be read 39 * @return true if the ODP setting exists, false otherwise 40 */ manifestContainsOdpSettings(Context context, String packageName)41 public static Boolean manifestContainsOdpSettings(Context context, 42 String packageName) { 43 PackageManager pm = context.getPackageManager(); 44 try { 45 pm.getProperty(ON_DEVICE_PERSONALIZATION_CONFIG_PROPERTY, packageName); 46 } catch (PackageManager.NameNotFoundException e) { 47 return false; 48 } 49 return true; 50 } 51 52 /** Returns the ODP manifest config for a package. */ getAppManifestConfig(Context context, String packageName)53 public static AppManifestConfig getAppManifestConfig(Context context, 54 String packageName) { 55 if (!manifestContainsOdpSettings(context, packageName)) { 56 // TODO(b/241941021) Determine correct exception to throw 57 throw new IllegalArgumentException( 58 "OdpSettings not found for package: " + packageName.toString()); 59 } 60 PackageManager pm = context.getPackageManager(); 61 try { 62 int resId = pm.getProperty(ON_DEVICE_PERSONALIZATION_CONFIG_PROPERTY, 63 packageName).getResourceId(); 64 Resources resources = pm.getResourcesForApplication(packageName); 65 XmlResourceParser xmlParser = resources.getXml(resId); 66 // TODO(b/239479120) Update to avoid re-parsing the XML too frequently if required 67 return AppManifestConfigParser.getConfig(xmlParser); 68 } catch (Exception e) { 69 // TODO(b/241941021) Determine correct exception to throw 70 throw new IllegalArgumentException( 71 "Failed to parse manifest for package: " + packageName, e); 72 } 73 } 74 75 /** 76 * Gets the download URL from package's ODP settings config 77 * 78 * @param context the context of the API call. 79 * @param packageName the packageName of the package whose manifest config will be read 80 */ getDownloadUrlFromOdpSettings(Context context, String packageName)81 public static String getDownloadUrlFromOdpSettings(Context context, String packageName) { 82 return getAppManifestConfig(context, packageName).getDownloadUrl(); 83 } 84 85 /** 86 * Gets the service name from package's ODP settings config 87 * 88 * @param context the context of the API call. 89 * @param packageName the packageName of the package whose manifest config will be read 90 */ getServiceNameFromOdpSettings(Context context, String packageName)91 public static String getServiceNameFromOdpSettings(Context context, 92 String packageName) { 93 return getAppManifestConfig(context, packageName).getServiceName(); 94 } 95 96 /** 97 * Gets the federated compute service remote server url from package's ODP settings config 98 * 99 * @param context the context of the API call. 100 * @param packageName the packageName of the package whose manifest config will be read 101 */ getFcRemoteServerUrlFromOdpSettings(Context context, String packageName)102 public static String getFcRemoteServerUrlFromOdpSettings(Context context, 103 String packageName) { 104 return getAppManifestConfig(context, packageName).getFcRemoteServerUrl(); 105 } 106 } 107