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.annotation.StringRes;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 import android.util.ArraySet;
25 
26 import com.android.internal.util.DataClass;
27 
28 import java.util.ArrayList;
29 import java.util.List;
30 
31 /**
32  * A {@link android.R.styleable#AndroidManifestAttribution <attribution>} tag parsed from the
33  * manifest.
34  *
35  * @hide
36  */
37 @DataClass(genAidl = false)
38 public class ParsedAttribution implements Parcelable {
39     /** Maximum length of attribution tag */
40     public static final int MAX_ATTRIBUTION_TAG_LEN = 50;
41 
42     /** Maximum amount of attributions per package */
43     private static final int MAX_NUM_ATTRIBUTIONS = 10000;
44 
45     /** Tag of the attribution */
46     public final @NonNull String tag;
47 
48     /** User visible label fo the attribution */
49     public final @StringRes int label;
50 
51     /** Ids of previously declared attributions this attribution inherits from */
52     public final @NonNull List<String> inheritFrom;
53 
54     /**
55      * @return Is this set of attributions a valid combination for a single package?
56      */
isCombinationValid(@ullable List<ParsedAttribution> attributions)57     public static boolean isCombinationValid(@Nullable List<ParsedAttribution> attributions) {
58         if (attributions == null) {
59             return true;
60         }
61 
62         ArraySet<String> attributionTags = new ArraySet<>(attributions.size());
63         ArraySet<String> inheritFromAttributionTags = new ArraySet<>();
64 
65         int numAttributions = attributions.size();
66         if (numAttributions > MAX_NUM_ATTRIBUTIONS) {
67             return false;
68         }
69 
70         for (int attributionNum = 0; attributionNum < numAttributions; attributionNum++) {
71             boolean wasAdded = attributionTags.add(attributions.get(attributionNum).tag);
72             if (!wasAdded) {
73                 // feature id is not unique
74                 return false;
75             }
76         }
77 
78         for (int attributionNum = 0; attributionNum < numAttributions; attributionNum++) {
79             ParsedAttribution feature = attributions.get(attributionNum);
80 
81             int numInheritFrom = feature.inheritFrom.size();
82             for (int inheritFromNum = 0; inheritFromNum < numInheritFrom; inheritFromNum++) {
83                 String inheritFrom = feature.inheritFrom.get(inheritFromNum);
84 
85                 if (attributionTags.contains(inheritFrom)) {
86                     // Cannot inherit from a attribution that is still defined
87                     return false;
88                 }
89 
90                 boolean wasAdded = inheritFromAttributionTags.add(inheritFrom);
91                 if (!wasAdded) {
92                     // inheritFrom is not unique
93                     return false;
94                 }
95             }
96         }
97 
98         return true;
99     }
100 
101 
102 
103     // Code below generated by codegen v1.0.23.
104     //
105     // DO NOT MODIFY!
106     // CHECKSTYLE:OFF Generated code
107     //
108     // To regenerate run:
109     // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/parsing/component/ParsedAttribution.java
110     //
111     // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
112     //   Settings > Editor > Code Style > Formatter Control
113     //@formatter:off
114 
115 
116     @android.annotation.IntDef(prefix = "MAX_", value = {
117         MAX_ATTRIBUTION_TAG_LEN,
118         MAX_NUM_ATTRIBUTIONS
119     })
120     @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE)
121     @DataClass.Generated.Member
122     public @interface Max {}
123 
124     @DataClass.Generated.Member
maxToString(@ax int value)125     public static String maxToString(@Max int value) {
126         switch (value) {
127             case MAX_ATTRIBUTION_TAG_LEN:
128                     return "MAX_ATTRIBUTION_TAG_LEN";
129             case MAX_NUM_ATTRIBUTIONS:
130                     return "MAX_NUM_ATTRIBUTIONS";
131             default: return Integer.toHexString(value);
132         }
133     }
134 
135     /**
136      * Creates a new ParsedAttribution.
137      *
138      * @param tag
139      *   Tag of the attribution
140      * @param label
141      *   User visible label fo the attribution
142      * @param inheritFrom
143      *   Ids of previously declared attributions this attribution inherits from
144      */
145     @DataClass.Generated.Member
ParsedAttribution( @onNull String tag, @StringRes int label, @NonNull List<String> inheritFrom)146     public ParsedAttribution(
147             @NonNull String tag,
148             @StringRes int label,
149             @NonNull List<String> inheritFrom) {
150         this.tag = tag;
151         com.android.internal.util.AnnotationValidations.validate(
152                 NonNull.class, null, tag);
153         this.label = label;
154         com.android.internal.util.AnnotationValidations.validate(
155                 StringRes.class, null, label);
156         this.inheritFrom = inheritFrom;
157         com.android.internal.util.AnnotationValidations.validate(
158                 NonNull.class, null, inheritFrom);
159 
160         // onConstructed(); // You can define this method to get a callback
161     }
162 
163     @Override
164     @DataClass.Generated.Member
writeToParcel(@onNull Parcel dest, int flags)165     public void writeToParcel(@NonNull Parcel dest, int flags) {
166         // You can override field parcelling by defining methods like:
167         // void parcelFieldName(Parcel dest, int flags) { ... }
168 
169         dest.writeString(tag);
170         dest.writeInt(label);
171         dest.writeStringList(inheritFrom);
172     }
173 
174     @Override
175     @DataClass.Generated.Member
describeContents()176     public int describeContents() { return 0; }
177 
178     /** @hide */
179     @SuppressWarnings({"unchecked", "RedundantCast"})
180     @DataClass.Generated.Member
ParsedAttribution(@onNull Parcel in)181     protected ParsedAttribution(@NonNull Parcel in) {
182         // You can override field unparcelling by defining methods like:
183         // static FieldType unparcelFieldName(Parcel in) { ... }
184 
185         String _tag = in.readString();
186         int _label = in.readInt();
187         List<String> _inheritFrom = new ArrayList<>();
188         in.readStringList(_inheritFrom);
189 
190         this.tag = _tag;
191         com.android.internal.util.AnnotationValidations.validate(
192                 NonNull.class, null, tag);
193         this.label = _label;
194         com.android.internal.util.AnnotationValidations.validate(
195                 StringRes.class, null, label);
196         this.inheritFrom = _inheritFrom;
197         com.android.internal.util.AnnotationValidations.validate(
198                 NonNull.class, null, inheritFrom);
199 
200         // onConstructed(); // You can define this method to get a callback
201     }
202 
203     @DataClass.Generated.Member
204     public static final @NonNull Parcelable.Creator<ParsedAttribution> CREATOR
205             = new Parcelable.Creator<ParsedAttribution>() {
206         @Override
207         public ParsedAttribution[] newArray(int size) {
208             return new ParsedAttribution[size];
209         }
210 
211         @Override
212         public ParsedAttribution createFromParcel(@NonNull Parcel in) {
213             return new ParsedAttribution(in);
214         }
215     };
216 
217     @DataClass.Generated(
218             time = 1618351459610L,
219             codegenVersion = "1.0.23",
220             sourceFile = "frameworks/base/core/java/android/content/pm/parsing/component/ParsedAttribution.java",
221             inputSignatures = "public static final  int MAX_ATTRIBUTION_TAG_LEN\nprivate static final  int MAX_NUM_ATTRIBUTIONS\npublic final @android.annotation.NonNull java.lang.String tag\npublic final @android.annotation.StringRes int label\npublic final @android.annotation.NonNull java.util.List<java.lang.String> inheritFrom\npublic static  boolean isCombinationValid(java.util.List<android.content.pm.parsing.component.ParsedAttribution>)\nclass ParsedAttribution extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genAidl=false)")
222     @Deprecated
__metadata()223     private void __metadata() {}
224 
225 
226     //@formatter:on
227     // End of generated code
228 
229 }
230