Add guidance on using proprietary components
PiperOrigin-RevId: 357201112
Change-Id: Ic3085e8f25e57ff7c53fa0cb8dd976bf88da0653
diff --git a/docs/open_source.md b/docs/open_source.md
new file mode 100644
index 0000000..2d92c6aa
--- /dev/null
+++ b/docs/open_source.md
@@ -0,0 +1,126 @@
+# Integrating proprietary components
+
+go/androidx/open_source
+
+<!--*
+# Document freshness: For more information, see go/fresh-source.
+freshness: { owner: 'alanv' reviewed: '2021-02-11' }
+*-->
+
+[TOC]
+
+One of the core principles of Jetpack is "Developed as open-source and
+compatible with AOSP Android," but what does that mean in practice? This guide
+provides specific, technical guidance on developing an open-source library and
+interacting with proprietary or closed-source libraries and services.
+
+## Why do we care?
+
+### Compatibility with AOSP ecosystem
+
+The Android Open-Source Project enables a diverse ecosystem of devices with a
+wide array of software environments in which our libraries will operate. Many of
+those devices are certified to run Play Services, but it's important for our
+libraries to work on all devices that are certified as Android -- even those
+with no Google software installed.
+
+* Features provided by primary artifacts **must** be able to function on AOSP
+ devices without the presence of proprietary components like Play Services
+
+### Testing and testability
+
+Isolating behavior makes it easier to write reliable and targeted tests, but
+introducing dependencies on proprietary components makes this difficult. In a
+well-abstracted library, developers should be able to write integration tests
+against the library's documented API surface without concerning themselves with
+the implementation details of a backing service.
+
+* Features provided by primary artifacts that may be backed by proprietary
+ components **must** be written in way that makes it feasible for a developer
+ to write and delegate to their own backing implementation
+
+## Developer choice
+
+Developers should be able to choose between proprietary components; however,
+libraries are also encouraged to provide a sensible default.
+
+* Features provided by primary artifacts that may be backed by proprietary
+ components **must** allow developers to choose a specific backing component
+ and **must not** hard-code proprietary components as the default choice
+* Libraries _may_ use a ranking or filtering heuristic based on platform APIs
+ such as permissions, presence on the system image, or other properties of
+ applications and packages
+
+## Open protocols
+
+Third-party developers should be able to provide their own backing services,
+which means service discovery mechanisms, communication protocols, and API
+surfaces used to implement a backing service must be publicly available for
+implementation.
+
+Third-party developers should also be able to validate that their implementation
+conforms to the expectations of the library. Library developers should already
+be writing tests to cover their backing service, e.g. that a service
+implementing a protocol or interface is correct, and in many cases these tests
+will be suitable for third-party developers to verify their own implementations.
+
+While we recommend that developers provide a stub backing implementation in a
+`-testing` artifact or use one in their own unit tests, we do not require one to
+be provided; only that it is possible to write one.
+
+## Examples of policy violations
+
+* A primary artifact uses `Intent` handling as a service discovery mechanism
+ and hard-codes a reference to `com.google.android` as a ranking heuristic.
+ * **What's wrong?** This conflicts with the developer choice principle.
+ Primary artifacts must remain neutral regarding specific proprietary
+ components.
+ * **How to fix?** This library should use an alternative ranking heuristic
+ that takes advantage of platform APIs such as granted permissions or
+ presence of the component on the system image (see
+ [FLAG_SYSTEM](https://developer.android.com/reference/android/content/pm/ApplicationInfo#FLAG_SYSTEM)
+ and
+ [FLAG_UPDATED_SYSTEM_APP](https://developer.android.com/reference/android/content/pm/ApplicationInfo#FLAG_UPDATED_SYSTEM_APP)).
+ The library will also need to provide an API that allows developers to
+ choose an explicit ranking or default component.
+* A primary artifact uses reflection to delegate to a specific fully-qualified
+ class name. This class is provided by an optional library that delegates to
+ Play Services.
+ * **What's wrong?** This is another situation where the library is
+ limiting developer choice. Features in primary artifacts which may
+ delegate to proprietary services must allow developers to choose a
+ different delegate. Reflection on a fully-qualified class name does
+ _not_ allow multiple delegates to exist on the classpath and is not a
+ suitable service discovery mechanism.
+ * **How to fix?** This library should use a more suitable service
+ discovery mechanism that allows multiple providers to coexist and
+ ensures the the developer is able to choose among them.
+* A primary artifact provides a service discovery mechanism that allows
+ multiple providers and exposes an API that lets the developer specify a
+ preference. Communication with the service is managed through a `Bundle`
+ where they keys, values, and behaviors are documented outside of Jetpack.
+ * **What's wrong?** This conflicts with the open protocols principle.
+ Third-party developers should be able to implement their own backing
+ services, but using a `Bundle` with a privately-documented protocol
+ means that (1) it is not possible to write adqeuate tests in Jetpack and
+ (2) developers outside of Google cannot feasibly write correct backing
+ implementations.
+ * **How to fix?** At a minimum, the developer should fully document the
+ keys, values, and behavior expected by the protocol; however, in this
+ case we would strongly recommend replacing or wrapping `Bundle` with a
+ strongly-typed and documented API surface and robust suite of tests to
+ ensure implementations on either side of the protocol are behaving
+ correctly.
+* A primary artifact provides an `interface` and an API that allows developers
+ to specify a backing service using classes that implement that interface.
+ The `interface` API surface has several `@hide` methods annotated with
+ `@RestrictTo(LIBRARY_GROUP)`.
+ * **What's wrong?** This is another open protocols issue. Third-party
+ developers should be able to implement their own backing services, but
+ using a partially-private `interface` means that only Jetpack libraries
+ can feasibly provide a backing implementation.
+ * **How to fix?** At a minimum, the developer should make the `interface`
+ fully public and documented so that it can be implemented by a
+ third-party. They should also provide robust tests for the default
+ backing implementation with the expectation that third-party developers
+ will use this to verify their own custom implementations.
diff --git a/docs/policies.md b/docs/policies.md
index 0b790f5..35b7aaa 100644
--- a/docs/policies.md
+++ b/docs/policies.md
@@ -1,4 +1,4 @@
-## AndroidX policies and processes
+# Policies and processes
This document is intended to describe release policies that affect the workflow
of an engineer developing within the AndroidX libraries. It also describes the
diff --git a/docs/principles.md b/docs/principles.md
index 6dba721..c498b10 100644
--- a/docs/principles.md
+++ b/docs/principles.md
@@ -53,11 +53,13 @@
### 5. Developed as open-source and compatible with AOSP Android
- Expose a unified developer-facing API surface across the Android ecosystem
-- Avoid proprietary services or closed-source libraries for core
- functionality, and instead provide integration points that allow a developer
- to choose a proprietary service as the backing implementation
- Develop in AOSP to provide visibility into new features and bug fixes and
encourage external participation
+- Avoid proprietary services or closed-source libraries for core
+ functionality, and instead provide integration points that allow a developer
+ to choose between a variety of services as the backing implementation
+- See [Integrating proprietary components] for guidance on using closed-source
+ and proprietary libraries and services
### 6. Written using language-idiomatic APIs