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.measurement
18 
19 import android.annotation.SuppressLint
20 import android.net.Uri
21 import android.os.Build
22 import android.os.ext.SdkExtensions
23 import android.view.InputEvent
24 import androidx.annotation.RequiresExtension
25 import androidx.privacysandbox.ads.adservices.measurement.WebSourceParams.Companion.convertWebSourceParams
26 
27 /**
28  * Class to hold input to measurement source registration calls from web context.
29  *
30  * @param webSourceParams Registration info to fetch sources.
31  * @param topOriginUri Top level origin of publisher.
32  * @param inputEvent User Interaction {@link InputEvent} used by the AttributionReporting API to
33  *   distinguish clicks from views.
34  * @param appDestination App destination of the source. It is the android app {@link Uri} where
35  *   corresponding conversion is expected. At least one of app destination or web destination is
36  *   required.
37  * @param webDestination Web destination of the source. It is the website {@link Uri} where
38  *   corresponding conversion is expected. At least one of app destination or web destination is
39  *   required.
40  * @param verifiedDestination Verified destination by the caller. This is where the user actually
41  *   landed.
42  */
43 class WebSourceRegistrationRequest
44 public constructor(
45     val webSourceParams: List<WebSourceParams>,
46     val topOriginUri: Uri,
47     val inputEvent: InputEvent? = null,
48     val appDestination: Uri? = null,
49     val webDestination: Uri? = null,
50     val verifiedDestination: Uri? = null
51 ) {
52 
equalsnull53     override fun equals(other: Any?): Boolean {
54         if (this === other) return true
55         if (other !is WebSourceRegistrationRequest) return false
56         return this.webSourceParams == other.webSourceParams &&
57             this.webDestination == other.webDestination &&
58             this.appDestination == other.appDestination &&
59             this.topOriginUri == other.topOriginUri &&
60             this.inputEvent == other.inputEvent &&
61             this.verifiedDestination == other.verifiedDestination
62     }
63 
hashCodenull64     override fun hashCode(): Int {
65         var hash = webSourceParams.hashCode()
66         hash = 31 * hash + topOriginUri.hashCode()
67         if (inputEvent != null) {
68             hash = 31 * hash + inputEvent.hashCode()
69         }
70         if (appDestination != null) {
71             hash = 31 * hash + appDestination.hashCode()
72         }
73         if (webDestination != null) {
74             hash = 31 * hash + webDestination.hashCode()
75         }
76         // Since topOriginUri is non-null.
77         hash = 31 * hash + topOriginUri.hashCode()
78         if (inputEvent != null) {
79             hash = 31 * hash + inputEvent.hashCode()
80         }
81         if (verifiedDestination != null) {
82             hash = 31 * hash + verifiedDestination.hashCode()
83         }
84         return hash
85     }
86 
toStringnull87     override fun toString(): String {
88         val vals =
89             "WebSourceParams=[$webSourceParams], TopOriginUri=$topOriginUri, " +
90                 "InputEvent=$inputEvent, AppDestination=$appDestination, " +
91                 "WebDestination=$webDestination, VerifiedDestination=$verifiedDestination"
92         return "WebSourceRegistrationRequest { $vals }"
93     }
94 
95     @SuppressLint("NewApi")
96     @RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 4)
97     @RequiresExtension(extension = Build.VERSION_CODES.S, version = 9)
convertToAdServicesnull98     internal fun convertToAdServices():
99         android.adservices.measurement.WebSourceRegistrationRequest {
100         return android.adservices.measurement.WebSourceRegistrationRequest.Builder(
101                 convertWebSourceParams(webSourceParams),
102                 topOriginUri
103             )
104             .setWebDestination(webDestination)
105             .setAppDestination(appDestination)
106             .setInputEvent(inputEvent)
107             .setVerifiedDestination(verifiedDestination)
108             .build()
109     }
110 
111     /**
112      * Builder for [WebSourceRegistrationRequest].
113      *
114      * @param webSourceParams source parameters containing source registration parameters, the list
115      *   should not be empty
116      * @param topOriginUri source publisher [Uri]
117      */
118     public class Builder(
119         private val webSourceParams: List<WebSourceParams>,
120         private val topOriginUri: Uri
121     ) {
122         private var inputEvent: InputEvent? = null
123         private var appDestination: Uri? = null
124         private var webDestination: Uri? = null
125         private var verifiedDestination: Uri? = null
126 
127         /**
128          * Setter for input event.
129          *
130          * @param inputEvent User Interaction InputEvent used by the AttributionReporting API to
131          *   distinguish clicks from views.
132          * @return builder
133          */
<lambda>null134         fun setInputEvent(inputEvent: InputEvent): Builder = apply { this.inputEvent = inputEvent }
135 
136         /**
137          * Setter for app destination. It is the android app {@link Uri} where corresponding
138          * conversion is expected. At least one of app destination or web destination is required.
139          *
140          * @param appDestination app destination [Uri]
141          * @return builder
142          */
<lambda>null143         fun setAppDestination(appDestination: Uri?): Builder = apply {
144             this.appDestination = appDestination
145         }
146 
147         /**
148          * Setter for web destination. It is the website {@link Uri} where corresponding conversion
149          * is expected. At least one of app destination or web destination is required.
150          *
151          * @param webDestination web destination [Uri]
152          * @return builder
153          */
<lambda>null154         fun setWebDestination(webDestination: Uri?): Builder = apply {
155             this.webDestination = webDestination
156         }
157 
158         /**
159          * Setter for verified destination.
160          *
161          * @param verifiedDestination verified destination
162          * @return builder
163          */
<lambda>null164         fun setVerifiedDestination(verifiedDestination: Uri?): Builder = apply {
165             this.verifiedDestination = verifiedDestination
166         }
167 
168         /** Pre-validates parameters and builds [WebSourceRegistrationRequest]. */
buildnull169         fun build(): WebSourceRegistrationRequest {
170             return WebSourceRegistrationRequest(
171                 webSourceParams,
172                 topOriginUri,
173                 inputEvent,
174                 appDestination,
175                 webDestination,
176                 verifiedDestination
177             )
178         }
179     }
180 }
181