1 /*
2  * Copyright 2025 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 androidx.annotation.IntRange;
20 
21 import org.jspecify.annotations.NonNull;
22 
23 /**
24  * Represents a configuration for speculative loading in a {@link Profile} instance. This should
25  * be set using {@link Profile#setSpeculativeLoadingConfig(SpeculativeLoadingConfig)}
26  */
27 @Profile.ExperimentalUrlPrefetch
28 public class SpeculativeLoadingConfig {
29 
30     private final int mPrefetchTTLSeconds;
31     private final int mMaxPrefetches;
32     private final int mMaxPrerenders;
33 
34     /**
35      * Private constructors, the application will need to use
36      * {@link Builder} for constructing instances of
37      * this class.
38      */
SpeculativeLoadingConfig(int ttlSecs, int maxPrefetches, int maxPrerenders)39     private SpeculativeLoadingConfig(int ttlSecs, int maxPrefetches, int maxPrerenders) {
40         mPrefetchTTLSeconds = ttlSecs;
41         mMaxPrefetches = maxPrefetches;
42         mMaxPrerenders = maxPrerenders;
43     }
44 
45     /**
46      * The "time to live" for a prefetch inside of the prefetch cache.
47      * This is representative of the maximum time that a prefetch is considered
48      * valid and can be served to a navigation. WebView will choose the appropriate default value.
49      */
50     @IntRange(from = 1)
getPrefetchTtlSeconds()51     public int getPrefetchTtlSeconds() {
52         return mPrefetchTTLSeconds;
53     }
54 
55     /**
56      * The max amount of prefetches that can live in the cache. WebView will choose the
57      * appropriate default value.
58      */
59     @IntRange(from = 1)
getMaxPrefetches()60     public int getMaxPrefetches() {
61         return mMaxPrefetches;
62     }
63 
64     /**
65      * The max amount of prerenders that can live in the cache of any WebView associated with
66      * this {@link Profile}. WebView will choose the appropriate default value.
67      */
68     @IntRange(from = 1)
69     @Profile.ExperimentalUrlPrefetch
getMaxPrerenders()70     public int getMaxPrerenders() {
71         return mMaxPrerenders;
72     }
73 
74     @Profile.ExperimentalUrlPrefetch
75     public static final class Builder {
76         private int mPrefetchTTLSeconds;
77         private int mMaxPrefetches;
78         private int mMaxPrerenders;
79 
Builder()80         public Builder() {
81         }
82 
83         /**
84          * Sets the Time-to-Live (TTL) in seconds for prefetched data.
85          * <p>
86          * This value determines how long prefetched data will be considered valid before it is
87          * refreshed.
88          *
89          * @param ttlSeconds The TTL value in seconds. Must be a positive integer.
90          * @return This builder instance for method chaining.
91          * @throws IllegalArgumentException If {@code ttlSeconds} is less than 1.
92          * @see Builder#build()
93          */
94         @NonNull
setPrefetchTtlSeconds(@ntRangefrom = 1) int ttlSeconds)95         public Builder setPrefetchTtlSeconds(@IntRange(from = 1) int ttlSeconds) {
96             if (ttlSeconds <= 0) {
97                 throw new IllegalArgumentException("Prefetch TTL must be greater than 0");
98             }
99             mPrefetchTTLSeconds = ttlSeconds;
100             return this;
101         }
102 
103         /**
104          * Sets the maximum number of allowed prefetches. This value limits the number of
105          * prefetch data that can live in the cache. The WebView's internal maximum limit may
106          * override this value.
107          *
108          * @param max The maximum number of prefetches. Must be a positive integer.
109          * @return This builder instance for method chaining.
110          * @throws IllegalArgumentException If {@code max} is less than 1.
111          * @see Builder#build()
112          */
113         @NonNull
setMaxPrefetches(@ntRangefrom = 1) int max)114         public Builder setMaxPrefetches(@IntRange(from = 1) int max) {
115             if (max < 1) {
116                 throw new IllegalArgumentException("Max prefetches must be greater than 0");
117             }
118             mMaxPrefetches = max;
119             return this;
120         }
121 
122         /**
123          * Sets the maximum number of allowed prerenders. The WebView's internal maximum limit
124          * may override this value.
125          *
126          * @param max The maximum number of prerenders. Must be a positive integer.
127          * @return This builder instance for method chaining.
128          * @throws IllegalArgumentException If {@code max} is less than 1.
129          * @see Builder#build()
130          */
131         @NonNull
setMaxPrerenders(@ntRangefrom = 1) int max)132         public Builder setMaxPrerenders(@IntRange(from = 1) int max) {
133             if (max < 1) {
134                 throw new IllegalArgumentException("Max prerenders must be greater than 0");
135             }
136             mMaxPrerenders = max;
137             return this;
138         }
139 
140         /**
141          * Builds a new {@link SpeculativeLoadingConfig} instance.
142          * <p>
143          * This method creates a new {@link SpeculativeLoadingConfig} object using the parameters
144          * that have been set in this builder.
145          *
146          * @return A new {@link SpeculativeLoadingConfig} instance.
147          */
148         @Profile.ExperimentalUrlPrefetch
149         @NonNull
build()150         public SpeculativeLoadingConfig build() {
151             return new SpeculativeLoadingConfig(mPrefetchTTLSeconds, mMaxPrefetches,
152                     mMaxPrerenders);
153         }
154     }
155 }
156