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.test;
18 
19 import android.adservices.ondevicepersonalization.DownloadCompletedInput;
20 import android.adservices.ondevicepersonalization.DownloadCompletedOutput;
21 import android.adservices.ondevicepersonalization.EventInput;
22 import android.adservices.ondevicepersonalization.EventLogRecord;
23 import android.adservices.ondevicepersonalization.EventOutput;
24 import android.adservices.ondevicepersonalization.ExecuteInput;
25 import android.adservices.ondevicepersonalization.ExecuteOutput;
26 import android.adservices.ondevicepersonalization.IsolatedServiceException;
27 import android.adservices.ondevicepersonalization.IsolatedWorker;
28 import android.adservices.ondevicepersonalization.KeyValueStore;
29 import android.adservices.ondevicepersonalization.RenderInput;
30 import android.adservices.ondevicepersonalization.RenderOutput;
31 import android.adservices.ondevicepersonalization.RenderingConfig;
32 import android.adservices.ondevicepersonalization.RequestLogRecord;
33 import android.adservices.ondevicepersonalization.TrainingExampleRecord;
34 import android.adservices.ondevicepersonalization.TrainingExamplesInput;
35 import android.adservices.ondevicepersonalization.TrainingExamplesOutput;
36 import android.adservices.ondevicepersonalization.WebTriggerInput;
37 import android.adservices.ondevicepersonalization.WebTriggerOutput;
38 import android.annotation.NonNull;
39 import android.content.ContentValues;
40 import android.os.OutcomeReceiver;
41 import android.util.Log;
42 
43 import java.util.ArrayList;
44 import java.util.Arrays;
45 import java.util.List;
46 import java.util.Objects;
47 import java.util.Set;
48 
49 // TODO(b/249345663) Move this class and related manifest to separate APK for more realistic testing
50 public class TestPersonalizationHandler implements IsolatedWorker {
51     public final String TAG = "TestPersonalizationHandler";
52     private final KeyValueStore mRemoteData;
53 
TestPersonalizationHandler(KeyValueStore remoteData)54     TestPersonalizationHandler(KeyValueStore remoteData) {
55         mRemoteData = remoteData;
56     }
57 
58     @Override
onDownloadCompleted( DownloadCompletedInput input, OutcomeReceiver<DownloadCompletedOutput, IsolatedServiceException> receiver)59     public void onDownloadCompleted(
60             DownloadCompletedInput input,
61             OutcomeReceiver<DownloadCompletedOutput, IsolatedServiceException> receiver) {
62         try {
63             Log.d(TAG, "Starting filterData.");
64             Log.d(TAG, "Data keys: " + input.getDownloadedContents().keySet());
65 
66             Log.d(TAG, "Existing keyExtra: " + Arrays.toString(mRemoteData.get("keyExtra")));
67             Log.d(TAG, "Existing keySet: " + mRemoteData.keySet());
68 
69             List<String> keysToRetain = getFilteredKeys(input.getDownloadedContents());
70             keysToRetain.add("keyExtra");
71             // Get the keys to keep from the downloaded data
72             DownloadCompletedOutput result =
73                     new DownloadCompletedOutput.Builder().setRetainedKeys(keysToRetain).build();
74             receiver.onResult(result);
75         } catch (Exception e) {
76             Log.e(TAG, "Error occurred in onDownload", e);
77         }
78     }
79 
80     @Override
onExecute( @onNull ExecuteInput input, @NonNull OutcomeReceiver<ExecuteOutput, IsolatedServiceException> receiver)81     public void onExecute(
82             @NonNull ExecuteInput input,
83             @NonNull OutcomeReceiver<ExecuteOutput, IsolatedServiceException> receiver) {
84         Log.d(TAG, "onExecute() started.");
85         ContentValues logData = new ContentValues();
86         logData.put("id", "bid1");
87         logData.put("pr", 5.0);
88         ExecuteOutput result =
89                 new ExecuteOutput.Builder()
90                         .setRequestLogRecord(new RequestLogRecord.Builder().addRow(logData).build())
91                         .setRenderingConfig(new RenderingConfig.Builder().addKey("bid1").build())
92                         .addEventLogRecord(
93                                 new EventLogRecord.Builder()
94                                         .setData(logData)
95                                         .setRequestLogRecord(
96                                                 new RequestLogRecord.Builder()
97                                                         .addRow(logData)
98                                                         .addRow(logData)
99                                                         .setRequestId(1)
100                                                         .build())
101                                         .setType(1)
102                                         .setRowIndex(1)
103                                         .build())
104                         .setOutputData(new byte[] {1, 2, 3})
105                         .build();
106         receiver.onResult(result);
107     }
108 
109     @Override
onRender( @onNull RenderInput input, @NonNull OutcomeReceiver<RenderOutput, IsolatedServiceException> receiver)110     public void onRender(
111             @NonNull RenderInput input,
112             @NonNull OutcomeReceiver<RenderOutput, IsolatedServiceException> receiver) {
113         Log.d(TAG, "onRender() started.");
114         RenderOutput result =
115                 new RenderOutput.Builder()
116                         .setContent(
117                                 "<p>RenderResult: "
118                                         + String.join(",", input.getRenderingConfig().getKeys())
119                                         + "<p>")
120                         .build();
121         receiver.onResult(result);
122     }
123 
124     @Override
onEvent( @onNull EventInput input, @NonNull OutcomeReceiver<EventOutput, IsolatedServiceException> receiver)125     public void onEvent(
126             @NonNull EventInput input,
127             @NonNull OutcomeReceiver<EventOutput, IsolatedServiceException> receiver) {
128         Log.d(TAG, "onEvent() started.");
129         long longValue = 0;
130         if (input.getParameters() != null) {
131             longValue = input.getParameters().getLong("x");
132         }
133         ContentValues logData = new ContentValues();
134         logData.put("x", longValue);
135         EventOutput result =
136                 new EventOutput.Builder()
137                         .setEventLogRecord(
138                                 new EventLogRecord.Builder()
139                                         .setType(1)
140                                         .setRowIndex(0)
141                                         .setData(logData)
142                                         .build())
143                         .build();
144         Log.d(TAG, "onEvent() result: " + result.toString());
145         receiver.onResult(result);
146     }
147 
getFilteredKeys(KeyValueStore data)148     private List<String> getFilteredKeys(KeyValueStore data) {
149         Set<String> filteredKeys = data.keySet();
150         Log.d(TAG, "key3 size: " + Objects.requireNonNull(data.get("key3")).length);
151         filteredKeys.remove("key3");
152         return new ArrayList<>(filteredKeys);
153     }
154 
155     @Override
onTrainingExamples( @onNull TrainingExamplesInput input, @NonNull OutcomeReceiver<TrainingExamplesOutput, IsolatedServiceException> receiver)156     public void onTrainingExamples(
157             @NonNull TrainingExamplesInput input,
158             @NonNull OutcomeReceiver<TrainingExamplesOutput, IsolatedServiceException> receiver) {
159         Log.d(TAG, "onTrainingExamples() started.");
160         Log.d(TAG, "Population name: " + input.getPopulationName());
161         Log.d(TAG, "Task name: " + input.getTaskName());
162 
163         List<TrainingExampleRecord> exampleRecordList = new ArrayList<>();
164         TrainingExampleRecord record1 =
165                 new TrainingExampleRecord.Builder()
166                         .setTrainingExample(new byte[] {10})
167                         .setResumptionToken("token1".getBytes())
168                         .build();
169         TrainingExampleRecord record2 =
170                 new TrainingExampleRecord.Builder()
171                         .setTrainingExample(new byte[] {20})
172                         .setResumptionToken("token2".getBytes())
173                         .build();
174         exampleRecordList.add(record1);
175         exampleRecordList.add(record2);
176 
177         TrainingExamplesOutput output =
178                 new TrainingExamplesOutput.Builder()
179                         .setTrainingExampleRecords(exampleRecordList)
180                         .build();
181         receiver.onResult(output);
182     }
183 
184     @Override
onWebTrigger( @onNull WebTriggerInput input, @NonNull OutcomeReceiver<WebTriggerOutput, IsolatedServiceException> receiver)185     public void onWebTrigger(
186             @NonNull WebTriggerInput input,
187             @NonNull OutcomeReceiver<WebTriggerOutput, IsolatedServiceException> receiver) {
188         Log.d(TAG, "onWebTrigger() started.");
189         ContentValues logData = new ContentValues();
190         logData.put("id", "trig1");
191         logData.put("val", 10.0);
192         WebTriggerOutput output =
193                 new WebTriggerOutput.Builder()
194                         .addEventLogRecord(
195                                 new EventLogRecord.Builder()
196                                         .setData(logData)
197                                         .setRequestLogRecord(
198                                                 new RequestLogRecord.Builder()
199                                                         .addRow(logData)
200                                                         .addRow(logData)
201                                                         .setRequestId(1)
202                                                         .build())
203                                         .setType(10)
204                                         .setRowIndex(1)
205                                         .build())
206                         .build();
207         receiver.onResult(output);
208     }
209 }
210