Uno, Duo, Hey!

Writing apps for the Surface Duo using the Uno platform

Published on 24 January 2020

Intro

Last December I wrote a blog post called "The Seven GUIs of Christmas" as part of the Third Annual C# Advent series. This post showed the use of the Uno Platform to write cross-platform apps in UWP. One of the major drivers behind this blog post a desire to write apps for Microsoft's recently announced Surface Neo and Surface Duo devices which run Windows 10X and Android respectively. Well, a couple of days ago, Microsoft finally released a preview SDK for the Surface Duo which included an Android Emulator with a preview Surface Duo image. Today I finally got a chance to see whether the Uno Platform really could deliver on these new form-factors.

Installing the Emulator

If, like me, you don't have Android Studio installed and/or you want to install the Surface Duo SDK in a non-standard location (my super-speedy Intel Optane 900P C:\ drive is getting a little crowded!), you're going to face issues running the emulator. This is mostly due to the run.bat file used to launch the emulator not looking in the correct location for the Android SDK and not supporting installation of the Surface Duo SDK in a path that contains spaces.

If you're encountering issues launching the emulator, navigate to the artifacts directory within the Surface Duo SDK installation directory and edit the run.bat file to the following:

@echo off

rem ##### ENSURE THE SDK LOCATION BELOW IS CORRECT: #######
set ANDROID_SDK_LOCATION=C:\Program Files (x86)\Android\android-sdk

rem ############ DO NOT Modify below this line ############

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.\

echo %DIRNAME%

rem Check if emulator is installed
set EMULATOR=%ANDROID_SDK_LOCATION%\emulator\emulator.exe
echo "%EMULATOR%"
if exist %EMULATOR% (
    set ANDROID_PRODUCT_OUT=%DIRNAME%
    "%EMULATOR%" -verbose -accel auto %* -sysdir "%DIRNAME%\bin" -kernel "%DIRNAME%\bin\kernel-ranchu" -datadir "%DIRNAME%\bin\data" -initdata "%DIRNAME%\bin\userdata.img" -vendor "%DIRNAME%\bin\vendor-qemu.img" -system "%DIRNAME%\bin\system-qemu.img" -initdata "%DIRNAME%\bin\userdata.img" -data "%DIRNAME%\bin\userdata.img"
) else (
    echo "Can't find emulator executable, make sure its installed"
)

TBH, the changes are mostly just encapsulating paths within quotes but hopefully this'll save you a little time.

Hopefully now, when you launch the emulator, you'll be greeted by this:

Android Duo Emulator

Hmm... dual screens!

Getting Started

Microsoft have done a great job of helping developers get started on this platform by supplying some great code-snippets and samples in both Java and C# (using the Xamarin platform). Furthermore, the emulator "just works" with the Visual Studio IDE such that, once running, it appears as a standard deployment target allowing you to quickly get apps running within the Surface Duo image.

VisualStudio Targetting The Duo Emulator

Cross-Platform Dual-Screen

My first priority with Uno was to make sure I could correctly interpret when the app was running on a single screen or across both screens. To do this, I took a look at the Xamarin samples and quickly saw that they used a ScreenHelper class to collate information on the current state of the app. This class is provided as part of the (very new - just two days old at time of writing!) Xamarin.DuoSdk nuget package. Fortunately, when running on Android (or iOS), Uno runs on top of Xamarin meaning I could just add a reference to this package from the Droid head project of my Uno solution and start using this class right away.

The main functions of the ScreenHelper class were abstracted behind an IDeviceHelper interface so that each head project could provide a platform specific implementation and a small shim written around the ScreenHelper class to satisfy this interface. Finally, to provide responsiveness to changes, I again used my MVx.Observable nuget package to dynamically call IDeviceHelper members and update properties on a view model whenever the application changed modes.

In very short order, I had this working:

Just to highlight: this is completely standard UWP / C# code, running unchanged on a dual-screen Android device.

A few comments / caveats:

  1. The loading time of the Uno app in the emulator was due to the app being run, as debug, directly from the Visual Studio IDE and is not indicative of Uno Platform app start times.
  2. The app disappearing when switching between screens or between single and dual screen modes is not due to the Uno Platform; this happen with apps that come as part of the Duo image.
  3. Occasionally, when switching between single and dual screen modes, the app will just disappear. Again, this is nothing to do with the Uno Platform and happens with apps that come as part of the Duo image.

Conclusion

Surface Duo

While the Surface Duo Android Emulator image is undoubtedly rough around the edges (it is, after all, a preview) it manages to provide a tantalising taste of what using dual-screen devices could be like. Indeed, just running the Contacts and Calendar apps side-by-side boggles the mind with possible interactions between the two. Furthermore Microsoft have, in relatively short order, delivered a preview SDK from which it is possible to start developing new dual-screen apps or enhance existing apps to take advantage of a second screen. Exciting times!

Uno Platform

Per my experience while writing "The Seven GUIs of Christmas" post, the Uno Platform has continued to preform admirably and shows great promise for writing apps that will run natively across platforms and on dual screens. The only issue I had with Uno while writing the app above was the use of a "Shared Project" to share the Xaml/ViewModel between the various head projects. This approach (which I recommended against in my previous post) resulted in Visual Studio stubbornly refusing to show the Xaml editor and countless errors being shown in the error window despite everything compiling and running fine.

Code

All code for this post can be found in my UnoDuoHey repository on Github.

Lastly...

I am currently eager to find potential new clients interested in using the Uno Platform to deliver cross-platform apps and those looking to capitalise on the amazing potential of dual-screen devices in particular. If this sounds like you or your company, please feel free to drop me a line to discuss your project/ideas using any of the links below or from my about page.