1# Integrating proprietary components
2
3[TOC]
4
5One of the core principles of Jetpack is "Developed as open-source and
6compatible with AOSP Android," but what does that mean in practice? This guide
7provides specific, technical guidance on developing an open-source library and
8interacting with proprietary or closed-source libraries and services.
9
10## What do we mean by "open-source"?
11
12Our definition of open-source includes products that provide publicly-available
13source code that can be compiled by an end-user to generate a functional version
14of the product, e.g. an `AAR`, that is equivalent to the one used by the
15library.
16
17### Exceptions
18
19#### Android Open Source Project
20
21The only unconditional exception to this definition is the Android Open Source
22Project itself, which does not release sources publicly until well after its API
23surface has been finalized.
24
25Libraries which are developed against the pre-release Android platform SDK _may_
26remain closed-source until the platform SDK's API surface is finalized, at which
27they **must** move to open-source.
28
29#### Closed-source dependencies
30
31In specific cases, libraries *may* include closed-source dependencies; however,
32we **strongly recommend** that closed-source dependencies like Play Services be
33paired with an open-source alternative provided directly in Jetpack, in the
34Android SDK, or as part of a Mainline module.
35
36See the
37[Open-source compatibility](/docs/api_guidelines/index.md#dependencies-aosp)
38section of the API Guidelines for details on integrating closed-source
39components.
40
41### Examples of products that are _not_ open-source
42
43*   A bundled `.so` file with no publicly-available source code
44*   A Maven dependency with no publicly-available source code, either in the
45    Maven distribution (ex. source `JAR`) or in a public repository
46*   A library that ships source code to GitHub, but the source does not compile
47*   A library that ships source code to AOSP, but binary compiled from that
48    source is not functionally equivalent to the library used by Jetpack
49*   A closed-source web service
50*   Google Play Services
51
52## Why do we care?
53
54### Compatibility with AOSP ecosystem
55
56The Android Open-Source Project enables a diverse ecosystem of devices with a
57wide array of software environments in which our libraries will operate. Many of
58those devices are certified to run Play Services, but it's important for our
59libraries to work on all devices that are certified as Android -- even those
60with no Google software installed.
61
62*   Features provided by primary artifacts **must** be able to function on AOSP
63    devices without the presence of proprietary components like Play Services
64
65### Testing and testability
66
67Isolating behavior makes it easier to write reliable and targeted tests, but
68introducing dependencies on proprietary components makes this difficult. In a
69well-abstracted library, developers should be able to write integration tests
70against the library's documented API surface without concerning themselves with
71the implementation details of a backing service.
72
73*   Features provided by primary artifacts that may be backed by proprietary
74    components **must** be written in way that makes it feasible for a developer
75    to write and delegate to their own backing implementation
76
77### Developer choice
78
79Developers should be able to choose between proprietary components; however,
80libraries are also encouraged to provide a sensible default.
81
82*   Features provided by primary artifacts that may be backed by proprietary
83    components **must** allow developers to choose a specific backing component
84    and **must not** hard-code proprietary components as the default choice
85*   Libraries _may_ use a ranking or filtering heuristic based on platform APIs
86    such as permissions, presence on the system image, or other properties of
87    applications and packages
88
89### Open protocols
90
91Third-party developers should be able to provide their own backing services,
92which means service discovery mechanisms, communication protocols, and API
93surfaces used to implement a backing service must be publicly available for
94implementation.
95
96Third-party developers should also be able to validate that their implementation
97conforms to the expectations of the library. Library developers should already
98be writing tests to cover their backing service, e.g. that a service
99implementing a protocol or interface is correct, and in many cases these tests
100will be suitable for third-party developers to verify their own implementations.
101
102While we recommend that developers provide a stub backing implementation in a
103`-testing` artifact or use one in their own unit tests, we do not require one to
104be provided; only that it is possible to write one.
105
106## Examples of policy violations
107
108*   A primary artifact uses `Intent` handling as a service discovery mechanism
109    and hard-codes a reference to `com.google.android` as a ranking heuristic.
110    *   **What's wrong?** This conflicts with the developer choice principle.
111        Primary artifacts must remain neutral regarding specific proprietary
112        components.
113    *   **How to fix?** This library should use an alternative ranking heuristic
114        that takes advantage of platform APIs such as granted permissions or
115        presence of the component on the system image (see
116        [FLAG_SYSTEM](https://developer.android.com/reference/android/content/pm/ApplicationInfo#FLAG_SYSTEM)
117        and
118        [FLAG_UPDATED_SYSTEM_APP](https://developer.android.com/reference/android/content/pm/ApplicationInfo#FLAG_UPDATED_SYSTEM_APP)).
119        The library will also need to provide an API that allows developers to
120        choose an explicit ranking or default component.
121*   A primary artifact uses reflection to delegate to a specific fully-qualified
122    class name. This class is provided by an optional library that delegates to
123    Play Services.
124    *   **What's wrong?** This is another situation where the library is
125        limiting developer choice. Features in primary artifacts which may
126        delegate to proprietary services must allow developers to choose a
127        different delegate. Reflection on a fully-qualified class name does
128        *not* allow multiple delegates to exist on the classpath and is not a
129        suitable service discovery mechanism.
130    *   **How to fix?** This library should use a more suitable service
131        discovery mechanism that allows multiple providers to coexist and
132        ensures the developer is able to choose among them.
133*   A primary artifact provides a service discovery mechanism that allows
134    multiple providers and exposes an API that lets the developer specify a
135    preference. Communication with the service is managed through a `Bundle`
136    where they keys, values, and behaviors are documented outside of Jetpack.
137    *   **What's wrong?** This conflicts with the open protocols principle.
138        Third-party developers should be able to implement their own backing
139        services, but using a `Bundle` with a privately-documented protocol
140        means that (1) it is not possible to write adqeuate tests in Jetpack and
141        (2) developers outside of Google cannot feasibly write correct backing
142        implementations.
143    *   **How to fix?** At a minimum, the developer should fully document the
144        keys, values, and behavior expected by the protocol; however, in this
145        case we would strongly recommend replacing or wrapping `Bundle` with a
146        strongly-typed and documented API surface and robust suite of tests to
147        ensure implementations on either side of the protocol are behaving
148        correctly.
149*   A primary artifact provides an `interface` and an API that allows developers
150    to specify a backing service using classes that implement that interface.
151    The `interface` API surface has several `@hide` methods annotated with
152    `@RestrictTo(LIBRARY_GROUP)`.
153    *   **What's wrong?** This is another open protocols issue. Third-party
154        developers should be able to implement their own backing services, but
155        using a partially-private `interface` means that only Jetpack libraries
156        can feasibly provide a backing implementation.
157    *   **How to fix?** At a minimum, the developer should make the `interface`
158        fully public and documented so that it can be implemented by a
159        third-party. They should also provide robust tests for the default
160        backing implementation with the expectation that third-party developers
161        will use this to verify their own custom implementations.
162