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.webkit.WebView; 20 21 import androidx.annotation.IntDef; 22 import androidx.annotation.RequiresFeature; 23 import androidx.annotation.RestrictTo; 24 25 import org.chromium.support_lib_boundary.WebSettingsBoundaryInterface; 26 import org.jspecify.annotations.NonNull; 27 28 import java.lang.annotation.ElementType; 29 import java.lang.annotation.Retention; 30 import java.lang.annotation.RetentionPolicy; 31 import java.lang.annotation.Target; 32 import java.util.HashMap; 33 import java.util.Map; 34 import java.util.Set; 35 36 /** 37 * Configuration to set API enablement status for site origins through override rules. 38 * 39 * <p>Websites will follow the default status supplied in the builder constructor, 40 * unless the site origin matches one of the origin patterns supplied in the override rules. 41 * 42 * <p>The override rules are a map from origin patterns to the desired 43 * {@link WebViewMediaIntegrityApiStatus}. 44 */ 45 @RequiresFeature(name = WebViewFeature.WEBVIEW_MEDIA_INTEGRITY_API_STATUS, 46 enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported") 47 public class WebViewMediaIntegrityApiStatusConfig { 48 @Target(ElementType.TYPE_USE) 49 @IntDef({WEBVIEW_MEDIA_INTEGRITY_API_DISABLED, 50 WEBVIEW_MEDIA_INTEGRITY_API_ENABLED_WITHOUT_APP_IDENTITY, 51 WEBVIEW_MEDIA_INTEGRITY_API_ENABLED}) 52 @RestrictTo(RestrictTo.Scope.LIBRARY) 53 @Retention(RetentionPolicy.SOURCE) 54 @interface WebViewMediaIntegrityApiStatus { 55 } 56 57 /** 58 * Enables the WebView Media Integrity API and allows sharing of the app package name with 59 * the JavaScript caller. 60 * 61 * <p>This is the default value. 62 */ 63 public static final int WEBVIEW_MEDIA_INTEGRITY_API_ENABLED = 64 WebSettingsBoundaryInterface.WebViewMediaIntegrityApiStatus.ENABLED; 65 66 /** 67 * Enables the WebView Media Integrity API for JavaScript callers but disables sharing app 68 * package name in generated tokens. 69 */ 70 public static final int WEBVIEW_MEDIA_INTEGRITY_API_ENABLED_WITHOUT_APP_IDENTITY = 71 WebSettingsBoundaryInterface.WebViewMediaIntegrityApiStatus 72 .ENABLED_WITHOUT_APP_IDENTITY; 73 74 /** 75 * Disables the WebView Media Integrity API and causes it to return an 76 * error code to the JavaScript callers indicating that the app has disabled it. 77 */ 78 public static final int WEBVIEW_MEDIA_INTEGRITY_API_DISABLED = 79 WebSettingsBoundaryInterface.WebViewMediaIntegrityApiStatus.DISABLED; 80 81 private final @WebViewMediaIntegrityApiStatus int mDefaultStatus; 82 private final Map<String, @WebViewMediaIntegrityApiStatus Integer> mOverrideRules; 83 WebViewMediaIntegrityApiStatusConfig(@onNull Builder builder)84 public WebViewMediaIntegrityApiStatusConfig(@NonNull Builder builder) { 85 this.mDefaultStatus = builder.mDefaultStatus; 86 this.mOverrideRules = builder.mOverrideRules; 87 } 88 89 /** 90 * Builds a {@link WebViewMediaIntegrityApiStatusConfig} having a default API status and 91 * a map of origin pattern rules to their respective API status. 92 * 93 * <p> 94 * Example: 95 * <pre class="prettyprint"> 96 * // Create a config with default API status being DISABLED and API status is ENABLED for 97 * // Uris matching origin pattern "http://*.example.com" 98 * new WebViewMediaIntegrityApiStatusConfig.Builder(WEBVIEW_MEDIA_INTEGRITY_API_DISABLED) 99 * .addOverrideRule("http://*.example.com", WEBVIEW_MEDIA_INTEGRITY_API_ENABLED) 100 * .build(); 101 * </pre> 102 */ 103 public static final class Builder { 104 private final @WebViewMediaIntegrityApiStatus int mDefaultStatus; 105 private Map<String, @WebViewMediaIntegrityApiStatus Integer> mOverrideRules; 106 107 /** 108 * @param defaultStatus Default API status that will be used for URIs that don't match 109 * any origin pattern rule. 110 */ Builder(@ebViewMediaIntegrityApiStatus int defaultStatus)111 public Builder(@WebViewMediaIntegrityApiStatus int defaultStatus) { 112 this.mDefaultStatus = defaultStatus; 113 this.mOverrideRules = new HashMap<>(); 114 } 115 116 /** 117 * Add an override rule to set a specific API status for origin sites matching the origin 118 * pattern stated in the rule. Origin patterns should be supplied in the same format as 119 * those in 120 * {@link androidx.webkit.WebViewCompat.WebMessageListener#addWebMessageListener(WebView, String, Set, WebViewCompat.WebMessageListener)} 121 * 122 * If two or more origin patterns match a given origin site, the least permissive option 123 * will be chosen. 124 */ 125 addOverrideRule(@onNull String originPattern, @WebViewMediaIntegrityApiStatus int permission)126 public @NonNull Builder addOverrideRule(@NonNull String originPattern, 127 @WebViewMediaIntegrityApiStatus int permission) { 128 mOverrideRules.put(originPattern, permission); 129 return this; 130 } 131 132 /** 133 * Set all required override rules at once using a map of origin patterns to 134 * desired API statuses. This overwrites existing rules. 135 * <p> 136 * If two or more origin patterns match a given origin site, the least permissive option 137 * will be chosen. 138 * <p> 139 * This is only meant for internal use within the library. 140 */ 141 @RestrictTo(RestrictTo.Scope.LIBRARY) setOverrideRules(@onNull Map<String, @WebViewMediaIntegrityApiStatus Integer> overrideRules)142 public @NonNull Builder setOverrideRules(@NonNull Map<String, 143 @WebViewMediaIntegrityApiStatus Integer> overrideRules) { 144 mOverrideRules = overrideRules; 145 return this; 146 } 147 148 /** 149 * Build the config. 150 */ build()151 public @NonNull WebViewMediaIntegrityApiStatusConfig build() { 152 return new WebViewMediaIntegrityApiStatusConfig(this); 153 } 154 } 155 156 /** 157 * Returns the default value for origins that don't match any override rules. 158 */ getDefaultStatus()159 public @WebViewMediaIntegrityApiStatus int getDefaultStatus() { 160 return mDefaultStatus; 161 } 162 163 /** 164 * Get the explicitly set override rules. 165 * <p> This is a map from origin patterns to their desired WebView Media Integrity API statuses. 166 * 167 */ getOverrideRules()168 public @NonNull Map<String, @WebViewMediaIntegrityApiStatus Integer> getOverrideRules() { 169 return mOverrideRules; 170 } 171 } 172