• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.FlaggedApi;
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.content.IntentFilter;
25 import android.content.pm.parsing.result.ParseInput;
26 import android.content.pm.parsing.result.ParseResult;
27 import android.content.res.Configuration;
28 import android.content.res.Resources;
29 import android.content.res.TypedArray;
30 import android.content.res.XmlResourceParser;
31 import android.os.Build;
32 import android.util.Slog;
33 
34 import com.android.internal.annotations.VisibleForTesting;
35 import com.android.internal.pm.pkg.parsing.ParsingPackage;
36 import com.android.internal.pm.pkg.parsing.ParsingUtils;
37 
38 import org.xmlpull.v1.XmlPullParserException;
39 
40 import java.io.IOException;
41 
42 /** @hide */
43 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
44 public class ParsedMainComponentUtils {
45 
46     private static final String TAG = ParsingUtils.TAG;
47 
48     @NonNull
49     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
parseMainComponent( Component component, String tag, String[] separateProcesses, ParsingPackage pkg, TypedArray array, int flags, boolean useRoundIcon, @Nullable String defaultSplitName, @NonNull ParseInput input, int bannerAttr, int descriptionAttr, int directBootAwareAttr, int enabledAttr, int iconAttr, int labelAttr, int logoAttr, int nameAttr, int processAttr, int roundIconAttr, int splitNameAttr, int attributionTagsAttr, int intentMatchingFlagsAttr)50     static <Component extends ParsedMainComponentImpl> ParseResult<Component> parseMainComponent(
51             Component component, String tag, String[] separateProcesses, ParsingPackage pkg,
52             TypedArray array, int flags, boolean useRoundIcon, @Nullable String defaultSplitName,
53             @NonNull ParseInput input, int bannerAttr, int descriptionAttr, int directBootAwareAttr,
54             int enabledAttr, int iconAttr, int labelAttr, int logoAttr, int nameAttr,
55             int processAttr, int roundIconAttr, int splitNameAttr, int attributionTagsAttr,
56             int intentMatchingFlagsAttr) {
57         ParseResult<Component> result = ParsedComponentUtils.parseComponent(component, tag, pkg,
58                 array, useRoundIcon, input, bannerAttr, descriptionAttr, iconAttr, labelAttr,
59                 logoAttr, nameAttr, roundIconAttr);
60         if (result.isError()) {
61             return result;
62         }
63 
64         if (directBootAwareAttr != NOT_SET) {
65             component.setDirectBootAware(array.getBoolean(directBootAwareAttr, false));
66             if (component.isDirectBootAware()) {
67                 pkg.setPartiallyDirectBootAware(true);
68             }
69         }
70 
71         if (enabledAttr != NOT_SET) {
72             component.setEnabled(array.getBoolean(enabledAttr, true));
73         }
74 
75         if (processAttr != NOT_SET) {
76             CharSequence processName;
77             if (pkg.getTargetSdkVersion() >= Build.VERSION_CODES.FROYO) {
78                 processName = array.getNonConfigurationString(processAttr,
79                         Configuration.NATIVE_CONFIG_VERSION);
80             } else {
81                 // Some older apps have been seen to use a resource reference
82                 // here that on older builds was ignored (with a warning).  We
83                 // need to continue to do this for them so they don't break.
84                 processName = array.getNonResourceString(processAttr);
85             }
86 
87             // Backwards-compat, ignore error
88             ParseResult<String> processNameResult = ComponentParseUtils.buildProcessName(
89                     pkg.getPackageName(), pkg.getProcessName(), processName, flags,
90                     separateProcesses, input);
91             if (processNameResult.isError()) {
92                 return input.error(processNameResult);
93             }
94 
95             component.setProcessName(processNameResult.getResult());
96         }
97 
98         if (splitNameAttr != NOT_SET) {
99             component.setSplitName(array.getNonConfigurationString(splitNameAttr, 0));
100         }
101 
102         if (defaultSplitName != null && component.getSplitName() == null) {
103             component.setSplitName(defaultSplitName);
104         }
105 
106         if (attributionTagsAttr != NOT_SET) {
107             final String attributionTags = array.getNonConfigurationString(attributionTagsAttr, 0);
108             if (attributionTags != null) {
109                 component.setAttributionTags(attributionTags.split("\\|"));
110             }
111         }
112 
113         if (android.security.Flags.enableIntentMatchingFlags()) {
114             int resolvedFlags = resolveIntentMatchingFlags(
115                         pkg.getIntentMatchingFlags(), array.getInt(intentMatchingFlagsAttr, 0));
116             component.setIntentMatchingFlags(resolvedFlags);
117         }
118 
119         return input.success(component);
120     }
121 
parseIntentFilter( ParsedMainComponent mainComponent, ParsingPackage pkg, Resources resources, XmlResourceParser parser, boolean visibleToEphemeral, boolean allowGlobs, boolean allowAutoVerify, boolean allowImplicitEphemeralVisibility, boolean failOnNoActions, ParseInput input)122     static ParseResult<ParsedIntentInfoImpl> parseIntentFilter(
123             ParsedMainComponent mainComponent,
124             ParsingPackage pkg, Resources resources, XmlResourceParser parser,
125             boolean visibleToEphemeral, boolean allowGlobs, boolean allowAutoVerify,
126             boolean allowImplicitEphemeralVisibility, boolean failOnNoActions,
127             ParseInput input) throws IOException, XmlPullParserException {
128         ParseResult<ParsedIntentInfoImpl> intentResult = ParsedIntentInfoUtils.parseIntentInfo(
129                 mainComponent.getName(), pkg, resources, parser, allowGlobs,
130                 allowAutoVerify, input);
131         if (intentResult.isError()) {
132             return input.error(intentResult);
133         }
134 
135         ParsedIntentInfo intent = intentResult.getResult();
136         IntentFilter intentFilter = intent.getIntentFilter();
137         int actionCount = intentFilter.countActions();
138         if (actionCount == 0 && failOnNoActions) {
139             Slog.w(TAG, "No actions in " + parser.getName() + " at " + pkg.getBaseApkPath() + " "
140                     + parser.getPositionDescription());
141             // Backward-compat, do not actually fail
142             return input.success(null);
143         }
144 
145         int intentVisibility;
146         if (visibleToEphemeral) {
147             intentVisibility = IntentFilter.VISIBILITY_EXPLICIT;
148         } else if (allowImplicitEphemeralVisibility
149                 && ComponentParseUtils.isImplicitlyExposedIntent(intent)){
150             intentVisibility = IntentFilter.VISIBILITY_IMPLICIT;
151         } else {
152             intentVisibility = IntentFilter.VISIBILITY_NONE;
153         }
154         intentFilter.setVisibilityToInstantApp(intentVisibility);
155 
156         return input.success(intentResult.getResult());
157     }
158 
159     /**
160      * Resolves intent matching flags from the application and a component, prioritizing the
161      * component's flags.
162      *
163      * @param applicationFlags The flag value from the "application" tag.
164      * @param componentFlags   The flag value from the "component" tags.
165      * @return The resolved intent matching flags.
166      */
167     @FlaggedApi(android.security.Flags.FLAG_ENABLE_INTENT_MATCHING_FLAGS)
168     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
resolveIntentMatchingFlags(int applicationFlags, int componentFlags)169     public static int resolveIntentMatchingFlags(int applicationFlags, int componentFlags) {
170         if (componentFlags == 0) {
171             return applicationFlags;
172         } else {
173             return componentFlags;
174         }
175     }
176 }
177