EXPEDIA GROUP TECHNOLOGY — SOFTWARE

Sizing Android WebView iframes with JavaScript

A debugging war story

Clay Tobolka
Expedia Group Technology

--

Photograph of two luchadores fighting
Photo by Mike González from Pexels

Filling the screen of an Android device with a web view is surprisingly difficult. I’d like to share my debugging war story in case it helps you out.

It started with a simple request to display the same iframe our web checkout team uses in the Android traveler app in order to show users 3D Secure (3DS) challenges, part of a two factor authentication protocol for securing online credit and debit card transactions.

Decorative separator

Here is the 3DS challenge shown in our existing web checkout flow for reference, along with the mockup from our design team for Android.

The iframe portion is highlighted by the red box, which does not fill the screen

I thought, “Oh, pretty simple, just show a web view that fills that screen, and load the URL for the iframe.”

In reality, there were some JavaScript calls mixed in there, but that’s not really relevant to this specific issue. After the JavaScript calls, I’d still expect the iframe to display as above.

The style=”?android:attr/webViewStyle” and android:focusable=”true” attributes are needed to allow the user to interact with the displayed web view, tapping and typing and such.

As you can see the WebView is using match_parent for both the layout_width and layout_height attributes, so we should be good. The ThreeDSWebView class is simply an extension of the Android WebView class with some logic for making the related JavaScript calls.

Well, I go through the checkout flow with a property that is supposed to show the 3DS challenge in the web view.

Animation showing a small 3DS challenge web view, perhaps only a third of the screen, rather than the required full screen

Well then…

Decorative separator

As you can see, the iframe shows up as some kind of popup model thing that only covers the top half of the screen.

At first I thought, “No problem, its just a layout issue.” I spun my wheels messing with the layout XML, setting every WebView value I could think of, and even tried adding viewport meta tags defining the devices size and scaling. Then I did what we all do and Googled the problem. I came across the idea of inspecting the WebView in Chrome in some Stack Overflow post, so I gave that a shot.

It looked useful, and after poking at it for a bit, I made some adjustments to the elements being shown. First I adjusted the style values in the side bar and then, as I found some that started to make a difference, I turned them into JS commands in the Console.

Look! It actually looks like the intended design there at the end. Now how in the world do I run those JavaScript commands in the app?

It was a little complicated because of how the 3DS challenge is shown. Since it’s the result of a series of JavaScript calls, the styling JavaScript calls needed to be run in a Runnable that is posted to the UI thread after the JavaScript call that triggers the challenge.

In a less dynamic WebView situation, that Runnable with the styling JavaScript calls would probably go in the WebViewClient.onPageFinished() method set on the WebView.

Now after running through the checkout flow again things are looking pretty good.

The web views fill the screen

Maybe it’s not an ironclad solution, but it helped us support releasing 3DS challenges quickly by reusing work other teams had already done.

Learn more about technology at Expedia Group

--

--