Docs: Add How to Write Cross-Platform UI doc

Change-Id: Ic1d89de8dd642e932b7917bea06dc1656aa8f539
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1516075
Commit-Queue: Tommy Li <tommycli@chromium.org>
Reviewed-by: Mark Cogan <marq@chromium.org>
Reviewed-by: Theresa <twellington@chromium.org>
Reviewed-by: Matthew Jones <mdjones@chromium.org>
Reviewed-by: Ted Choc <tedchoc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#641666}
diff --git a/docs/cross_platform_ui.md b/docs/cross_platform_ui.md
new file mode 100644
index 0000000..f55f6de5
--- /dev/null
+++ b/docs/cross_platform_ui.md
@@ -0,0 +1,80 @@
+# How to Write Cross-Platform UI (Native components)
+
+[TOC]
+
+Chrome runs on many platforms such as Desktop (Windows, Mac, Linux, and
+ChromeOS), Android, iOS, and VR. These platforms have different UIs, written in
+different languages. Chrome also has WebUI, which is browser UI implemented in
+the HTML content area. This can be considered another UI toolkit.
+
+## Separating out platform-independent business logic
+
+For UI that appears on multiple platforms, it's best to share as much of the
+business logic (model behavior backing the UI) as possible. The
+platform-specific views should be as minimal and "dumb" as possible. One caveat:
+sharing everything may not be feasible if there are performance or latency
+concerns.
+
+The cross-platform model will be in native C++ code, likely in the
+//components/foobar directory. Model layer code should handle the business
+logic, and be richly observable. Platform-specific views/controllers should
+observe the model, update the UI, and mutate the model as needed. This model
+should have tests.
+
+Note that there can be model state that is applicable to only a subset of
+platforms. For instance, mobile devices can change device rotation or layout. On
+Mobile, the platform itself may provide extended text editing capabilities that
+don't exist on Desktop.
+
+## Lifetime Issues
+
+Different platforms may have different UI lifetime semantics, so it's helpful to
+keep the business logic stateless or with a flexible lifetime model. Android
+Java object lifetimes are well-defined, but has gotchas for cross-platform code.
+For instance: the Java side of Android is available immediately on startup, but
+the C++ side needs to wait for the native library to be loaded. Having a native
+object "own" a garbage-collected Java object or vice versa can also be tricky.
+
+ 1. Pure static functions are the easiest, if this works for your use case. In
+    addition to being easy to bridge to Java, these are also easy to unit test,
+    since they don't require setting up state.
+
+    You can usually use pure static functions for simpler cases that don't
+    involve state. These are easy to bridge to Java. See
+    [`UrlFormatter`](https://cs.chromium.org/chromium/src/components/url_formatter/android/java/src/org/chromium/components/url_formatter/UrlFormatter.java)
+    for an example of this.
+
+ 2. For objects that are associated with a specific `Profile`, use a
+    `KeyedService` instance with
+    [`BrowserContextKeyedServiceFactory`](https://cs.chromium.org/chromium/src/components/keyed_service/content/browser_context_keyed_service_factory.h).
+    If your object depends on other `KeyedService` instances, there's a strong
+    chance your object should also be a `KeyedService`. 
+
+    These are also pretty easy to bridge to Java. In most cases, the Java code
+    will need to pass a `Profile` object, so that the native `KeyedService` can
+    be fetched.
+
+    A neat trick is that the Java code can be all-static, even if the native
+    code isn't, if every method also includes a `Profile` parameter.
+
+ 3. Objects tied to WebContents lifetimes are also commonly used, and can be
+    implemented using a WebContentsObserver and WebContentsUserData.
+
+ 4. For lifetimes tied to UI instances, or other custom lifetimes, you will need
+    to do custom lifetime management. For Java bridging advice, see the JNI
+    documentation for details.
+
+## More Advice on Bridging to Java
+
+Bridging a code module to Java will have three parts:
+
+ 1. components/omnibox/browser/foobar.h/cc - Cross-platform code you already
+    wrote and have unit tests for.
+
+ 2. chrome/browser/android/omnibox/foo_feature_android.h/cc - C++ side of the
+    bridge. You might only need the cc file.
+
+ 3. chrome/android/java/src/org/chromium/chrome/browser/omnibox/FooFeature.java
+    - Java side of the bridge.
+
+See the [JNI README](../base/android/jni_generator/README.md) for more details.