To answer Josh's questions:
Q: Do you have any strong reasons to keep the API sync aside from matching the Java impl?
A: There isn't a strong reason to keep the calls synchronous at your layer, but we will eventually need to translate these into synchronous calls (even if it's just one level higher). Our calls can be disruptive (eg. connecting to a hotspot will disconnect you from your normal network) and the way we guard against disrupting ourselves is to make sure we try things one at a time. This will become more important as more mediums are added to ChromeOS (eg. TDLS on WLAN causes issues with WiFi Direct).
Q: Do you have a rough idea of the work involved for a refactor like this?
A: Maybe a few months? Assuming most calls in the core NC layer can be switched from foo.bar() to foo.barAsync().get().
Q: Would moving to an async API break other clients, like Windows?
A: Windows APIs are primarily async too, so I don't think there's much of an issue there. I don't know about iOS. But it does mean rewriting all of these methods.