1 /*
2  * Copyright 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 androidx.privacysandbox.ads.adservices.adselection
18 
19 import android.annotation.SuppressLint
20 import android.os.Build
21 import android.os.ext.SdkExtensions
22 import androidx.annotation.RequiresExtension
23 import androidx.annotation.RestrictTo
24 import androidx.privacysandbox.ads.adservices.common.ExperimentalFeatures
25 import androidx.privacysandbox.ads.adservices.internal.AdServicesInfo
26 
27 /**
28  * Represent input parameters to the reportImpression API.
29  *
30  * @param adSelectionId An ID unique only to a device user that identifies a successful ad
31  *   selection.
32  * @param adSelectionConfig optional config used in the selectAds() call identified by the provided
33  *   ad selection ID. If the {@code adSelectionId} is for a on-device auction run using
34  *   [AdSelectionManager#selectAds], then the config must be included. If the {@code adSelectionId}
35  *   is for a server auction run where device info collected
36  *   by [AdSelectionManager#getAdSelectionData} then the impression reporting request should only
37  *   include the ad selection id.
38  */
39 class ReportImpressionRequest
40 public constructor(val adSelectionId: Long, val adSelectionConfig: AdSelectionConfig) {
41     @ExperimentalFeatures.Ext8OptIn
42     constructor(adSelectionId: Long) : this(adSelectionId, AdSelectionConfig.EMPTY)
43 
44     /** Checks whether two [ReportImpressionRequest] objects contain the same information. */
equalsnull45     override fun equals(other: Any?): Boolean {
46         if (this === other) return true
47         if (other !is ReportImpressionRequest) return false
48         return this.adSelectionId == other.adSelectionId &&
49             this.adSelectionConfig == other.adSelectionConfig
50     }
51 
52     /** Returns the hash of the [ReportImpressionRequest] object's data. */
hashCodenull53     override fun hashCode(): Int {
54         var hash = adSelectionId.hashCode()
55         hash = 31 * hash + adSelectionConfig.hashCode()
56         return hash
57     }
58 
59     /** Overrides the toString method. */
toStringnull60     override fun toString(): String {
61         return "ReportImpressionRequest: adSelectionId=$adSelectionId, " +
62             "adSelectionConfig=$adSelectionConfig"
63     }
64 
65     @SuppressLint("NewApi")
66     @RestrictTo(RestrictTo.Scope.LIBRARY)
convertToAdServicesnull67     internal fun convertToAdServices(): android.adservices.adselection.ReportImpressionRequest {
68         if (
69             AdServicesInfo.adServicesVersion() >= 10 || AdServicesInfo.extServicesVersionS() >= 10
70         ) {
71             return Ext10Impl.convertReportImpressionRequest(this)
72         }
73         return Ext4Impl.convertReportImpressionRequest(this)
74     }
75 
76     @RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 10)
77     @RequiresExtension(extension = Build.VERSION_CODES.S, version = 10)
78     private class Ext10Impl private constructor() {
79         companion object {
convertReportImpressionRequestnull80             fun convertReportImpressionRequest(
81                 request: ReportImpressionRequest
82             ): android.adservices.adselection.ReportImpressionRequest {
83                 return if (request.adSelectionConfig == AdSelectionConfig.EMPTY)
84                     android.adservices.adselection.ReportImpressionRequest(request.adSelectionId)
85                 else
86                     android.adservices.adselection.ReportImpressionRequest(
87                         request.adSelectionId,
88                         request.adSelectionConfig.convertToAdServices()
89                     )
90             }
91         }
92     }
93 
94     @RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 4)
95     @RequiresExtension(extension = Build.VERSION_CODES.S, version = 9)
96     private class Ext4Impl private constructor() {
97         companion object {
convertReportImpressionRequestnull98             fun convertReportImpressionRequest(
99                 request: ReportImpressionRequest
100             ): android.adservices.adselection.ReportImpressionRequest {
101                 if (request.adSelectionConfig == AdSelectionConfig.EMPTY) {
102                     throw UnsupportedOperationException(
103                         "adSelectionConfig is mandatory for" + "API versions lower than ext 10"
104                     )
105                 }
106                 return android.adservices.adselection.ReportImpressionRequest(
107                     request.adSelectionId,
108                     request.adSelectionConfig.convertToAdServices()
109                 )
110             }
111         }
112     }
113 }
114