1 /*
2  * Copyright (C) 2023 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 package com.android.adservices.service.common;
17 
18 import static java.lang.annotation.RetentionPolicy.SOURCE;
19 
20 import android.annotation.IntDef;
21 
22 import com.android.adservices.service.stats.AdServicesStatsLog;
23 import com.android.internal.annotations.VisibleForTesting;
24 
25 import java.lang.annotation.Retention;
26 import java.util.Objects;
27 
28 /** Represents a call to a public {@link AppManifestConfigHelper} method. */
29 public final class AppManifestConfigCall {
30 
31     public static final int API_UNSPECIFIED =
32             AdServicesStatsLog
33                     .APP_MANIFEST_CONFIG_HELPER_CALLED__API_ACCESS_TYPE__API_ACCESS_TYPE_UNSPECIFIED;
34     public static final int API_TOPICS =
35             AdServicesStatsLog
36                     .APP_MANIFEST_CONFIG_HELPER_CALLED__API_ACCESS_TYPE__API_ACCESS_TYPE_TOPICS;
37     public static final int API_CUSTOM_AUDIENCES =
38             AdServicesStatsLog
39                     .APP_MANIFEST_CONFIG_HELPER_CALLED__API_ACCESS_TYPE__API_ACCESS_TYPE_CUSTOM_AUDIENCES;
40 
41     public static final int API_PROTECTED_SIGNALS =
42             AdServicesStatsLog
43                     .APP_MANIFEST_CONFIG_HELPER_CALLED__API_ACCESS_TYPE__API_ACCESS_TYPE_PROTECTED_SIGNALS;
44 
45     public static final int API_AD_SELECTION =
46             AdServicesStatsLog
47                     .APP_MANIFEST_CONFIG_HELPER_CALLED__API_ACCESS_TYPE__API_ACCESS_TYPE_AD_SELECTION;
48     public static final int API_ATTRIBUTION =
49             AdServicesStatsLog
50                     .APP_MANIFEST_CONFIG_HELPER_CALLED__API_ACCESS_TYPE__API_ACCESS_TYPE_ATTRIBUTION;
51 
52     @IntDef({
53         API_UNSPECIFIED,
54         API_TOPICS,
55         API_CUSTOM_AUDIENCES,
56         API_ATTRIBUTION,
57         API_PROTECTED_SIGNALS,
58         API_AD_SELECTION
59     })
60     @Retention(SOURCE)
61     public @interface ApiType {}
62 
63     public static final int RESULT_UNSPECIFIED =
64             AdServicesStatsLog
65                     .APP_MANIFEST_CONFIG_HELPER_CALLED__API_ACCESS_RESULT__API_ACCESS_RESULT_UNSPECIFIED;
66     public static final int RESULT_ALLOWED_BY_DEFAULT_APP_DOES_NOT_HAVE_CONFIG =
67             AdServicesStatsLog
68                     .APP_MANIFEST_CONFIG_HELPER_CALLED__API_ACCESS_RESULT__API_ACCESS_RESULT_ALLOWED_BY_DEFAULT_APP_DOES_NOT_HAVE_CONFIG;
69     public static final int RESULT_ALLOWED_BY_DEFAULT_APP_HAS_CONFIG_WITHOUT_API_SECTION =
70             AdServicesStatsLog
71                     .APP_MANIFEST_CONFIG_HELPER_CALLED__API_ACCESS_RESULT__API_ACCESS_RESULT_ALLOWED_BY_DEFAULT_APP_HAS_CONFIG_WITHOUT_API_SECTION;
72     public static final int RESULT_ALLOWED_APP_ALLOWS_ALL =
73             AdServicesStatsLog
74                     .APP_MANIFEST_CONFIG_HELPER_CALLED__API_ACCESS_RESULT__API_ACCESS_RESULT_ALLOWED_APP_ALLOWS_ALL;
75     public static final int RESULT_ALLOWED_APP_ALLOWS_SPECIFIC_ID =
76             AdServicesStatsLog
77                     .APP_MANIFEST_CONFIG_HELPER_CALLED__API_ACCESS_RESULT__API_ACCESS_RESULT_ALLOWED_APP_ALLOWS_SPECIFIC_ID;
78     public static final int RESULT_DISALLOWED_APP_DOES_NOT_EXIST =
79             AdServicesStatsLog
80                     .APP_MANIFEST_CONFIG_HELPER_CALLED__API_ACCESS_RESULT__API_ACCESS_RESULT_DISALLOWED_APP_DOES_NOT_EXIST;
81     public static final int RESULT_DISALLOWED_APP_CONFIG_PARSING_ERROR =
82             AdServicesStatsLog
83                     .APP_MANIFEST_CONFIG_HELPER_CALLED__API_ACCESS_RESULT__API_ACCESS_RESULT_DISALLOWED_APP_CONFIG_PARSING_ERROR;
84     public static final int RESULT_DISALLOWED_APP_DOES_NOT_HAVE_CONFIG =
85             AdServicesStatsLog
86                     .APP_MANIFEST_CONFIG_HELPER_CALLED__API_ACCESS_RESULT__API_ACCESS_RESULT_DISALLOWED_APP_DOES_NOT_HAVE_CONFIG;
87     public static final int RESULT_DISALLOWED_APP_HAS_CONFIG_WITHOUT_API_SECTION =
88             AdServicesStatsLog
89                     .APP_MANIFEST_CONFIG_HELPER_CALLED__API_ACCESS_RESULT__API_ACCESS_RESULT_DISALLOWED_APP_DOES_HAS_CONFIG_WITHOUT_API_SECTION;
90     public static final int RESULT_DISALLOWED_BY_APP =
91             AdServicesStatsLog
92                     .APP_MANIFEST_CONFIG_HELPER_CALLED__API_ACCESS_RESULT__API_ACCESS_RESULT_DISALLOWED_BY_APP;
93     public static final int RESULT_DISALLOWED_GENERIC_ERROR =
94             AdServicesStatsLog
95                     .APP_MANIFEST_CONFIG_HELPER_CALLED__API_ACCESS_RESULT__API_ACCESS_RESULT_DISALLOWED_GENERIC_ERROR;
96 
97     @IntDef({
98         RESULT_UNSPECIFIED,
99         RESULT_ALLOWED_BY_DEFAULT_APP_DOES_NOT_HAVE_CONFIG,
100         RESULT_ALLOWED_BY_DEFAULT_APP_HAS_CONFIG_WITHOUT_API_SECTION,
101         RESULT_ALLOWED_APP_ALLOWS_ALL,
102         RESULT_ALLOWED_APP_ALLOWS_SPECIFIC_ID,
103         RESULT_DISALLOWED_APP_DOES_NOT_EXIST,
104         RESULT_DISALLOWED_APP_CONFIG_PARSING_ERROR,
105         RESULT_DISALLOWED_APP_DOES_NOT_HAVE_CONFIG,
106         RESULT_DISALLOWED_APP_HAS_CONFIG_WITHOUT_API_SECTION,
107         RESULT_DISALLOWED_BY_APP,
108         RESULT_DISALLOWED_GENERIC_ERROR
109     })
110     @Retention(SOURCE)
111     public @interface Result {}
112 
113     @VisibleForTesting static final String INVALID_API_TEMPLATE = "Invalid API: %d";
114 
115     public final String packageName;
116     public final @ApiType int api;
117     public @Result int result;
118 
AppManifestConfigCall(String packageName, @ApiType int api)119     public AppManifestConfigCall(String packageName, @ApiType int api) {
120         switch (api) {
121             case API_TOPICS:
122             case API_CUSTOM_AUDIENCES:
123             case API_ATTRIBUTION:
124             case API_PROTECTED_SIGNALS:
125             case API_AD_SELECTION:
126                 this.api = api;
127                 break;
128             default:
129                 throw new IllegalArgumentException(String.format(INVALID_API_TEMPLATE, api));
130         }
131         this.packageName = Objects.requireNonNull(packageName, "packageName cannot be null");
132     }
133 
134     @Override
equals(Object obj)135     public boolean equals(Object obj) {
136         if (this == obj) {
137             return true;
138         }
139         if (obj == null) {
140             return false;
141         }
142         if (getClass() != obj.getClass()) {
143             return false;
144         }
145         AppManifestConfigCall other = (AppManifestConfigCall) obj;
146         return api == other.api
147                 && Objects.equals(packageName, other.packageName)
148                 && result == other.result;
149     }
150 
151     @Override
hashCode()152     public int hashCode() {
153         return Objects.hash(api, packageName, result);
154     }
155 
156     @Override
toString()157     public String toString() {
158         return "AppManifestConfigCall[pkg="
159                 + packageName
160                 + ", api="
161                 + apiToString(api)
162                 + ", result="
163                 + resultToString(result)
164                 + "]";
165     }
166 
resultToString(@esult int result)167     static String resultToString(@Result int result) {
168         switch (result) {
169             case RESULT_UNSPECIFIED:
170                 return "UNSPECIFIED";
171             case RESULT_ALLOWED_BY_DEFAULT_APP_DOES_NOT_HAVE_CONFIG:
172                 return "ALLOWED_BY_DEFAULT_APP_DOES_NOT_HAVE_CONFIG";
173             case RESULT_ALLOWED_BY_DEFAULT_APP_HAS_CONFIG_WITHOUT_API_SECTION:
174                 return "ALLOWED_BY_DEFAULT_APP_HAS_CONFIG_WITHOUT_API_SECTION";
175             case RESULT_ALLOWED_APP_ALLOWS_ALL:
176                 return "ALLOWED_APP_ALLOWS_ALL";
177             case RESULT_ALLOWED_APP_ALLOWS_SPECIFIC_ID:
178                 return "ALLOWED_APP_ALLOWS_SPECIFIC_ID";
179             case RESULT_DISALLOWED_APP_DOES_NOT_EXIST:
180                 return "DISALLOWED_APP_DOES_NOT_EXIST";
181             case RESULT_DISALLOWED_APP_CONFIG_PARSING_ERROR:
182                 return "DISALLOWED_APP_CONFIG_PARSING_ERROR";
183             case RESULT_DISALLOWED_APP_DOES_NOT_HAVE_CONFIG:
184                 return "DISALLOWED_APP_DOES_NOT_HAVE_CONFIG";
185             case RESULT_DISALLOWED_APP_HAS_CONFIG_WITHOUT_API_SECTION:
186                 return "DISALLOWED_APP_HAS_CONFIG_WITHOUT_API_SECTION";
187             case RESULT_DISALLOWED_BY_APP:
188                 return "DISALLOWED_BY_APP";
189             case RESULT_DISALLOWED_GENERIC_ERROR:
190                 return "DISALLOWED_GENERIC_ERROR";
191             default:
192                 return "INVALID-" + result;
193         }
194     }
195 
apiToString(@piType int result)196     static String apiToString(@ApiType int result) {
197         switch (result) {
198             case API_UNSPECIFIED:
199                 return "UNSPECIFIED";
200             case API_TOPICS:
201                 return "TOPICS";
202             case API_CUSTOM_AUDIENCES:
203                 return "CUSTOM_AUDIENCES";
204             case API_ATTRIBUTION:
205                 return "ATTRIBUTION";
206             case API_PROTECTED_SIGNALS:
207                 return "PROTECTED_SIGNALS";
208             case API_AD_SELECTION:
209                 return "AD_SELECTION";
210             default:
211                 return "INVALID-" + result;
212         }
213     }
214 
isAllowed(@esult int result)215     static boolean isAllowed(@Result int result) {
216         switch (result) {
217             case RESULT_ALLOWED_BY_DEFAULT_APP_DOES_NOT_HAVE_CONFIG:
218             case RESULT_ALLOWED_BY_DEFAULT_APP_HAS_CONFIG_WITHOUT_API_SECTION:
219             case RESULT_ALLOWED_APP_ALLOWS_ALL:
220             case RESULT_ALLOWED_APP_ALLOWS_SPECIFIC_ID:
221                 return true;
222             default:
223                 return false;
224         }
225     }
226 }
227