1 /*
2  * Copyright 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 androidx.webkit;
18 
19 import android.os.CancellationSignal;
20 import android.webkit.CookieManager;
21 import android.webkit.GeolocationPermissions;
22 import android.webkit.ServiceWorkerController;
23 import android.webkit.WebStorage;
24 
25 import androidx.annotation.AnyThread;
26 import androidx.annotation.RequiresFeature;
27 import androidx.annotation.RequiresOptIn;
28 import androidx.annotation.UiThread;
29 
30 import org.jspecify.annotations.NonNull;
31 import org.jspecify.annotations.Nullable;
32 
33 import java.lang.annotation.ElementType;
34 import java.lang.annotation.Retention;
35 import java.lang.annotation.RetentionPolicy;
36 import java.lang.annotation.Target;
37 import java.util.Map;
38 import java.util.concurrent.Executor;
39 
40 /**
41  * A Profile represents one browsing session for WebView.
42  * <p> You can have multiple profiles and each profile holds its own set of data. The creation
43  * and deletion of the Profile is being managed by {@link ProfileStore}.
44  */
45 public interface Profile {
46 
47     /**
48      * Represents the name of the default profile which can't be deleted.
49      */
50     String DEFAULT_PROFILE_NAME = "Default";
51 
52     /**
53      * @return the name of this Profile which was used to create the Profile from
54      * ProfileStore create methods.
55      */
56     @AnyThread
57     @RequiresFeature(name = WebViewFeature.MULTI_PROFILE,
58             enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
59     @NonNull
getName()60     String getName();
61 
62     /**
63      * Returns the profile's cookie manager.
64      * <p>
65      * Can be called from any thread.
66      *
67      * @throws IllegalStateException if the profile has been deleted by
68      *                               {@link ProfileStore#deleteProfile(String)}}.
69      */
70     @AnyThread
71     @RequiresFeature(name = WebViewFeature.MULTI_PROFILE,
72             enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
73     @NonNull
getCookieManager()74     CookieManager getCookieManager();
75 
76     /**
77      * Returns the profile's web storage.
78      * <p>
79      * Can be called from any thread.
80      *
81      * @throws IllegalStateException if the profile has been deleted by
82      *                               {@link ProfileStore#deleteProfile(String)}}.
83      */
84     @AnyThread
85     @RequiresFeature(name = WebViewFeature.MULTI_PROFILE,
86             enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
87     @NonNull
getWebStorage()88     WebStorage getWebStorage();
89 
90     /**
91      * Returns the geolocation permissions of the profile.
92      * <p>
93      * Can be called from any thread.
94      *
95      * @throws IllegalStateException if the profile has been deleted by
96      *                               {@link ProfileStore#deleteProfile(String)}}.
97      */
98     @AnyThread
99     @RequiresFeature(name = WebViewFeature.MULTI_PROFILE,
100             enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
101     @NonNull
getGeolocationPermissions()102     GeolocationPermissions getGeolocationPermissions();
103 
104     /**
105      * Returns the service worker controller of the profile.
106      * <p>
107      * Can be called from any thread.
108      *
109      * @throws IllegalStateException if the profile has been deleted by
110      *                               {@link ProfileStore#deleteProfile(String)}}.
111      */
112     @AnyThread
113     @RequiresFeature(name = WebViewFeature.MULTI_PROFILE,
114             enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
115     @NonNull
getServiceWorkerController()116     ServiceWorkerController getServiceWorkerController();
117 
118     /**
119      * Denotes that the UrlPrefetch API surface is experimental.
120      * It may change without warning.
121      */
122     @Retention(RetentionPolicy.CLASS)
123     @Target({ElementType.METHOD, ElementType.TYPE, ElementType.FIELD})
124     @RequiresOptIn(level = RequiresOptIn.Level.ERROR)
125     @interface ExperimentalUrlPrefetch {
126     }
127 
128     /**
129      * Starts a URL prefetch request. Must be called from the UI thread.
130      * <p>
131      * All WebViews associated with this Profile will use a URL request
132      * matching algorithm during execution of all variants of
133      * {@link android.webkit.WebView#loadUrl(String)} for determining if there
134      * was already a prefetch request executed for the provided URL. This
135      * includes prefetches that are "in progress". If a prefetch is matched,
136      * WebView will leverage that for handling the URL, otherwise the URL
137      * will be handled normally (i.e. through a network request).
138      * <p>
139      * Applications will still be responsible for calling
140      * {@link android.webkit.WebView#loadUrl(String)} to display web contents
141      * in a WebView.
142      * <p>
143      * NOTE: Additional headers passed to
144      * {@link android.webkit.WebView#loadUrl(String, Map)} are not considered
145      * in the matching algorithm for determining whether or not to serve a
146      * prefetched response to a navigation.
147      * <p>
148      * For max latency saving benefits, it is recommended to call this method
149      * as early as possible (i.e. before any WebView associated with this
150      * profile is created).
151      * <p>
152      * Only supports HTTPS scheme.
153      *
154      * @param url                the url associated with the prefetch request.
155      * @param cancellationSignal will make the best effort to cancel an
156      *                           in-flight prefetch request, However cancellation is not
157      *                           guaranteed.
158      * @param callbackExecutor   the executor to resolve the callback with.
159      * @param operationCallback  callbacks for reporting result back to application.
160      * @throws IllegalArgumentException if the url or callback is null.
161      */
162     @RequiresFeature(name = WebViewFeature.PROFILE_URL_PREFETCH,
163             enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
164     @UiThread
165     @ExperimentalUrlPrefetch
prefetchUrlAsync(@onNull String url, @Nullable CancellationSignal cancellationSignal, @NonNull Executor callbackExecutor, @NonNull OutcomeReceiverCompat<Void, PrefetchException> operationCallback)166     void prefetchUrlAsync(@NonNull String url,
167             @Nullable CancellationSignal cancellationSignal,
168             @NonNull Executor callbackExecutor,
169             @NonNull OutcomeReceiverCompat<Void, PrefetchException> operationCallback);
170 
171     /**
172      * Starts a URL prefetch request. Must be called from the UI thread.
173      * <p>
174      * All WebViews associated with this Profile will use a URL request
175      * matching algorithm during execution of all variants of
176      * {@link android.webkit.WebView#loadUrl(String)} for determining if there
177      * was already a prefetch request executed for the provided URL. This
178      * includes prefetches that are "in progress". If a prefetch is matched,
179      * WebView will leverage that for handling the URL, otherwise the URL
180      * will be handled normally (i.e. through a network request).
181      * <p>
182      * Applications will still be responsible for calling
183      * {@link android.webkit.WebView#loadUrl(String)} to display web contents
184      * in a WebView.
185      * <p>
186      * NOTE: Additional headers passed to
187      * {@link android.webkit.WebView#loadUrl(String, Map)} are not considered
188      * in the matching algorithm for determining whether or not to serve a
189      * prefetched response to a navigation.
190      * <p>
191      * For max latency saving benefits, it is recommended to call this method
192      * as early as possible (i.e. before any WebView associated with this
193      * profile is created).
194      * <p>
195      * Only supports HTTPS scheme.
196      *
197      * @param url                          the url associated with the prefetch request.
198      * @param cancellationSignal           will make the best effort to cancel an
199      *                                     in-flight prefetch request, However cancellation is not
200      *                                     guaranteed.
201      * @param callbackExecutor             the executor to resolve the callback with.
202      * @param speculativeLoadingParameters parameters to customize the prefetch request.
203      * @param operationCallback            callbacks for reporting result back to application.
204      * @throws IllegalArgumentException if the url or callback is null.
205      */
206     @RequiresFeature(name = WebViewFeature.PROFILE_URL_PREFETCH,
207             enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
208     @UiThread
209     @ExperimentalUrlPrefetch
prefetchUrlAsync(@onNull String url, @Nullable CancellationSignal cancellationSignal, @NonNull Executor callbackExecutor, @NonNull SpeculativeLoadingParameters speculativeLoadingParameters, @NonNull OutcomeReceiverCompat<Void, PrefetchException> operationCallback)210     void prefetchUrlAsync(@NonNull String url,
211             @Nullable CancellationSignal cancellationSignal,
212             @NonNull Executor callbackExecutor,
213             @NonNull SpeculativeLoadingParameters speculativeLoadingParameters,
214             @NonNull OutcomeReceiverCompat<Void, PrefetchException> operationCallback);
215 
216     /**
217      * Removes a cached prefetch response for the provided url
218      * if it exists, otherwise does nothing.
219      * <p>
220      * Calling this does not guarantee that the prefetched response will
221      * not be served to a WebView before it is cleared.
222      * <p>
223      *
224      * @param url               the url associated with the prefetch request. Should be
225      *                          an exact match with the URL passed to {@link #prefetchUrlAsync}.
226      * @param callbackExecutor  the executor to resolve the callback with.
227      * @param operationCallback runs when the clear operation is complete Or and error occurred
228      *                          during it.
229      * @throws IllegalArgumentException if the url or callback is null.
230      */
231     @RequiresFeature(name = WebViewFeature.PROFILE_URL_PREFETCH,
232             enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
233     @UiThread
234     @ExperimentalUrlPrefetch
clearPrefetchAsync(@onNull String url, @NonNull Executor callbackExecutor, @NonNull OutcomeReceiverCompat<Void, PrefetchException> operationCallback)235     void clearPrefetchAsync(@NonNull String url,
236             @NonNull Executor callbackExecutor,
237             @NonNull OutcomeReceiverCompat<Void, PrefetchException> operationCallback);
238 
239     /**
240      * Sets the {@link SpeculativeLoadingConfig} for the current profile session.
241      * These configurations will be applied to any Prefetch requests made after they are set;
242      * they will not be applied to in-flight requests.
243      * <p>
244      * These configurations will be applied to any prefetch requests initiated by
245      * a prerender request. This applies specifically to WebViews that are
246      * associated with this Profile.
247      * <p>
248      * @param speculativeLoadingConfig the config to set for this profile session.
249      */
250     @RequiresFeature(name = WebViewFeature.SPECULATIVE_LOADING_CONFIG,
251             enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
252     @UiThread
253     @ExperimentalUrlPrefetch
setSpeculativeLoadingConfig(@onNull SpeculativeLoadingConfig speculativeLoadingConfig)254     void setSpeculativeLoadingConfig(@NonNull SpeculativeLoadingConfig
255             speculativeLoadingConfig);
256 
257 }
258