Overview
The Browser SDK provides an easy way to integrate Fillr autofill in to your own WebView
based application, allowing users to populate web forms without leaving your application.
Prerequisites
Contact us for the Developer Key, Secret Key and SDK information required for the integration.
If you are a device manufacturer with a pre-install agreement with Fillr you will also need the Fillr APK. Please get in touch with us.
Getting Started
- Add the following dependencies to the build.gradle file located in the application’s directory (i.e. not the root build.gradle). Our library is hosted on jCenter.
implementation 'com.fillr:fillrcore-fillrembedded:latest_version'
Click here for the latest version.
-
If you are using pro-guard to obfuscate your code. Please ensure that you exclude our JavascriptNativeInterface. By adding the following lines:
-keepclassmembers class * { @android.webkit.JavascriptInterface <methods>; } -keep class com.fillr.browsersdk.Fillr$JSNativeInterface -keepclassmembers class com.fillr.browsersdk.Fillr -keepclassmembers class com.fillr.browsersdk.Fillr$JSNativeInterface -keep public class * implements com.fillr.browsersdk.Fillr$JSNativeInterface -keepclassmembers class com.fillr.browsersdk.Fillr$JSNativeInterface { <methods>; } -keep class com.fillr.analytics.** -keep interface com.fillr.analytics.** -keepattributes JavascriptInterface -keepattributes *Annotation* -keepattributes Signature -keepattributes InnerClasses -keep class retrofit.** { *; } -keep interface retrofit.** { *; } -dontwarn okio.** -dontwarn com.squareup.okhttp.** -dontwarn rx.** -dontwarn com.google.appengine.api.urlfetch.** -dontwarn retrofit.** -dontwarn com.google.android.gms.** -keepclassmembers class ** {
Your app should compile now.
Enable Fillr on Your Browser Tabs
- The Fillr SDK requires a reference to the root activity object of your application, which hosts the underlying WebView container. This can be done either in your Activity or Application.
Fillr also requires a reference to current active browser view. If you have multiple browser views e.g. for tabbed browsing, you need to call trackWebview each time the current active tab changes.
import com.fillr.browsersdk.Fillr;
import com.fillr.browsersdk.Fillr.BROWSER_TYPE;
...
// The Fillr SDK needs to be set up before any web views are displayed
// an onCreate of your main browser activity might be a good place to initialise the Fillr SDK
Activity parentActivity = getActivity();
Fillr fillr = Fillr.getInstance();
// Fillr browser properties allow the Fillr views to be branded to match your browser
FillrBrowserProperties fillrBrowserProperties = new FillrBrowserProperties("Browser Name", "Browser Name Displayed on Toolbar");
// In addition to that browser properties allows customisation of the Toolbar icon. Provide a 20dp image of your browsers icon - refer Toolbar //Icon Dimensions below for more info.
//(It is also recommended that it is a selector, with a on and off state)
FillrBrowserProperties fillrBrowserProperties = new FillrBrowserProperties("Browser Name", "Browser Name Displayed on Toolbar", "Your browser icon");
String devKey = "your_developer_key";
String secretKey = "your_secret_key";
//Implement the remote widget auth to receive over the air updates and fixes. These credentials will be provided to you along with your developer key and secret.
String remoteWidgeAuthUsername = "your_username";
String remoteWidgeAuthPassword = "your_password";
FillrConfig config = new FillrConfig(devKey, secretKey, new FillrWidgetAuth(remoteWidgeAuthUsername, remoteWidgeAuthPassword));
// Initialise only needs to be called once per application session, but it *must* be called before you call Fillr.trackWebView()
fillr.initialise(config, parentActivity, BROWSER_TYPE.(WEB_KIT|GECKO), fillrBrowserProperties);
...
// Enable the Fillr toolbar on each of your web views. Call trackWebView once per web view, ideally as soon as the web view is created but *must* be after you have called Fillr.initialise()
// And for WebKit based webViews it *must* be called before the web view's loadUrl is called (See note https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/webkit/WebView.java#1785
// Call trackWebView in whichever method creates and/or displays your web views
Fillr.getInstance().trackWebView(webView, FillrWebView.(OPTIONS_TLS_PROXY|OPTIONS_NONE)); //see discussion of these options in the next section, below
Browser Activity Code Example
https://github.com/Fillr/Lightning-Browser/blob/master/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java#L89
https://github.com/Fillr/Lightning-Browser/blob/master/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java#L1197-L1198
Configuring the WebView Options
The FIllr SDK has two options that can be passed in when tracking a WebView
:
1. OPTIONS_TLS_PROXY
- Instructs Fillr to install a TLS proxy between the WebView
and the rest of the Internet; all outbound HTTP/S traffic from the WebView
will be routed through the proxy. This increases the range of sites Fillr can supply autofill services for, by ensuring it can always inject the JavaScript autofill widget.
2. OPTIONS_NONE
- Instructs Fillr to rely solely upon Android’s shouldInterceptRequest callback when injecting the JavaScript autofill widget. This allows a simpler/more lightweight integration, at the expense of limited autofill capabilities in certain use-cases.
If no option is passed when calling trackWebView
, then the SDK will default to using OPTIONS_NONE
.
Consider carefully which option is most appropriate for your application, and be aware of the additional requirements and caveats that may apply to your chosen approach. These are discussed in more detail below.
Using OPTIONS_TLS_PROXY
With this option, the Fillr SDK will proxy all outbound network requests and inject the JavaScript autofill widget directly into response data if/when required. This enables autofill support on the broadest range of sites possible.
When using OPTIONS_TLS_PROXY
, it’s important that Fillr
be notified of onReceivedSslError
callbacks from the WebView
. There are two options for accomplishing this:
Option 1. Set FillrWebViewClient as WebViewClient or extend FillrWebViewClient instead of WebViewClient
webView.setWebViewClient(new FillrWebViewClient());
Option 2. Within your WebViewClient onReceivedSslError method add a call to Fillr.onReceivedSslError(WebView view, SslErrorHandler handler, SslError error).
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
boolean handled = Fillr.getInstance().onReceivedSslError(view, handler, error);
if (handled) {
//Fillr has dealt with the error, nothing more to do
return;
}
//any additional code you want to run here, or call super.onReceivedSslError()
}
Note that if your app makes its own network requests outside of the Android WebView and there’s a chance your internal network requests may access some of the same domains being requested by the WebView then you should be sure to pass the Proxy.NO_PROXY
flag when establishing a new network request to ensure that no cross-talk with the TLS proxy occurs.
Note that if your app needs to run its own internal network proxy (or route traffic through a specific external proxy) then OPTIONS_TLS_PROXY
should not be used as the competing proxy configurations will interfere with each other. In these cases, OPTIONS_NONE
should be preferred.
Using OPTIONS_NONE
With this option Fillr will not modify the WebView
proxy settings and can safely be used alongside internal/external proxies provided/configured by your application.
There’s no additional configuration or integration changes required when using this option.
The main drawback when using OPTIONS_NONE
is that cross-origin frames loaded via POST
request will not support autofill. The same may apply to cross-origin resources loaded using GET
requests, in cases where the request relies upon per-session cookie values and similar state. This can cause autofill to be unavailable within some e-commerce checkout flows.
Configuring HEADLESS Mode.
The guide below details how to run the SDK first in HEADLESS MODE, and then moves onto explain how to configure HEADLESS MODE.
Enable HEADLESS MODE
We can set the Fill mode as HEADLESS using the code listed below, this is usually done soon after initialization of the Fillr SDK, i.e After calling Fillr.initialise() method.
Fillr fillr = Fillr.getInstance();
fillr.setFillMode(Fillr.FillMode.HEADLESS);
Profile Data Listener
In order to receive the Form Fields from the WebView
, we need to implement a callback listener. The following code illustrates this,
fillr.profileDataListener(new Fillr.FillrProfileDataListener() {
@Override
public void onFormDetected(FillrWebView webview, FillrMapping mapping) {
//Fillr returns detected form elements.
//Using the Fillr namespace; profile data values can be set. Such as,
//"PersonalDetails.Honorific", "PersonalDetails.FirstName" which is avialable through the FillrMapping object.
}
});
Inserting data into the WebView
In order to parse data into the FillrWebView; We have to use the objects FillrMapping and FillrWebView obtained from the method onFormDetected(FillrWebView webview, FillrMapping mapping)
.
The data needs to be formatted as key value pairs. Such as,
@Override
public void onFormDetected(FillrWebView webview, FillrMapping fillrMapping) {
.....
HashMap<String, String> profileData = new HashMap<>();
profileData.put("PersonalDetails.Honorific", "Mr.");
profileData.put("PersonalDetails.FirstName", "John");
profileData.put("PersonalDetails.LastName", "Doe");
profileData.put("PersonalDetails.BirthDate.Day", "05");
profileData.put("PersonalDetails.BirthDate.Month", "05");
profileData.put("PersonalDetails.BirthDate.Year", "1997");
profileData.put("ContactDetails.CellPhones.CellPhone.Number", "0416525889");
profileData.put("ContactDetails.Emails.Email.Address", "test@test.com");
profileData.put("AddressDetails.HomeAddress.AddressLine1", "245 Chapel Street");
profileData.put("AddressDetails.HomeAddress.Suburb", "Prahran");
profileData.put("AddressDetails.HomeAddress.PostalCode", "3181");
profileData.put("AddressDetails.HomeAddress.AdministrativeArea", "Glen Iris");
//once the data has been populated, we can then set the profile data
//into the mapping request and inject it into the webview using the code below,
fillrMapping.setProfileData(profileData);
Fillr.getInstance().performAutofillOnWebView(webview, fillrMapping);
Notify Fillr events
- You need to configure your
WebViewClient
in the following manner,
Option 1. Set FillrWebViewClient as WebViewClient or extends FillrWebViewClient instead of WebViewClient
webView.setWebViewClient(new FillrWebViewClient());
Option 2. Within your WebViewClient methods add calls to Fillr.onPageStarted(WebView view, String url) and Fillr.onPageFinished(WebView view). Also, within your WebViewClient shouldInterceptRequest method add a call Fillr.shouldInterceptRequest(view, request).
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
...
Fillr.getInstance().onPageStarted(view, url);
}
@Override
public void onPageFinished(WebView view, String url) {
...
Fillr.getInstance().onPageFinished(view);
}
@Override
public WebResourceResponse shouldInterceptRequest (WebView view, WebResourceRequest request) {
...
WebResourceResponse response = Fillr.getInstance().shouldInterceptRequest(view, request);
if (response != null) return response;
return super.shouldInterceptRequest(view, request);
}
Note that if using any other mechanism to trigger Fillr.onPageStarted(WebView view, String url) and Fillr.onPageFinished(WebView view) calls it’s important to ensure that Fillr.onPageStarted(WebView view, String url) is called exactly once per page-load. Failure to do so may result in repeat widget injections, which can degrade application performance.
Optional Configuration
Enable/Disable Autofill for Users
Your users may want to enable/disable the Fillr autofill prompt from appearing when they tap in to a form field. This can be achieved by the Fillr API:
Fillr API Call
Fillr.getInstance().setEnabled(false);
Widget Source
The Fillr SDK allows for the widget to be fetched from the remote CDN or local assets.
The remote CDN is constantly updated with new features so providing your users with the best autofill capabilities will require fewer SDK/App updates and releases for your browser.
Loading the widget from the local assets folder means less outbound requests during a fill and can speed things up for slow connections. You will need to keep an eye out for important widget updates to ensure your browser has the latest autofill capabilities.
Fillr.getInstance().setWidgetSource(FillrAuthenticationStore.WidgetSource);
enum FillrAuthenticationStore.WidgetSource { REMOTE, LOCAL }
REMOTE - Load the widget each fill from https://d2o8n2jotd2j7i.cloudfront.net/widget/android/sdk/FillrWidget-Android.js.gz
LOCAL - Load the widget from ~/<project root>/FillrSDK/src/main/assets/FillrWidget-Android.js
FillrToolbarEventListener
Your application can register to listen for various Fillr toolbar events through the FillrToolbarEventListener class.
public interface FillrToolbarEventListener {
// Raised whenever the visibility of the toolbar is changed
public void onToolbarVisibilityChanged(Fillr.ToolbarViewVisibility visibility, boolean isFillrInstalled);
// Raised when the user taps the toolbar fill button
public void onToolbarFillClicked(boolean isFillrInstalled);
// Raised after the toolbar has been dismissed by the user more times than the threshold
// The threshold is by default set to 4
public void onDismissThresholdExceeded();
}
Create a FillrToolbarEventListener instance and register it as follows:
FillrToolbarEventListener listener = new FillrToolbarEventListener(...);
Fillr.getInstance().setToolbarEventListener(listener);
Get notified of capture value events
Capture values returns values entered into the web form back to an integrator in digestible format. To get notified of capture value events and access the values captured, implement listener FillrCaptureValueListener
and its method onValuesCaptured
as follow:
fillr.captureValueListener(new Fillr.FillrCaptureValueListener() {
@Override
public void onValuesCaptured(FillrWebView webview, HashMap<String, String> valueMappings) {
}
});
Supported Web Views
In general the Fillr SDK will work against any WebView or wrapper object that exposes the following API:
- getSettings - Used to enable Javascript. Must return a WebSettings compatible object.
- addJavascriptInterface - Used to add a JNI Object
- loadUrl - Used to load the JS // Needed to determine when to show the Fillr Toolbar
- hasFocus - Used to toggle visibility Fillr Toolbar
- getVisibility - Used to toggle visibility of the Fillr Toolbar through a listener // Used to compensate for the Fillr Toolbar
- getScrollX - Determine the current scrolling position
- getScrollY - Determine the current scrolling position
- scrollTo(x, y); - Used to componsate for the Fillr Toolbar
Migrating from Version 5/6/7 to Version 8+
To migrate to SDK versions 8 and higher you must ensure that the Fillr SDK is informed of webview lifecycle events. There are two main options for accomplishing this:
Option 1. Set FillrWebViewClient as WebViewClient or extend FillrWebViewClient instead of WebViewClient in your implementation (ensuring that superclass methods are invoked)
webView.setWebViewClient(new FillrWebViewClient());
– OR –
Option 2. Within your WebViewClient implementation add calls to Fillr.onPageStarted(WebView view, String url)
and Fillr.onPageFinished(WebView view)
.
Also, within your WebViewClient shouldInterceptRequest
method add a call to Fillr.shouldInterceptRequest(view, request)
.
Migrating from Version 4 to Version 5
To migrate from Version 4 to Version 5 you should update your trackWebView
calls to pass either OPTIONS_TLS_PROXY
or OPTIONS_NONE
as per your preference/requirements.
The trackWebView
invocation changes from:
Fillr.getInstance().trackWebView(webView);
to
Fillr.getInstance().trackWebView(webView, FillrWebView.(OPTIONS_TLS_PROXY|OPTIONS_NONE));
For a detailed discussion of these options, please consult the ‘Configuring the WebView Options’ section, above.
Note that this change is optional and you can continue calling the original, single-parameter version of trackWebView
if you wish. This is the same as calling the updated trackWebView
method with OPTIONS_NONE
as the second argument.
Migrating from Version 2 to Version 5
In addition to the steps discussed in the ‘Migrating from Version 4 to Version 5’ section, above, to migrate from Version 2 to Version 5 you also need to change the initialization method. To activate the cart scraper, you will need to pass the username and password into the FillrWidgetAuth
object.
The initialise
method changes from:
fillr.initialise(FILLR_KEY, FILLR_SECRET, this, Fillr.BROWSER_TYPE.WEB_KIT);
to
String remoteAuthUsername = "username";
String remoteAuthPassword = "password";
FillrConfig config = new FillrConfig(FILLR_KEY, FILLR_SECRET, new FillrWidgetAuth(remoteAuthUsername, remoteAuthPassword));
Eclipse Projects
The Fillr SDK is configured for Gradle enabled projects. To include in an Eclipse project, unpack the FillrSDK.zip to your workspace:
- Click File > New > Other
- Select Android Project
- Select “Create Project from existing source”
- Click “Browse…” button and navigate to FillrSDK
- Finish (Now you should be able to see the FillrSDK project in your workspace)
- Right-click on your project (your browser) > Properties
- In Android > Library section click Add > select the FillrSDK project
- Click ok > Clean and Build
Importing User Data into Fillr
To import the users data into the Fillr SDK so it can be used to fill forms the following api is provided.
public final class UserDataAccessor
public UserDataAccessor(Context context)
public void importEmail(String email)
public void importFirstName(String firstName)
public void importLastName(String lastName)
public void importPhoneNumber(UserCellPhoneNumber userCellPhoneNumber)
public void importTelephoneNumber(UserTelephoneNumber userTelephoneNumber)
public void importCreditCards(List<UserCreditCard> creditCards)
public void importAddresses(List<UserAddress> addresses)
public void importRawAddresses(List<String> addresses)
After instantiating an instance of UserDataAccessor its public methods can be used to pass in Strings and the following Java Objects which are also public:
UserCellPhoneNumber
UserCreditCard
UserAddress
Importing Addresses as unformatted strings
- It is likely that you may store your address data in a different format. To simplify the import process addresses can be provided as a String. These addresses are then parsed using the LibPostal API. Refer to their documentation to get a better understanding of the best way to format your address Strings.
IMPORTANT NOTE
- The sdk supports import only. When data is imported all preexisting data in the same catagory is deleted (i.e. Importing an address removes all previously imported and stored addresses). To clear out all data in a specific category you will need to import an empty list. For Name and Email passing a blank string will do the equivalent.
Fennec Build
Integrating the Fillr SDK in to Fennec requires a bit more effort. The following details how to adjust the Fennec build and mach build scripts to neatly bundle the FillrSDK in to the apk.
The following assumes you have a relatively recent checkout of the Fennec source code from git. (Mercurial repos should just require a little bit more attention when patching the Fennec makefile sources). We are also assuming you are using the Fennec supplied mach build system (For Gradle builds please contact Fillr tech support)
Step 1.
Add the FillrSDK to your project.
- Download the latest SDK
- Unzip the contents to
<project root>/mobile/android/FillrSDK
- Download the Gecko JavaScript Widget
- Put the FillrWidget-Gecko.js file in a new folder
<project root>/mobile/android/FillrSDK/src/main/assets
- Download the Loopj Asynchronous HTTP Client for Android
- Put the android-async-http-1.4.5.jar in a new folder
<project root>/mobile/android/FillrSDK/libs
Your project should now look something like this:
├── project-root
...
├── mobile
├── android
...
├── FillrSDK
├── libs
| └── android-async-http-1.4.5.jar
└── src
└── main
├── assets
| └── FillrWidget-Gecko.js
├── java ...
└── res ...
Step 2
Add the blocks of code found below to the file <project root>/mobile/android/base/BrowserApp.java
Imports:
import com.fillr.browsersdk.Fillr;
import com.fillr.browsersdk.Fillr.BROWSER_TYPE;
In your onCreate
method, as close to the top of the method as possible:
((GeckoView) mLayerView).importScript("resource://android/assets/FillrWidget-Gecko.js");
Fillr.getInstance().initialise("testkey", this, Fillr.BROWSER_TYPE.GECKO);
Fillr.getInstance().trackGeckoView(new Fillr.FillInitListener() {
@Override
public void onFillButtonClicked() {
if (mLayerView instanceof GeckoView) {
GeckoAppShell.sendRequestToGecko(new org.mozilla.gecko.util.GeckoRequest("Fillr:GetFields", "fillr") {
@Override
public void onResponse(NativeJSObject response) {
String retVal = response.toString();
Fillr.getInstance().startProcess(retVal);
}
});
}
}
@Override
public boolean shouldShowFillrToolbar() {
if (mLayerView instanceof GeckoView) {
return mLayerView.hasFocus();
}
return false;
}
});
In your onActivityResult
method of the same file, as close to the top of the method as possible:
if(Fillr.FILLR_REQUEST_CODE == requestCode){
if (resultCode == RESULT_OK) {
String payload = data.getStringExtra("com.fillr.payload");
String mappings = data.getStringExtra("com.fillr.mappings");
if(payload != null && mappings != null) {
String map = mappings.replaceAll("(\\\\t|\\\\n|\\\\r')", " ");
String pl = payload.toString();
JSONObject temp = new JSONObject();
try {
temp.put("fields",new JSONObject(map));
temp.put("payload",new JSONObject(pl));
GeckoAppShell.sendRequestToGecko(new org.mozilla.gecko.util.GeckoRequest("Fillr:Fill", temp) {
@Override
public void onResponse(NativeJSObject response) {
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
}
return;
}
In the onResume
method add the following as close to the top of the method but below the super.onResume()
call:
Fillr.getInstance().onResume();
Step 3
In /firefox/mozilla-central/mobile/android/base/resources/layout/gecko_app.xml
Add the following:
<com.fillr.browsersdk.FillrToolbarView
android:id="@+id/fillrtoolbarview"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="0dp"
android:visibility="invisible" />
Before the last closing tag </org.mozilla.gecko.OuterLayout>
Step 4
Adjust the mach build scripts. Download the following patch and apply to your project.
https://fillr.s3.amazonaws.com/integration/fillr-sdk-fennec-40.0.patch
Browser Icon Dimensions
Test Forms
The following are recommended forms for testing Fillr autofill and validating your integration. They are easy to access and exercise a good range of fields from the Fillr profile:
- https://psr.slv.vic.gov.au
- https://www.gpcu.org/Applications/Loan-Payment-Form.aspx
- https://www.bradford.com.au/onlinepayment.html
Support
For technical support contact product@fillr.com
Draft document only. API subject to change.