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.tests.providers.sdkmeasurement;
18 
19 import android.adservices.clients.measurement.MeasurementClient;
20 import android.adservices.measurement.DeletionRequest;
21 import android.adservices.measurement.WebSourceParams;
22 import android.adservices.measurement.WebSourceRegistrationRequest;
23 import android.adservices.measurement.WebTriggerParams;
24 import android.adservices.measurement.WebTriggerRegistrationRequest;
25 import android.app.sdksandbox.LoadSdkException;
26 import android.app.sdksandbox.SandboxedSdk;
27 import android.app.sdksandbox.SandboxedSdkProvider;
28 import android.content.Context;
29 import android.net.Uri;
30 import android.os.Binder;
31 import android.os.Bundle;
32 import android.util.Log;
33 import android.view.View;
34 
35 import androidx.annotation.NonNull;
36 
37 import com.android.adservices.common.WebUtil;
38 import com.android.compatibility.common.util.TestUtils;
39 
40 import java.time.Instant;
41 import java.util.Collections;
42 import java.util.concurrent.Executor;
43 import java.util.concurrent.Executors;
44 
45 public class SdkMeasurement extends SandboxedSdkProvider {
46     private static final String TAG = "SdkMeasurement";
47     private static final Executor CALLBACK_EXECUTOR = Executors.newCachedThreadPool();
48     private static final Uri SOURCE_REGISTRATION_URI = WebUtil.validUri("https://test.test/source");
49     private static final Uri TRIGGER_REGISTRATION_URI =
50             WebUtil.validUri("https://test.test/trigger");
51     private static final Uri DESTINATION = WebUtil.validUri("http://destination.test");
52     private static final Uri OS_DESTINATION = Uri.parse("android-app://os.destination");
53     private static final Uri WEB_DESTINATION = WebUtil.validUri("http://web-destination.test");
54     private static final Uri ORIGIN_URI = WebUtil.validUri("http://origin-uri.test");
55     private static final Uri DOMAIN_URI = WebUtil.validUri("http://domain-uri.test");
56 
57     private MeasurementClient mMeasurementClient;
58 
59     @Override
onLoadSdk(Bundle params)60     public SandboxedSdk onLoadSdk(Bundle params) throws LoadSdkException {
61         try {
62             setup();
63         } catch (Exception e) {
64             final String errorMessage = "Error setting up SdkMeasurement: " + e.getMessage();
65             Log.e(TAG, errorMessage);
66             throw new LoadSdkException(e, new Bundle());
67         }
68 
69         execute(
70                 "registerSource",
71                 () ->
72                         mMeasurementClient
73                                 .registerSource(SOURCE_REGISTRATION_URI, /* inputEvent = */ null)
74                                 .get());
75 
76         execute(
77                 "registerTrigger",
78                 () -> mMeasurementClient.registerTrigger(TRIGGER_REGISTRATION_URI).get());
79 
80         execute(
81                 "registerWebSource",
82                 () ->
83                         mMeasurementClient
84                                 .registerWebSource(buildDefaultWebSourceRegistrationRequest())
85                                 .get());
86 
87         execute(
88                 "registerWebTrigger",
89                 () ->
90                         mMeasurementClient
91                                 .registerWebTrigger(buildDefaultWebTriggerRegistrationRequest())
92                                 .get());
93 
94         execute(
95                 "deleteRegistrations",
96                 () ->
97                         mMeasurementClient
98                                 .deleteRegistrations(
99                                         new DeletionRequest.Builder()
100                                                 .setOriginUris(
101                                                         Collections.singletonList(ORIGIN_URI))
102                                                 .setDomainUris(
103                                                         Collections.singletonList(DOMAIN_URI))
104                                                 .setStart(Instant.ofEpochMilli(0))
105                                                 .setEnd(Instant.now())
106                                                 .build())
107                                 .get());
108 
109         // If we got this far, that means the test succeeded
110         return new SandboxedSdk(new Binder());
111     }
112 
113     @Override
getView( @onNull Context windowContext, @NonNull Bundle params, int width, int height)114     public View getView(
115             @NonNull Context windowContext, @NonNull Bundle params, int width, int height) {
116         return null;
117     }
118 
setup()119     private void setup() {
120         mMeasurementClient =
121                 new MeasurementClient.Builder()
122                         .setContext(getContext())
123                         .setExecutor(CALLBACK_EXECUTOR)
124                         .build();
125     }
126 
execute(String apiName, TestUtils.RunnableWithThrow executable)127     private void execute(String apiName, TestUtils.RunnableWithThrow executable)
128             throws LoadSdkException {
129         try {
130             executable.run();
131         } catch (Exception e) {
132             final String errorMessage = String.format("Error in %s: %s", apiName, e.getMessage());
133             Log.e(TAG, errorMessage);
134             throw new LoadSdkException(e, new Bundle());
135         }
136     }
137 
buildDefaultWebSourceRegistrationRequest()138     private WebSourceRegistrationRequest buildDefaultWebSourceRegistrationRequest() {
139         WebSourceParams webSourceParams =
140                 new WebSourceParams.Builder(SOURCE_REGISTRATION_URI)
141                         .setDebugKeyAllowed(false)
142                         .build();
143 
144         return new WebSourceRegistrationRequest.Builder(
145                         Collections.singletonList(webSourceParams), SOURCE_REGISTRATION_URI)
146                 .setInputEvent(null)
147                 .setAppDestination(OS_DESTINATION)
148                 .setWebDestination(WEB_DESTINATION)
149                 .setVerifiedDestination(null)
150                 .build();
151     }
152 
buildDefaultWebTriggerRegistrationRequest()153     private WebTriggerRegistrationRequest buildDefaultWebTriggerRegistrationRequest() {
154         WebTriggerParams webTriggerParams =
155                 new WebTriggerParams.Builder(TRIGGER_REGISTRATION_URI).build();
156 
157         return new WebTriggerRegistrationRequest.Builder(
158                         Collections.singletonList(webTriggerParams), DESTINATION)
159                 .build();
160     }
161 }
162