Skip to content

Commit

Permalink
feat(sdk): config to control webview hardware acceleration (#119)
Browse files Browse the repository at this point in the history
  • Loading branch information
CAMOBAP authored May 17, 2023
1 parent 890f849 commit 9868c61
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 31 deletions.
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

# 3.9.0

- Feature: add config to control WebView hardware acceleration `HCaptchaConfig.disableHardwareAcceleration`
- Fix: removed unsafe cast with improved public api

# 3.8.2

- Bugfix: handle BadParcelableException when hCaptcha fragment needs to be recreated due to app resume
Expand Down
47 changes: 24 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,29 +151,30 @@ To release all resources you may call `HCaptcha.reset()`.
The following list contains configuration properties to allows customization of the hCaptcha verification flow.
| Name | Values/Type | Required | Default | Description |
|-------------------|-------------------------|----------|----------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `siteKey` | String | **Yes** | - | This is your sitekey, this allows you to load challenges. If you need a sitekey, please visit [hCaptcha](https://www.hcaptcha.com), and sign up to get your sitekey. |
| `size` | Enum | No | INVISIBLE | This specifies the "size" of the checkbox component. By default, the checkbox is invisible and the challenge is shown automatically. |
| `orientation` | Enum | No | PORTRAIT | This specifies the "orientation" of the challenge. |
| `theme` | Enum | No | LIGHT | hCaptcha supports light, dark, and contrast themes. |
| `locale` | String (ISO 639-1 code) | No | AUTO | You can enforce a specific language or let hCaptcha auto-detect the local language based on user's device. |
| `resetOnTimeout` | Boolean | No | False | (DEPRECATED, use `retryPredicate`) Automatically reload to fetch new challenge if user does not submit challenge. (Matches iOS SDK behavior.) |
| `retryPredicate` | Lambda | No | - | Automatically trigger a new verification when some error occurs. |
| `jsSrc` | String (URL) | No | https://js.hcaptcha.com/1/api.js | See Enterprise docs. |
| `sentry` | Boolean | No | True | See Enterprise docs. |
| `rqdata` | String | No | - | See Enterprise docs. |
| `apiEndpoint` | String (URL) | No | - | (DEPRECATED, use `jsSrc`) See Enterprise docs. |
| `endpoint` | String (URL) | No | - | See Enterprise docs. |
| `reportapi` | String (URL) | No | - | See Enterprise docs. |
| `assethost` | String (URL) | No | - | See Enterprise docs. |
| `imghost` | String (URL) | No | - | See Enterprise docs. |
| `customTheme` | Stringified JSON | No | - | See Enterprise docs. |
| `host` | String (URL) | No | - | See Enterprise docs. |
| `loading` | Boolean | No | True | Show or hide the loading dialog. |
| `hideDialog` | Boolean | No | False | To be used in combination with a passive sitekey when no user interaction is required. See Enterprise docs. |
| `tokenExpiration` | long | No | 120 | hCaptcha token expiration timeout (seconds). |
| `diagnosticLog` | Boolean | No | False | Emit detailed console logs for debugging |
| Name | Values/Type | Required | Default | Description |
|-------------------------------|-------------------------|----------|----------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `siteKey` | String | **Yes** | - | This is your sitekey, this allows you to load challenges. If you need a sitekey, please visit [hCaptcha](https://www.hcaptcha.com), and sign up to get your sitekey. |
| `size` | Enum | No | INVISIBLE | This specifies the "size" of the checkbox component. By default, the checkbox is invisible and the challenge is shown automatically. |
| `orientation` | Enum | No | PORTRAIT | This specifies the "orientation" of the challenge. |
| `theme` | Enum | No | LIGHT | hCaptcha supports light, dark, and contrast themes. |
| `locale` | String (ISO 639-1 code) | No | AUTO | You can enforce a specific language or let hCaptcha auto-detect the local language based on user's device. |
| `resetOnTimeout` | Boolean | No | False | (DEPRECATED, use `retryPredicate`) Automatically reload to fetch new challenge if user does not submit challenge. (Matches iOS SDK behavior.) |
| `retryPredicate` | Lambda | No | - | Automatically trigger a new verification when some error occurs. |
| `jsSrc` | String (URL) | No | https://js.hcaptcha.com/1/api.js | See Enterprise docs. |
| `sentry` | Boolean | No | True | See Enterprise docs. |
| `rqdata` | String | No | - | See Enterprise docs. |
| `apiEndpoint` | String (URL) | No | - | (DEPRECATED, use `jsSrc`) See Enterprise docs. |
| `endpoint` | String (URL) | No | - | See Enterprise docs. |
| `reportapi` | String (URL) | No | - | See Enterprise docs. |
| `assethost` | String (URL) | No | - | See Enterprise docs. |
| `imghost` | String (URL) | No | - | See Enterprise docs. |
| `customTheme` | Stringified JSON | No | - | See Enterprise docs. |
| `host` | String (URL) | No | - | See Enterprise docs. |
| `loading` | Boolean | No | True | Show or hide the loading dialog. |
| `hideDialog` | Boolean | No | False | To be used in combination with a passive sitekey when no user interaction is required. See Enterprise docs. |
| `tokenExpiration` | long | No | 120 | hCaptcha token expiration timeout (seconds). |
| `diagnosticLog` | Boolean | No | False | Emit detailed console logs for debugging |
| `disableHardwareAcceleration` | Boolean | No | True | Disable WebView hardware acceleration |
### Config Examples
Expand Down
2 changes: 1 addition & 1 deletion example-app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ android {
dependencies {
//noinspection GradleDependency
implementation "androidx.appcompat:appcompat:${prop('exampleAppcompatVersion', '1.3.1')}"

implementation "com.google.android.flexbox:flexbox:3.0.0"
implementation project(path: ':sdk')

testImplementation 'junit:junit:4.13.2'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class MainActivity extends AppCompatActivity {
private Spinner sizeSpinner;
private CheckBox hideDialog;
private CheckBox loading;
private CheckBox disableHardwareAccel;
private TextView tokenTextView;
private TextView errorTextView;
private HCaptcha hCaptcha;
Expand All @@ -39,6 +40,7 @@ protected void onCreate(Bundle savedInstanceState) {
errorTextView = findViewById(R.id.errorTextView);
hideDialog = findViewById(R.id.hide_dialog);
loading = findViewById(R.id.loading);
disableHardwareAccel = findViewById(R.id.hwAccel);
final ArrayAdapter<HCaptchaSize> adapter = new ArrayAdapter<>(this,
android.R.layout.simple_spinner_dropdown_item,
Arrays.asList(HCaptchaSize.NORMAL, HCaptchaSize.INVISIBLE, HCaptchaSize.COMPACT));
Expand All @@ -63,6 +65,7 @@ private HCaptchaConfig getConfig() {
.size(size)
.loading(loading.isChecked())
.hideDialog(hideDialog.isChecked())
.disableHardwareAcceleration(disableHardwareAccel.isChecked())
.tokenExpiration(10)
.diagnosticLog(true)
.retryPredicate((config, exception) -> exception.getHCaptchaError() == HCaptchaError.SESSION_TIMEOUT)
Expand Down
16 changes: 13 additions & 3 deletions example-app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@style/Theme.AppCompat"
tools:context=".MainActivity">

<LinearLayout
<com.google.android.flexbox.FlexboxLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
app:flexDirection="row"
app:flexWrap="wrap">
<Spinner
android:id="@+id/sizes"
android:theme="@style/ThemeOverlay.AppCompat.Light"
Expand Down Expand Up @@ -41,7 +43,15 @@
android:checked="false"
android:text="@string/web_view_debug"
style="@style/CheckBoxText" />
</LinearLayout>
<CheckBox
android:id="@+id/hwAccel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:checked="true"
android:text="@string/hw_accel"
style="@style/CheckBoxText" />
</com.google.android.flexbox.FlexboxLayout>

<LinearLayout
android:layout_width="match_parent"
Expand Down
1 change: 1 addition & 0 deletions example-app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
<string name="mark_used">Mark used</string>
<string name="loading">Loading</string>
<string name="web_view_debug">Web Debug</string>
<string name="hw_accel">Disable HW Accel</string>
<string name="hide_dialog">Hide Dialog</string>
</resources>
4 changes: 2 additions & 2 deletions sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ android {
// See https://developer.android.com/studio/publish/versioning
// versionCode must be integer and be incremented by one for every new update
// android system uses this to prevent downgrades
versionCode 34
versionCode 35

// version number visible to the user
// should follow semantic versioning (See https://semver.org)
versionName "3.8.2"
versionName "3.9.0"

buildConfigField 'String', 'VERSION_NAME', "\"${defaultConfig.versionName}_${defaultConfig.versionCode}\""

Expand Down
7 changes: 7 additions & 0 deletions sdk/src/main/java/com/hcaptcha/sdk/HCaptchaConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,13 @@ public class HCaptchaConfig implements Serializable {
@Builder.Default
private Boolean diagnosticLog = false;

/**
* Disable hardware acceleration for WebView
*/
@Builder.Default
@NonNull
private Boolean disableHardwareAcceleration = true;

/**
* @deprecated use {@link #getJsSrc()} getter instead
*/
Expand Down
6 changes: 4 additions & 2 deletions sdk/src/main/java/com/hcaptcha/sdk/HCaptchaWebViewHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,13 @@ private void setupWebView(@NonNull final Handler handler) {
webView.setWebChromeClient(new HCaptchaWebChromeClient());
}
webView.setBackgroundColor(Color.TRANSPARENT);
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
if (config.getDisableHardwareAcceleration()) {
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
webView.addJavascriptInterface(jsInterface, HCaptchaJSInterface.JS_INTERFACE_TAG);
webView.addJavascriptInterface(debugInfo, HCaptchaDebugInfo.JS_INTERFACE_TAG);
webView.loadDataWithBaseURL(config.getHost(), htmlProvider.getHtml(), "text/html", "UTF-8", null);
HCaptchaLog.d("WebViewHelper.loadData");
HCaptchaLog.d("WebViewHelper.loadData. Hardware acceleration enabled: %b", webView.isHardwareAccelerated());
}

public void destroy() {
Expand Down
4 changes: 4 additions & 0 deletions sdk/src/test/java/com/hcaptcha/sdk/HCaptchaConfigTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public void default_config() {
assertEquals(Locale.getDefault().getLanguage(), config.getLocale());
assertEquals("https://js.hcaptcha.com/1/api.js", config.getJsSrc());
assertEquals(null, config.getCustomTheme());
assertEquals(true, config.getDisableHardwareAcceleration());
assertNull(config.getRqdata());
}

Expand All @@ -44,6 +45,7 @@ public void custom_config() {
final String customEndpoint = "https://local/api.js";
final String customLocale = "ro";
final Boolean sentry = false;
final Boolean disableHWAccel = false;
final String customTheme = "{ \"palette\": {"
+ "\"mode\": \"light\", \"primary\": { \"main\": \"#F16622\" },"
+ "\"warn\": { \"main\": \"#F16622\" },"
Expand All @@ -59,6 +61,7 @@ public void custom_config() {
.size(hCaptchaSize)
.orientation(hCaptchaOrientation)
.customTheme(customTheme)
.disableHardwareAcceleration(disableHWAccel)
.build();
assertEquals(MOCK_SITE_KEY, config.getSiteKey());
assertEquals(sentry, config.getSentry());
Expand All @@ -69,6 +72,7 @@ public void custom_config() {
assertEquals(customRqdata, config.getRqdata());
assertEquals(customEndpoint, config.getJsSrc());
assertEquals(customTheme, config.getCustomTheme());
assertEquals(disableHWAccel, config.getDisableHardwareAcceleration());
}

@Test
Expand Down
Loading

0 comments on commit 9868c61

Please sign in to comment.