/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.webkit;
import android.webkit.WebView;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresFeature;
import androidx.annotation.RestrictTo;
import org.chromium.support_lib_boundary.WebSettingsBoundaryInterface;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Configuration to set API enablement status for site origins through override rules.
*
* <p>Websites will follow the default status supplied in the builder constructor,
* unless the site origin matches one of the origin patterns supplied in the override rules.
*
* <p>The override rules are a map from origin patterns to the desired
* {@link WebViewMediaIntegrityApiStatus}.
*/
@RequiresFeature(name = WebViewFeature.WEBVIEW_MEDIA_INTEGRITY_API_STATUS,
enforcement = "androidx.webkit.WebViewFeature#isFeatureSupported")
public class WebViewMediaIntegrityApiStatusConfig {
@Target(ElementType.TYPE_USE)
@IntDef({WEBVIEW_MEDIA_INTEGRITY_API_DISABLED,
WEBVIEW_MEDIA_INTEGRITY_API_ENABLED_WITHOUT_APP_IDENTITY,
WEBVIEW_MEDIA_INTEGRITY_API_ENABLED})
@RestrictTo(RestrictTo.Scope.LIBRARY)
@Retention(RetentionPolicy.SOURCE)
@interface WebViewMediaIntegrityApiStatus {
}
/**
* Enables the WebView Media Integrity API and allows sharing of the app package name with
* the JavaScript caller.
*
* <p>This is the default value.
*/
public static final int WEBVIEW_MEDIA_INTEGRITY_API_ENABLED =
WebSettingsBoundaryInterface.WebViewMediaIntegrityApiStatus.ENABLED;
/**
* Enables the WebView Media Integrity API for JavaScript callers but disables sharing app
* package name in generated tokens.
*/
public static final int WEBVIEW_MEDIA_INTEGRITY_API_ENABLED_WITHOUT_APP_IDENTITY =
WebSettingsBoundaryInterface.WebViewMediaIntegrityApiStatus
.ENABLED_WITHOUT_APP_IDENTITY;
/**
* Disables the WebView Media Integrity API and causes it to return an
* error code to the JavaScript callers indicating that the app has disabled it.
*/
public static final int WEBVIEW_MEDIA_INTEGRITY_API_DISABLED =
WebSettingsBoundaryInterface.WebViewMediaIntegrityApiStatus.DISABLED;
private @WebViewMediaIntegrityApiStatus int mDefaultStatus;
private Map<String, @WebViewMediaIntegrityApiStatus Integer> mOverrideRules;
public WebViewMediaIntegrityApiStatusConfig(@NonNull Builder builder) {
this.mDefaultStatus = builder.mDefaultStatus;
this.mOverrideRules = builder.mOverrideRules;
}
/**
* Builds a {@link WebViewMediaIntegrityApiStatusConfig} having a default API status and
* a map of origin pattern rules to their respective API status.
*
* <p>
* Example:
* <pre class="prettyprint">
* // Create a config with default API status being DISABLED and API status is ENABLED for
* // Uris matching origin pattern "http://*.example.com"
* new WebViewMediaIntegrityApiStatusConfig.Builder(WEBVIEW_MEDIA_INTEGRITY_API_DISABLED)
* .addOverrideRule("http://*.example.com", WEBVIEW_MEDIA_INTEGRITY_API_ENABLED)
* .build();
* </pre>
*/
public static final class Builder {
private @WebViewMediaIntegrityApiStatus int mDefaultStatus;
private Map<String, @WebViewMediaIntegrityApiStatus Integer> mOverrideRules;
/**
* @param defaultStatus Default API status that will be used for URIs that don't match
* any origin pattern rule.
*/
public Builder(@WebViewMediaIntegrityApiStatus int defaultStatus) {
this.mDefaultStatus = defaultStatus;
this.mOverrideRules = new HashMap<>();
}
/**
* Add an override rule to set a specific API status for origin sites matching the origin
* pattern stated in the rule. Origin patterns should be supplied in the same format as
* those in
* {@link androidx.webkit.WebViewCompat.WebMessageListener#addWebMessageListener(WebView, String, Set, WebViewCompat.WebMessageListener)}
*
* If two or more origin patterns match a given origin site, the least permissive option
* will be chosen.
*/
@NonNull
public Builder addOverrideRule(@NonNull String originPattern,
@WebViewMediaIntegrityApiStatus int permission) {
mOverrideRules.put(originPattern, permission);
return this;
}
/**
* Set all required override rules at once using a map of origin patterns to
* desired API statuses. This overwrites existing rules.
*
* If two or more origin patterns match a given origin site, the least permissive option
* will be chosen.
*
* This is only meant for internal use within the library.
*/
@RestrictTo(RestrictTo.Scope.LIBRARY)
@NonNull
public Builder setOverrideRules(@NonNull Map<String,
@WebViewMediaIntegrityApiStatus Integer> overrideRules) {
mOverrideRules = overrideRules;
return this;
}
/**
* Build the config.
*/
@NonNull
public WebViewMediaIntegrityApiStatusConfig build() {
return new WebViewMediaIntegrityApiStatusConfig(this);
}
}
/**
* Returns the default value for origins that don't match any override rules.
*/
public @WebViewMediaIntegrityApiStatus int getDefaultStatus() {
return mDefaultStatus;
}
/**
* Get the explicitly set override rules.
* <p> This is a map from origin patterns to their desired WebView Media Integrity API statuses.
*
*/
@NonNull
public Map<String, @WebViewMediaIntegrityApiStatus Integer> getOverrideRules() {
return mOverrideRules;
}
}