blob: 90bbf193ba5b95b38bef6329214aeba01ad5bf13 [file] [log] [blame] [view]
alanvda56d5d2021-02-12 09:00:29 -08001# Integrating proprietary components
2
alanvda56d5d2021-02-12 09:00:29 -08003[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
alanv13925ad2021-07-16 09:40:20 -070010## 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
alanv669a2d52022-05-05 07:28:16 -070019#### 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.
alanv13925ad2021-07-16 09:40:20 -070024
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
alanv669a2d52022-05-05 07:28:16 -070029#### Closed-source dependencies
30
AndroidX Core Teamd59cd1d2024-05-20 13:30:47 -070031In 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
Ian Baker186108e2023-11-20 06:54:36 -080037[Open-source compatibility](/docs/api_guidelines/index.md#dependencies-aosp)
AndroidX Core Teamd59cd1d2024-05-20 13:30:47 -070038section of the API Guidelines for details on integrating closed-source
39components.
alanvf3ff25e2022-01-05 07:16:05 -080040
alanv13925ad2021-07-16 09:40:20 -070041### 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
alanvda56d5d2021-02-12 09:00:29 -080052## 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
alanv13925ad2021-07-16 09:40:20 -070077### Developer choice
alanvda56d5d2021-02-12 09:00:29 -080078
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
alanv13925ad2021-07-16 09:40:20 -070089### Open protocols
alanvda56d5d2021-02-12 09:00:29 -080090
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
AndroidX Core Teame80aab72021-09-29 08:44:33 -0700128 *not* allow multiple delegates to exist on the classpath and is not a
alanvda56d5d2021-02-12 09:00:29 -0800129 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
AndroidX Core Teame80aab72021-09-29 08:44:33 -0700132 ensures the developer is able to choose among them.
alanvda56d5d2021-02-12 09:00:29 -0800133* 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.