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 
17 package android.adservices.ondevicepersonalization;
18 
19 import android.annotation.FlaggedApi;
20 import android.annotation.NonNull;
21 import android.os.OutcomeReceiver;
22 
23 import com.android.adservices.ondevicepersonalization.flags.Flags;
24 
25 /**
26  * Interface with methods that need to be implemented to handle requests from the
27  * OnDevicePersonalization service to an {@link IsolatedService}. The {@link IsolatedService}
28  * creates an instance of {@link IsolatedWorker} on each request and calls one of the methods
29  * below, depending the type of the request. The {@link IsolatedService} calls the method on a
30  * Binder thread and the {@link IsolatedWorker} should offload long running operations to a
31  * worker thread. The {@link IsolatedWorker} should use the {@code receiver} parameter of each
32  * method to return results. If any of these methods throws a {@link RuntimeException}, the
33  * platform treats it as an unrecoverable error in the {@link IsolatedService} and ends processing
34  * the request.
35  */
36 @FlaggedApi(Flags.FLAG_ON_DEVICE_PERSONALIZATION_APIS_ENABLED)
37 public interface IsolatedWorker {
38 
39     /**
40      * Handles a request from an app. This method is called when an app calls {@code
41      * OnDevicePersonalizationManager#execute(ComponentName, PersistableBundle,
42      * java.util.concurrent.Executor, OutcomeReceiver)} that refers to a named
43      * {@link IsolatedService}.
44      *
45      * @param input Request Parameters from the calling app.
46      * @param receiver Callback that receives the result {@link ExecuteOutput} or an
47      *     {@link IsolatedServiceException}. If this method throws a {@link RuntimeException} or
48      *     returns either {@code null} or {@link IsolatedServiceException}, the error is indicated
49      *     to the calling app as an {@link OnDevicePersonalizationException} with error code
50      *     {@link OnDevicePersonalizationException#ERROR_ISOLATED_SERVICE_FAILED}. To avoid leaking
51      *     private data to the calling app, more detailed errors are not reported to the caller.
52      *     If the {@link IsolatedService} needs to report additional data beyond the error code to
53      *     its backend servers, it should populate the logging fields in {@link ExecuteOutput} with
54      *     the additional error data for logging, and rely on Federated Analytics for the stats.
55      */
onExecute( @onNull ExecuteInput input, @NonNull OutcomeReceiver<ExecuteOutput, IsolatedServiceException> receiver)56     default void onExecute(
57             @NonNull ExecuteInput input,
58             @NonNull OutcomeReceiver<ExecuteOutput, IsolatedServiceException> receiver) {
59         receiver.onResult(new ExecuteOutput.Builder().build());
60     }
61 
62     /**
63      * Handles a completed download. The platform downloads content using the parameters defined in
64      * the package manifest of the {@link IsolatedService}, calls this function after the download
65      * is complete, and updates the REMOTE_DATA table from
66      * {@link IsolatedService#getRemoteData(RequestToken)} with the result of this method.
67      *
68      * @param input Download handler parameters.
69      * @param receiver Callback that receives the result {@link DownloadCompletedOutput} or an
70      *     {@link IsolatedServiceException}.
71      *     <p>If this method returns a {@code null} result or exception via the callback, or
72      *     throws a {@link RuntimeException}, no updates are made to the REMOTE_DATA table.
73      */
onDownloadCompleted( @onNull DownloadCompletedInput input, @NonNull OutcomeReceiver<DownloadCompletedOutput, IsolatedServiceException> receiver)74     default void onDownloadCompleted(
75             @NonNull DownloadCompletedInput input,
76             @NonNull OutcomeReceiver<DownloadCompletedOutput, IsolatedServiceException> receiver) {
77         receiver.onResult(new DownloadCompletedOutput.Builder().build());
78     }
79 
80     /**
81      * Generates HTML for the results that were returned as a result of
82      * {@link #onExecute(ExecuteInput, android.os.OutcomeReceiver)}. Called when a client app calls
83      * {@link OnDevicePersonalizationManager#requestSurfacePackage(SurfacePackageToken, IBinder, int, int, int, java.util.concurrent.Executor, OutcomeReceiver)}.
84      * The platform will render this HTML in an {@link android.webkit.WebView} inside a fenced
85      * frame.
86      *
87      * @param input Parameters for the render request.
88      * @param receiver Callback that receives the result {@link RenderOutput} or an
89      *     {@link IsolatedServiceException}.
90      *     <p>If this method returns a {@code null} result or exception via the callback, or
91      *     throws a {@link RuntimeException}, the error is also reported to calling
92      *     apps as an {@link OnDevicePersonalizationException} with error code {@link
93      *     OnDevicePersonalizationException#ERROR_ISOLATED_SERVICE_FAILED}.
94      */
onRender( @onNull RenderInput input, @NonNull OutcomeReceiver<RenderOutput, IsolatedServiceException> receiver)95     default void onRender(
96             @NonNull RenderInput input,
97             @NonNull OutcomeReceiver<RenderOutput, IsolatedServiceException> receiver) {
98         receiver.onResult(new RenderOutput.Builder().build());
99     }
100 
101     /**
102      * Handles an event triggered by a request to a platform-provided tracking URL {@link
103      * EventUrlProvider} that was embedded in the HTML output returned by
104      * {@link #onRender(RenderInput, android.os.OutcomeReceiver)}. The platform updates the EVENTS table with
105      * {@link EventOutput#getEventLogRecord()}.
106      *
107      * @param input The parameters needed to compute event data.
108      * @param receiver Callback that receives the result {@link EventOutput} or an
109      *     {@link IsolatedServiceException}.
110      *     <p>If this method returns a {@code null} result or exception via the callback, or
111      *     throws a {@link RuntimeException}, no data is written to the EVENTS table.
112      */
onEvent( @onNull EventInput input, @NonNull OutcomeReceiver<EventOutput, IsolatedServiceException> receiver)113     default void onEvent(
114             @NonNull EventInput input,
115             @NonNull OutcomeReceiver<EventOutput, IsolatedServiceException> receiver) {
116         receiver.onResult(new EventOutput.Builder().build());
117     }
118 
119     /**
120      * Generate a list of training examples used for federated compute job. The platform will call
121      * this function when a federated compute job starts. The federated compute job is scheduled by
122      * an app through {@link FederatedComputeScheduler#schedule}.
123      *
124      * @param input The parameters needed to generate the training example.
125      * @param receiver Callback that receives the result {@link TrainingExamplesOutput} or an
126      *     {@link IsolatedServiceException}.
127      *     <p>If this method returns a {@code null} result or exception via the callback, or
128      *     throws a {@link RuntimeException}, no training examples is produced for this
129      *     training session.
130      */
onTrainingExamples( @onNull TrainingExamplesInput input, @NonNull OutcomeReceiver<TrainingExamplesOutput, IsolatedServiceException> receiver)131     default void onTrainingExamples(
132             @NonNull TrainingExamplesInput input,
133             @NonNull OutcomeReceiver<TrainingExamplesOutput, IsolatedServiceException> receiver) {
134         receiver.onResult(new TrainingExamplesOutput.Builder().build());
135     }
136 
137     /**
138      * Handles a Web Trigger event from a browser. A Web Trigger event occurs when a browser
139      * registers a web trigger event with the OS using the <a href="https://github.com/WICG/attribution-reporting-api">
140      * Attribution and Reporting API</a>. If the data in the web trigger payload indicates that the
141      * event should be forwarded to an {@link IsolatedService}, the platform will call this function
142      * with the web trigger data.
143      *
144      * @param input The parameters needed to process Web Trigger event.
145      * @param receiver Callback that receives the result {@link WebTriggerOutput} or an
146      *     {@link IsolatedServiceException}. Should be called with a
147      *     {@link WebTriggerOutput} object populated with a set of records to be written to the
148      *     REQUESTS or EVENTS tables.
149      *     <p>If this method returns a {@code null} result or exception via the callback, or
150      *     throws a {@link RuntimeException}, no data is written to the REQUESTS orEVENTS tables.
151      */
onWebTrigger( @onNull WebTriggerInput input, @NonNull OutcomeReceiver<WebTriggerOutput, IsolatedServiceException> receiver)152     default void onWebTrigger(
153             @NonNull WebTriggerInput input,
154             @NonNull OutcomeReceiver<WebTriggerOutput, IsolatedServiceException> receiver) {
155         receiver.onResult(new WebTriggerOutput.Builder().build());
156     }
157 }
158