androidandroid-webviewlive-wallpaper

Android: How to use a VirtualDisplay to host a WebView in a WallpaperService?


Background

I have a web-based animation that I've turned into an Android app with live wallpaper:

http://pixfabrik.com/livingworlds/

I've done so by creating a WebView and periodically copying its contents to the WallpaperService's Surface. Here's the code for that:

https://gist.github.com/iangilman/71650d46384a2d4ae6387f2d4087cc37

… And here's how I got to that solution:

Android: Use WebView for WallpaperService

That's been working great for the last four months, but WebView 76 broke the live wallpaper by introducing this bug:

https://bugs.chromium.org/p/chromium/issues/detail?id=991078

The bug is being worked on, so I'm optimistic that WebView 77 (due to be released September 10), and will have it fixed, but it would be nice to fix my app sooner than that, if possible!

The Issue

In the bug report above, one of the Chromium developers suggested using VirtualDisplay to connect the WebView to the WallpaperService instead, so now I'm pursuing that. I'm relatively new to Android, so I'm doing it naïvely, and so far it's not working. I'm writing here seeking help!

Here's what I currently have (in my Engine's OnSurfaceChanged (so I can take advantage of the width/height it gives me)):

@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    super.onSurfaceChanged(holder, format, width, height);

    DisplayManager mDisplayManager = (DisplayManager)getSystemService(Context.DISPLAY_SERVICE);

    int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
    int density = DisplayMetrics.DENSITY_DEFAULT;

    VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay("MyVirtualDisplay",
        width, height, density, holder.getSurface(), flags);

    Presentation myPresentation = new Presentation(myContext, virtualDisplay.getDisplay());

    WebView myWebView = new WebView(myPresentation.getContext());
    myWebView.loadUrl("file:///android_asset/index.html");

    ViewGroup.LayoutParams params = new ViewGroup.LayoutParams (width, height);
    myPresentation.setContentView(myWebView, params);
}

I'm using a Presentation to connect the VirtualDisplay to the WebView (on the recommendation of the Chromium developer), but I don't know for sure if that's the right way to go about it.

The WallpaperService runs, and I don't get any errors, but I also don't see my webpage; it's just a white screen.

Hopefully I'm just doing something dumb… Please enlighten me! :-)


Solution

  • You must call the show() method on your Presentation object otherwise it won't be displayed to the Virtual Display.