New Wizards for Tomorrow’s Setup
Senior Software Engineer, Initial Configuration Team
How was your Sonos setup experience? How long did it take? What did you think of the third page after sign-in? The seventh? If the setup went poorly, you might have a great deal to say, while if it was merely "okay," it might not warrant a memory at all. A short, forgettable setup is certainly preferable to a drawn-out misadventure in home networking, but on the Initial Configuration team, we believe your first impression of Sonos can and should be much more.
Setup might not be glamorous—it's the liminal experience between buying Sonos and actually listening better—but it is critical. Like a grand temple entrance, a good setup can not only deliver us to our destination, but excite us for what is to come. To revitalize the gates of the Sonos ecosystem our team has entirely overhauled the S2 app’s setup flows—with a full rewrite of the wizard framework, the addition of 3D renders to replace line art, and the introduction of Google’s Flutter framework for the user interface. This blog post covers the first topic, and to cover it fully, we need to start at the beginning.
What is a wizard?
Software setup has long been a complex task; wizards are state-based visual flows which guide the user through this perilous quest. Originally a term for desktop applications (think “Microsoft Windows Setup Wizard”) the concept has since spread to mobile and taken on a variety of shapes and sizes.
A Brief History of Setup
The Dawn of Setup
The early years of Sonos setup were quite straightforward, requiring either a Sonos hardware controller (such as the CR100) or a desktop computer with the Sonos application installed. A single “setup wizard” guided users through all required tasks, from naming speakers to network configuration. This simple ecosystem limited the complexity of setup: there were only a few steps, a few network configurations, and a few controller platforms. Wizard code remained platform-dependent as, after all, adding a new page required edits in only three locations. All that would change, however, in one of software's most seminal years.
The Smartphone Revolution
The opening of the Apple App Store and Google Android Market in 2008 hailed a new era of software development: the era of third-party smartphone apps. Sensing the chance to provide even more freedom of choice, Sonos launched an iOS controller that very year, followed by an Android app in 2011. For the first time, users could set up their Sonos systems without the need of a desktop computer or specialized Sonos hardware, making system control (and setup) as convenient as a phone call.
While managing a Sonos system was easier than ever, managing setup’s complexity was more difficult than anticipated. With five controller platforms to support, the time cost of adding new setup steps increased dramatically. By the launch of home theater setup in 2013, (accompanying Playbar) it was obvious that the current development pattern was not sustainable. Sonos wizards needed a brand-new solution, and that solution had no name.
The Age of Anonymity
The rise of “anonymous” wizards was perhaps the most important development in Sonos wizard history. Rather than the secret society of magicians one might suspect, anonymous wizards were the first to free themselves of platform code and reside entirely within the Sonos controllers’ common C++ library (“anonymity” here refers to the platform's ignorance of which wizard they were showing). This new, centralized approach allowed componentization of the UI, platform-agnostic development, and the modularization of larger flows into “subwizards”: smaller, reusable flows.
Anonymous wizards ruled the Sonos controller applications from roughly 2014 to 2020, bringing us Trueplay, voice setup, and a variety of other experiences core to Sonos’ ecosystem. Nearly every element of setup grew in sophistication and complexity, catering to a variety of use cases and user preferences. There was just one problem: all these new wizards were quickly oustripping test capacity.
The (Brief) XML Era
Seeking to add automation support in the long reign of anonymous wizards, the setup team embarked on a brief adventure in “XML” wizards: defining a wizard’s transitions in XML and—in some cases—UI components in JSON. This had enormous advantages for automation, since all transitions were forced into an event-response structure which could be triggered and transversed by automation scripts.
Unfortunately, XML wizards came with a heavy trade-off: what was easy for automation was less so for development. While many apps’ wizard-systems are oriented around user decision points and the resulting state transitions, Sonos’ setup is much more operations-intensive. A single page in setup might fire off a half-dozen networking calls, all of which require processing in the C++ core library. Developers now needed to edit three files per wizard: a real time sink in a fast-moving industry like home audio. Only a few wizards were ever brought into the world of XML, and by the close of 2017, it seemed like pure anonymity would rule the day.
In 2018, our designers laid out a bold new vision for setup guided by the cardinal rule: show, don’t tell. From the earliest specs, text-heavy modals were replaced by sleek cards with product renders that would pop up upon speaker detection. Moreover, the new design would fully migrate Sonos setup to the mobile controllers—reflecting the overwhelming consumer move to smartphones. With such a bold vision, there was little doubt that the wizard framework needed a redesign: the only question was what a new framework should prioritize. After long discussion, a few key goals were outlined:
Event handling needed to be simple yet extensible for developers, avoiding the pitfalls of XML wizards while harnessing the benefits of event-driven design
The design needed to accommodate a large variety of presentations—from pop-up cards to three-quarters plates to full-screen modals
The UI’s data model would need to be as flexible as possible—Flutter was not yet decided upon for the view layer
Automation support had to be built in from the beginning, and able to contend with an ever-growing matrix of setup possibilities
The resulting framework is one of compromise—borrowing elements of older wizard frameworks while introducing an entirely new stack. Its design is tripartite, roughly following an MVP (Model-View-Presenter) pattern:
A C++ Model layer written by developers representing the abstract user experience, from transitions to how specific events should be handled
A C++ Presenter layer with Java and Objective-C adapters for interfacing with the view via JSON messages
A Flutter View layer, capable of turning JSON provided by the wizard framework into visual elements and plumbing back user interaction
Developing in the New Framework
If “new setup” is to be a grand entryway for the Sonos ecosystem, it's worth reflecting on why some displays of architecture stand for thousands of years while others crumble within decades. At the core of the oldest pyramid’s longevity is an adherence to simplicity: basic blocks steadily stacked tend not to fall flat. Likewise, building software with only a few exposed components—a few well-defined blocks—can stave off the worst ravages of code rot. In this spirit, the new wizard framework’s API consists of only a few extensible “blocks,” all in the model layer.
To create a new user flow, (say, for home theater setup) developers need only to implement a Wizard subclass and populate it with states. These states come in two varieties: Wizard Pages, and Subwizard States. Pages hold the majority of domain-specific logic (for example, configuring home theater settings) and provide a description of the UI for rendering by the framework. Subwizard states, on the other hand, carry little logic but allow nesting of wizard flows (for example, allowing remote control setup within home theater setup).
The framework is set in motion by Wizard Events raised by Wizard Event Sources— classes which serve as observers of other Sonos controller modules. When Bluetooth is toggled off, the app is backgrounded, or a UI button is pressed, the corresponding event source triggers an event which the framework passes down to the current page, querying what to do.
The result of this query—a description of any state transitions to perform and how to display those transitions—is called a Wizard Update. Using a visitor pattern, this “update” transitions from one state to the next, looking for its resting place. Once complete, the update is handed up to the Wizard Controller, transformed into JSON, and sent off to Flutter for rendering.
The Age of Modern Wizardry
The mapping of wizard lifecycles to an event-response system—while at first a chore for developers—has paid dividends. Logs now indicate what triggers each and every state transition, while developers new to wizard development can easily adopt others’ events for their own purposes. A brand-new BLE (Bluetooth Low Energy) test wizard, for example, was able to leverage existing BLE events from setup’s own BLE wizard implementation.
Lessons learned from the XML days, all wizard-specific code is now housed within the common C++ codebase of our app, meaning that there is a single source of truth for the “behavior” of each wizard—easily queried by internal software tools. This universal description of a wizard’s traits, coupled with its event-driven design, mean that automation is more powerful than ever.
Finally, the real power of this design comes from its extensibility. Any amount of data can be passed into a wizard update, meaning that UI complexity can grow without requiring an overhaul to the system. Any flow can be nested within any other, while any event can trigger any UI change. Simple, consistent, and flexible—the right blocks for that grand entrance (save the flexibility, perhaps, if we’re still talking architecture).
“New setup” launched for the S2 app in October 2020—supported by the new wizard framework, new asset servers, and a brand-new Flutter UI. With these new tools, the Initial Configuration team has made flows easier to build, easier to maintain, and easier on the eyes. While many parts of the setup experience have been permanently upgraded, other improvements are only now within reach: Sonos has never had a shortage of ideas in this regard. From improved diagnostics to new setup techniques, there’s a lot in store for Sonos setup.
The Sonos ecosystem has come a long way these past 18 years—from all-in-one speakers to soundbars, from amps to, well, lamps. While our team’s work is never done, this new start has us excited—and hopefully our users as well. At Sonos, we don’t think it’s just up to best-in-class multiroom audio to entice and impress, but good-old setup and configuration as well.