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.internal.pm.pkg.component; 18 19 import static com.android.internal.pm.pkg.parsing.ParsingUtils.NOT_SET; 20 21 import android.annotation.NonNull; 22 import android.content.pm.PackageManager; 23 import android.content.pm.PackageManager.Property; 24 import android.content.pm.parsing.result.ParseInput; 25 import android.content.pm.parsing.result.ParseResult; 26 import android.content.res.Resources; 27 import android.content.res.TypedArray; 28 import android.content.res.XmlResourceParser; 29 import android.os.Bundle; 30 import android.text.TextUtils; 31 import android.util.TypedValue; 32 33 import com.android.internal.annotations.VisibleForTesting; 34 import com.android.internal.pm.pkg.parsing.ParsingPackage; 35 import com.android.internal.pm.pkg.parsing.ParsingPackageUtils; 36 import com.android.internal.pm.pkg.parsing.ParsingUtils; 37 38 /** @hide */ 39 class ParsedComponentUtils { 40 41 @NonNull 42 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) parseComponent( Component component, String tag, ParsingPackage pkg, TypedArray array, boolean useRoundIcon, ParseInput input, int bannerAttr, int descriptionAttr, int iconAttr, int labelAttr, int logoAttr, int nameAttr, int roundIconAttr)43 static <Component extends ParsedComponentImpl> ParseResult<Component> parseComponent( 44 Component component, String tag, ParsingPackage pkg, TypedArray array, 45 boolean useRoundIcon, ParseInput input, int bannerAttr, int descriptionAttr, 46 int iconAttr, int labelAttr, int logoAttr, 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 .setPackageName(packageName); 61 62 int roundIconVal = useRoundIcon ? array.getResourceId(roundIconAttr, 0) : 0; 63 if (roundIconVal != 0) { 64 component.setIcon(roundIconVal) 65 .setNonLocalizedLabel(null); 66 } else { 67 int iconVal = array.getResourceId(iconAttr, 0); 68 if (iconVal != 0) { 69 component.setIcon(iconVal); 70 component.setNonLocalizedLabel(null); 71 } 72 } 73 74 int logoVal = array.getResourceId(logoAttr, 0); 75 if (logoVal != 0) { 76 component.setLogo(logoVal); 77 } 78 79 int bannerVal = array.getResourceId(bannerAttr, 0); 80 if (bannerVal != 0) { 81 component.setBanner(bannerVal); 82 } 83 84 if (descriptionAttr != NOT_SET) { 85 component.setDescriptionRes(array.getResourceId(descriptionAttr, 0)); 86 } 87 88 TypedValue v = array.peekValue(labelAttr); 89 if (v != null) { 90 component.setLabelRes(v.resourceId); 91 if (v.resourceId == 0) { 92 component.setNonLocalizedLabel(v.coerceToString()); 93 } 94 } 95 96 return input.success(component); 97 } 98 addMetaData(ParsedComponentImpl component, ParsingPackage pkg, Resources resources, XmlResourceParser parser, ParseInput input)99 static ParseResult<Bundle> addMetaData(ParsedComponentImpl 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.setMetaData(property.toBundle(component.getMetaData())); 109 } 110 return input.success(component.getMetaData()); 111 } 112 addProperty(ParsedComponentImpl component, ParsingPackage pkg, Resources resources, XmlResourceParser parser, ParseInput input)113 static ParseResult<Property> addProperty(ParsedComponentImpl 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