1 /* 2 * Copyright (C) 2020 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 android.content.pm.parsing.component; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.content.pm.PackageManager; 22 import android.content.pm.PackageManager.Property; 23 import android.content.pm.parsing.ParsingPackage; 24 import android.content.pm.parsing.ParsingPackageUtils; 25 import android.content.pm.parsing.ParsingUtils; 26 import android.content.pm.parsing.result.ParseInput; 27 import android.content.pm.parsing.result.ParseResult; 28 import android.content.res.Resources; 29 import android.content.res.TypedArray; 30 import android.content.res.XmlResourceParser; 31 import android.os.Bundle; 32 import android.text.TextUtils; 33 import android.util.TypedValue; 34 35 import com.android.internal.annotations.VisibleForTesting; 36 37 /** @hide */ 38 class ParsedComponentUtils { 39 40 @NonNull 41 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) parseComponent( Component component, String tag, ParsingPackage pkg, TypedArray array, boolean useRoundIcon, ParseInput input, int bannerAttr, @Nullable Integer descriptionAttr, int iconAttr, int labelAttr, int logoAttr, int nameAttr, int roundIconAttr)42 static <Component extends ParsedComponent> ParseResult<Component> parseComponent( 43 Component component, String tag, ParsingPackage pkg, TypedArray array, 44 boolean useRoundIcon, ParseInput input, int bannerAttr, 45 @Nullable Integer descriptionAttr, int iconAttr, int labelAttr, int logoAttr, 46 int nameAttr, int roundIconAttr) { 47 String name = array.getNonConfigurationString(nameAttr, 0); 48 if (TextUtils.isEmpty(name)) { 49 return input.error(tag + " does not specify android:name"); 50 } 51 52 String packageName = pkg.getPackageName(); 53 String className = ParsingUtils.buildClassName(packageName, name); 54 if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)) { 55 return input.error(tag + " invalid android:name"); 56 } 57 58 //noinspection ConstantConditions; null check done above with isEmpty 59 component.setName(className); 60 component.setPackageName(packageName); 61 62 int roundIconVal = useRoundIcon ? array.getResourceId(roundIconAttr, 0) : 0; 63 if (roundIconVal != 0) { 64 component.icon = roundIconVal; 65 component.nonLocalizedLabel = null; 66 } else { 67 int iconVal = array.getResourceId(iconAttr, 0); 68 if (iconVal != 0) { 69 component.icon = iconVal; 70 component.nonLocalizedLabel = null; 71 } 72 } 73 74 int logoVal = array.getResourceId(logoAttr, 0); 75 if (logoVal != 0) { 76 component.logo = logoVal; 77 } 78 79 int bannerVal = array.getResourceId(bannerAttr, 0); 80 if (bannerVal != 0) { 81 component.banner = bannerVal; 82 } 83 84 if (descriptionAttr != null) { 85 component.descriptionRes = array.getResourceId(descriptionAttr, 0); 86 } 87 88 TypedValue v = array.peekValue(labelAttr); 89 if (v != null) { 90 component.labelRes = v.resourceId; 91 if (v.resourceId == 0) { 92 component.nonLocalizedLabel = v.coerceToString(); 93 } 94 } 95 96 return input.success(component); 97 } 98 addMetaData(ParsedComponent component, ParsingPackage pkg, Resources resources, XmlResourceParser parser, ParseInput input)99 static ParseResult<Bundle> addMetaData(ParsedComponent component, ParsingPackage pkg, 100 Resources resources, XmlResourceParser parser, ParseInput input) { 101 ParseResult<Property> result = ParsingPackageUtils.parseMetaData(pkg, component, 102 resources, parser, "<meta-data>", input); 103 if (result.isError()) { 104 return input.error(result); 105 } 106 final Property property = result.getResult(); 107 if (property != null) { 108 component.metaData = property.toBundle(component.metaData); 109 } 110 return input.success(component.metaData); 111 } 112 addProperty(ParsedComponent component, ParsingPackage pkg, Resources resources, XmlResourceParser parser, ParseInput input)113 static ParseResult<Property> addProperty(ParsedComponent component, ParsingPackage pkg, 114 Resources resources, XmlResourceParser parser, ParseInput input) { 115 ParseResult<Property> result = ParsingPackageUtils.parseMetaData(pkg, component, 116 resources, parser, "<property>", input); 117 if (result.isError()) { 118 return input.error(result); 119 } 120 final Property property = result.getResult(); 121 if (property != null) { 122 component.addProperty(property); 123 } 124 return input.success(property); 125 } 126 } 127