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