# Library API guidelines

[TOC]

## Introduction {#introduction}

This guide is an addendum to
s.android.com/api-guidelines,
which covers standard and practices for designing platform APIs.

All platform API design guidelines also apply to Jetpack libraries, with any
additional guidelines or exceptions noted in this document. Jetpack libraries
also follow
[explicit API mode](https://kotlinlang.org/docs/reference/whatsnew14.html#explicit-api-mode-for-library-authors)
for Kotlin libraries.

## Modules {#module}

### Packaging and naming {#module-naming}

Java packages within Jetpack follow the format `androidx.<feature-name>`. All
classes within a feature's artifact must reside within this package, and may
further subdivide into `androidx.<feature-name>.<layer>` using standard Android
layers (app, widget, etc.) or layers specific to the feature.

Maven specifications use the groupId format `androidx.<feature-name>` and
artifactId format `<feature-name>` to match the Java package. For example,
`androidx.core.role` uses the Maven spec `androidx.core:role`.

Sub-features that can be separated into their own artifact are recommended to
use the following formats:

-   Java package: `androidx.<feature-name>.<sub-feature>.<layer>`
-   Maven groupId: `androidx.<feature-name>`
-   Maven artifactId: `<feature-name>-<sub-feature>`

Gradle project names and directories follow the Maven spec format, substituting
the project name separator `:` or directory separator `/` for the Maven
separators `.` or `:`. For example, `androidx.core:core-role` would use project
name `:core:core-role` and directory `/core/core-role`.

New modules in androidx can be created using the
[project creator script](#module-creator).

NOTE Modules for OEM-implemented shared libraries (also known as extensions or
sidecars) that ship on-device and are referenced via the `<uses-library>` tag
should follow the naming convention `com.android.extensions.<feature-name>` to
avoid placing `androidx`-packaged code in the platform's boot classpath.

#### Project directory structure {#module-structure}

Libraries developed in AndroidX follow a consistent project naming and directory
structure.

Library groups should organize their projects into directories and project names
(in brackets) as:

```
<feature-name>/
  <feature-name>-<sub-feature>/ [<feature-name>:<feature-name>-<sub-feature>]
    samples/ [<feature-name>:<feature-name>-<sub-feature>-samples]
  integration-tests/
    testapp/ [<feature-name>:testapp]
    testlib/ [<feature-name>:testlib]
```

For example, the `navigation` library group's directory structure is:

```
navigation/
  navigation-benchmark/ [navigation:navigation-benchmark]
  ...
  navigation-ui/ [navigation:navigation-ui]
  navigation-ui-ktx/ [navigation:navigation-ui-ktx]
  integration-tests/
    testapp/ [navigation:integration-tests:testapp]
```

#### Project creator script {#module-creation}

Note: The terms *project*, *module*, and *library* are often used
interchangeably within AndroidX, with project being the technical term used by
Gradle to describe a build target, e.g. a library that maps to a single AAR.

New projects can be created using our
[project creation script](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:development/project-creator/?q=project-creator&ss=androidx%2Fplatform%2Fframeworks%2Fsupport)
available in our repo.

It will create a new project with the proper structure and configuration based
on your project needs!

To use it:

```sh
cd ~/androidx-main/frameworks/support && \
cd development/project-creator && \
./create_project.py androidx.foo foo-bar
```

If you see an error message `No module named 'toml'` try the following steps.

*   Install necessary tools if they are not already installed
    *   (Linux) `sudo apt-get install virtualenv python3-venv`
    *   (Mac) `pip3 install virtualenv`
*   Create a virtual environment with `virtualenv androidx_project_creator` (you
    can choose another name for your virtualenv if you wish).
*   Install the `toml` library in your virtual env with
    `androidx_project_creator/bin/pip3 install toml`
*   Run the project creator script from your virtual env with
    `androidx_project_creator/bin/python3
    ./development/project-creator/create_project.py androidx.foo foo-bar`
*   Delete your virtual env with `rm -rf ./androidx-project_creator`
    *   virtualenv will automatically .gitignore itself, but you may want to to
        remove it anyway.

#### Common sub-feature names {#module-naming-subfeature}

*   `-testing` for an artifact intended to be used while testing usages of your
    library, e.g. `androidx.room:room-testing`
*   `-core` for a low-level artifact that *may* contain public APIs but is
    primarily intended for use by other libraries in the group
*   `-ktx` for an Kotlin artifact that exposes idiomatic Kotlin APIs as an
    extension to a Java-only library (see
    [additional -ktx guidance](#module-ktx))
*   `-samples` for sample code which can be inlined in documentation (see
    [Sample code in Kotlin modules](#sample-code-in-kotlin-modules)
*   `-<third-party>` for an artifact that integrates an optional third-party API
    surface, e.g. `-proto` or `-rxjava2`. Note that a major version is included
    in the sub-feature name for third-party API surfaces where the major version
    indicates binary compatibility (only needed for post-1.x).

Artifacts **should not** use `-impl` or `-base` to indicate that a library is an
implementation detail shared within the group. Instead, use `-core`.

#### Splitting existing modules

Existing modules *should not* be split into smaller modules; doing so creates
the potential for class duplication issues when a developer depends on a new
sub-module alongside the older top-level module. Consider the following
scenario:

*   `androidx.library:1.0.0`
    *   contains class `androidx.library.A`
    *   contains class `androidx.library.util.B`

This module is split, moving `androidx.library.util.B` to a new module:

*   `androidx.library:1.1.0`
    *   contains class `androidx.library.A`
    *   depends on `androidx.library.util:1.1.0`
*   `androidx.library.util:1.1.0`
    *   contains class `androidx.library.util.B`

A developer writes an app that depends directly on `androidx.library.util:1.1.0`
and also transitively pulls in `androidx.library:1.0.0`. Their app will no
longer compile due to class duplication of `androidx.library.util.B`.

While it is possible for the developer to fix this by manually specifying a
dependency on `androidx.library:1.1.0`, there is no easy way for the developer
to discover this solution from the class duplication error raised at compile
time.

Same-version groups are a special case for this rule. Existing modules that are
already in a same-version group may be split into sub-modules provided that (a)
the sub-modules are also in the same-version group and (b) the full API surface
of the existing module is preserved through transitive dependencies, e.g. the
sub-modules are added as dependencies of the existing module.

#### Same-version (atomic) groups {#modules-atomic}

Library groups are encouraged to opt-in to a same-version policy whereby all
libraries in the group use the same version and express exact-match dependencies
on libraries within the group. Such groups must increment the version of every
library at the same time and release all libraries at the same time.

Atomic groups are specified in
[libraryversions.toml](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:libraryversions.toml):

```
// Non-atomic library group
APPCOMPAT = { group = "androidx.appcompat" }
// Atomic library group
APPSEARCH = { group = "androidx.appsearch", atomicGroupVersion = "versions.APPSEARCH" }
```

Libraries within an atomic group should not specify a version in their
`build.gradle`:

```groovy
androidx {
    name = 'AppSearch'
    publish = Publish.SNAPSHOT_AND_RELEASE
    mavenGroup = LibraryGroups.APPSEARCH
    inceptionYear = '2019'
    description = 'Provides local and centralized app indexing'
}
```

The benefits of using an atomic group are:

-   Easier for developers to understand dependency versioning
-   `@RestrictTo(LIBRARY_GROUP)` APIs are treated as private APIs and not
    tracked for binary compatibility
-   `@RequiresOptIn` APIs defined within the group may be used without any
    restrictions between libraries in the group

Potential drawbacks include:

-   All libraries within the group must be versioned identically at head
-   All libraries within the group must release at the same time

#### Early-stage development {#modules-atomic-alpha}

There is one exception to the same-version policy: newly-added libraries within
an atomic group may be "quarantined" from other libraries to allow for rapid
iteration until they are API-stable.

A quarantined library must stay within the `1.0.0-alphaXX` cycle until it is
ready to conform to the same-version policy. While in quarantime, a library is
treated at though it is in a separate group from its nomical same-version group:

-   Must stay in `1.0.0-alphaXX`, e.g. same-version policy is not enforced
-   May use `project` or pinned version dependencies, e.g. strict-match
    dependencies are not enforced
-   May release on a separate cadence from other libraries within group
-   Must not reference restricted `LIBRARY-GROUP`-scoped APIs

When the library would like to leave quarantine, it must wait for its atomic
group to be within a `beta` cycle and then match the version. It is okay for a
library in this situation to skip versions, e.g. move directly from
`1.0.0-alpha02` to `2.1.3-beta06`.

### Choosing a `minSdkVersion` {#module-minsdkversion}

The recommended minimum SDK version for new Jetpack libraries is currently
**19** (Android 4.4, KitKat). This SDK was chosen to represent 99% of active
devices based on Play Store check-ins (see Android Studio
[distribution metadata](https://dl.google.com/android/studio/metadata/distributions.json)
for current statistics). This maximizes potential users for external developers
while minimizing the amount of overhead necessary to support legacy versions.

However, if no explicit minimum SDK version is specified for a library, the
default is **14** (Android 4.0, Ice Cream Sandwich).

Note that a library **must not** depend on another library with a higher
`minSdkVersion` that its own, so it may be necessary for a new library to match
its dependent libraries' `minSdkVersion`.

Individual modules may choose a higher minimum SDK version for business or
technical reasons. This is common for device-specific modules such as Auto or
Wear.

Individual classes or methods may be annotated with the
[@RequiresApi](https://developer.android.com/reference/android/annotation/RequiresApi.html)
annotation to indicate divergence from the overall module's minimum SDK version.
Note that this pattern is *not recommended* because it leads to confusion for
external developers and should be considered a last-resort when backporting
behavior is not feasible.

### Kotlin extension `-ktx` libraries {#module-ktx}

New libraries should prefer Kotlin sources with built-in Java compatibility via
`@JvmName` and other affordances of the Kotlin language; however, existing Java
sourced libraries may benefit from extending their API surface with
Kotlin-friendly APIs in a `-ktx` library.

A Kotlin extension library **may only** provide extensions for a single base
library's API surface and its name **must** match the base library exactly. For
example, `work:work-ktx` may only provide extensions for APIs exposed by
`work:work`.

Additionally, an extension library **must** specify an `api`-type dependency on
the base library and **must** be versioned and released identically to the base
library.

Kotlin extension libraries *should not* expose new functionality; they should
only provide Kotlin-friendly versions of existing Java-facing functionality.

## Platform compatibility API patterns {#platform-compatibility-apis}

NOTE For all library APIs that wrap or provide parity with platform APIs,
*parity with the platform APIs overrides API guidelines*. For example, if the
platform API being wrapped has incorrect `Executor` and `Callback` ordering
according to the API Guidelines, the corresponding library API should have the
exact same (incorrect) ordering.

### Static shims (ex. [ViewCompat](https://developer.android.com/reference/android/support/v4/view/ViewCompat.html)) {#static-shim}

When to use?

*   Platform class exists at module's `minSdkVersion`
*   Compatibility implementation does not need to store additional metadata

Implementation requirements

*   Class name **must** be `<PlatformClass>Compat`
*   Package name **must** be `androidx.<feature>.<platform.package>`
*   Superclass **must** be `Object`
*   Class **must** be non-instantiable, i.e. constructor is private no-op
*   Static fields and static methods **must** match match signatures with
    `<PlatformClass>`
    *   Static fields that can be inlined, ex. integer constants, **must not**
        be shimmed
*   Public method names **must** match platform method names
*   Public methods **must** be static and take `<PlatformClass>` as first
    parameter (except in the case of static methods on the platform class, as
    shown below)
*   Implementation *may* delegate to `<PlatformClass>` methods when available

#### Sample {#static-shim-sample}

The following sample provides static helper methods for the platform class
`android.os.Process`.

```java
/**
 * Helper for accessing features in {@link Process}.
 */
public final class ProcessCompat {
    private ProcessCompat() {
        // This class is non-instantiable.
    }

    /**
     * [Docs should match platform docs.]
     *
     * Compatibility behavior:
     * <ul>
     * <li>SDK 24 and above, this method matches platform behavior.
     * <li>SDK 16 through 23, this method is a best-effort to match platform behavior, but may
     * default to returning {@code true} if an accurate result is not available.
     * <li>SDK 15 and below, this method always returns {@code true} as application UIDs and
     * isolated processes did not exist yet.
     * </ul>
     *
     * @param [match platform docs]
     * @return [match platform docs], or a value based on platform-specific fallback behavior
     */
    public static boolean isApplicationUid(int uid) {
        if (Build.VERSION.SDK_INT >= 24) {
            return Api24Impl.isApplicationUid(uid);
        } else if (Build.VERSION.SDK_INT >= 17) {
            return Api17Impl.isApplicationUid(uid);
        } else if (Build.VERSION.SDK_INT == 16) {
            return Api16Impl.isApplicationUid(uid);
        } else {
            return true;
        }
    }

    @RequiresApi(24)
    static class Api24Impl {
        static boolean isApplicationUid(int uid) {
            // In N, the method was made public on android.os.Process.
            return Process.isApplicationUid(uid);
        }
    }

    @RequiresApi(17)
    static class Api17Impl {
        private static Method sMethod_isAppMethod;
        private static boolean sResolved;

        static boolean isApplicationUid(int uid) {
            // In JELLY_BEAN_MR2, the equivalent isApp(int) hidden method moved to public class
            // android.os.UserHandle.
            try {
                if (!sResolved) {
                    sResolved = true;
                    sMethod_isAppMethod = UserHandle.class.getDeclaredMethod("isApp",int.class);
                }
                if (sMethod_isAppMethod != null) {
                    return (Boolean) sMethod_isAppMethod.invoke(null, uid);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return true;
        }
    }

    ...
}
```

### Wrapper (ex. [AccessibilityNodeInfoCompat](https://developer.android.com/reference/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.html)) {#wrapper}

When to use?

*   Platform class may not exist at module's `minSdkVersion`
*   Compatibility implementation may need to store additional metadata
*   Needs to integrate with platform APIs as return value or method argument
*   **Note:** Should be avoided when possible, as using wrapper classes makes it
    very difficult to deprecate classes and migrate source code when the
    `minSdkVersion` is raised

#### Sample {#wrapper-sample}

The following sample wraps a hypothetical platform class `ModemInfo` that was
added to the platform SDK in API level 23:

```java
public final class ModemInfoCompat {
  // Only guaranteed to be non-null on SDK_INT >= 23. Note that referencing the
  // class itself directly is fine -- only references to class members need to
  // be pushed into static inner classes.
  private final ModemInfo wrappedObj;

  /**
   * [Copy platform docs for matching constructor.]
   */
  public ModemInfoCompat() {
    if (SDK_INT >= 23) {
      wrappedObj = Api23Impl.create();
    } else {
      wrappedObj = null;
    }
    ...
  }

  @RequiresApi(23)
  private ModemInfoCompat(@NonNull ModemInfo obj) {
    mWrapped = obj;
  }

  /**
   * Provides a backward-compatible wrapper for {@link ModemInfo}.
   * <p>
   * This method is not supported on devices running SDK < 23 since the platform
   * class will not be available.
   *
   * @param info platform class to wrap
   * @return wrapped class, or {@code null} if parameter is {@code null}
   */
  @RequiresApi(23)
  @NonNull
  public static ModemInfoCompat toModemInfoCompat(@NonNull ModemInfo info) {
    return new ModemInfoCompat(obj);
  }

  /**
   * Provides the {@link ModemInfo} represented by this object.
   * <p>
   * This method is not supported on devices running SDK < 23 since the platform
   * class will not be available.
   *
   * @return platform class object
   * @see ModemInfoCompat#toModemInfoCompat(ModemInfo)
   */
  @RequiresApi(23)
  @NonNull
  public ModemInfo toModemInfo() {
    return mWrapped;
  }

  /**
   * [Docs should match platform docs.]
   *
   * Compatibility behavior:
   * <ul>
   * <li>API level 23 and above, this method matches platform behavior.
   * <li>API level 18 through 22, this method ...
   * <li>API level 17 and earlier, this method always returns false.
   * </ul>
   *
   * @return [match platform docs], or platform-specific fallback behavior
   */
  public boolean isLteSupported() {
    if (SDK_INT >= 23) {
      return Api23Impl.isLteSupported(mWrapped);
    } else if (SDK_INT >= 18) {
      // Smart fallback behavior based on earlier APIs.
      ...
    }
    // Default behavior.
    return false;
  }

  // All references to class members -- including the constructor -- must be
  // made on an inner class to avoid soft-verification errors that slow class
  // loading and prevent optimization.
  @RequiresApi(23)
  private static class Api23Impl {
    @DoNotInline
    @NonNull
    static ModemInfo create() {
      return new ModemInfo();
    }

    @DoNotInline
    static boolean isLteSupported(ModemInfo obj) {
      return obj.isLteSupported();
    }
  }
}
```

Note that libraries written in Java should express conversion to and from the
platform class differently than Kotlin classes. For Java classes, conversion
from the platform class to the wrapper should be expressed as a `static` method,
while conversion from the wrapper to the platform class should be a method on
the wrapper object:

```java
@NonNull
public static ModemInfoCompat toModemInfoCompat(@NonNull ModemInfo info);

@NonNull
public ModemInfo toModemInfo();
```

In cases where the primary library is written in Java and has an accompanying
`-ktx` Kotlin extensions library, the following conversion should be provided as
an extension function:

```kotlin
fun ModemInfo.toModemInfoCompat() : ModemInfoCompat
```

Whereas in cases where the primary library is written in Kotlin, the conversion
should be provided as an extension factory:

```kotlin
class ModemInfoCompat {
  fun toModemInfo() : ModemInfo

  companion object {
    @JvmStatic
    @JvmName("toModemInfoCompat")
    fun ModemInfo.toModemInfoCompat() : ModemInfoCompat
  }
}
```

#### API guidelines {#wrapper-api-guidelines}

##### Naming {#wrapper-naming}

*   Class name **must** be `<PlatformClass>Compat`
*   Package name **must** be `androidx.core.<platform.package>`
*   Superclass **must not** be `<PlatformClass>`

##### Construction {#wrapper-construction}

*   Class *may* have public constructor(s) to provide parity with public
    `PlatformClass` constructors
    *   Constructor used to wrap `PlatformClass` **must not** be public
*   Class **must** implement a static `PlatformClassCompat
    toPlatformClassCompat(PlatformClass)` method to wrap `PlatformClass` on
    supported SDK levels
    *   If class does not exist at module's `minSdkVersion`, method must be
        annotated with `@RequiresApi(<sdk>)` for SDK version where class was
        introduced

#### Implementation {#wrapper-implementation}

*   Class **must** implement a `PlatformClass toPlatformClass()` method to
    unwrap `PlatformClass` on supported SDK levels
    *   If class does not exist at module's `minSdkVersion`, method must be
        annotated with `@RequiresApi(<sdk>)` for SDK version where class was
        introduced
*   Implementation *may* delegate to `PlatformClass` methods when available (see
    below note for caveats)
*   To avoid runtime class verification issues, all operations that interact
    with the internal structure of `PlatformClass` must be implemented in inner
    classes targeted to the SDK level at which the operation was added.
    *   See the [sample](#wrapper-sample) for an example of interacting with a
        method that was added in SDK level 23.

### Standalone (ex. [ArraySet](https://developer.android.com/reference/android/support/v4/util/ArraySet.html), [Fragment](https://developer.android.com/reference/android/support/v4/app/Fragment.html)) {#standalone}

When to use?

*   Platform class may exist at module's `minSdkVersion`
*   Does not need to integrate with platform APIs
*   Does not need to coexist with platform class, ex. no potential `import`
    collision due to both compatibility and platform classes being referenced
    within the same source file

Implementation requirements

*   Class name **must** be `<PlatformClass>`
*   Package name **must** be `androidx.<platform.package>`
*   Superclass **must not** be `<PlatformClass>`
*   Class **must not** expose `PlatformClass` in public API
    *   In exceptional cases, a *released* standalone class may add conversion
        between itself and the equivalent platform class; however, *new* classes
        that support conversion should follow the [Wrapper](#wrapper)
        guidelines. In these cases, use a `toPlatform<PlatformClass>` and
        `static toCompat<PlatformClass>` method naming convention.
*   Implementation *may* delegate to `PlatformClass` methods when available

### Standalone JAR library (no Android dependencies) {#standalone-jar-library-no-android-dependencies}

When to use

*   General purpose library with minimal interaction with Android types
    *   or when abstraction around types can be used (e.g. Room's SQLite
        wrapper)
*   Lib used in parts of app with minimal Android dependencies
    *   ex. Repository, ViewModel
*   When Android dependency can sit on top of common library
*   Clear separation between android dependent and independent parts of your
    library
*   Clear that future integration with android dependencies can be layered
    separately

**Examples:**

The **Paging Library** pages data from DataSources (such as DB content from Room
or network content from Retrofit) into PagedLists, so they can be presented in a
RecyclerView. Since the included Adapter receives a PagedList, and there are no
other Android dependencies, Paging is split into two parts - a no-android
library (paging-common) with the majority of the paging code, and an android
library (paging-runtime) with just the code to present a PagedList in a
RecyclerView Adapter. This way, tests of Repositories and their components can
be tested in host-side tests.

**Room** loads SQLite data on Android, but provides an abstraction for those
that want to use a different SQL implementation on device. This abstraction, and
the fact that Room generates code dynamically, means that Room interfaces can be
used in host-side tests (though actual DB code should be tested on device, since
DB impls may be significantly different on host).

## Implementing compatibility {#compat}

### Referencing new APIs {#compat-newapi}

Generally, methods on extension library classes should be available to all
devices above the library's `minSdkVersion`.

#### Checking device SDK version {#compat-sdk}

The most common way of delegating to platform or backport implementations is to
compare the device's `Build.VERSION.SDK_INT` field to a known-good SDK version;
for example, the SDK in which a method first appeared or in which a critical bug
was first fixed.

Non-reflective calls to new APIs gated on `SDK_INT` **must** be made from
version-specific static inner classes to avoid verification errors that
negatively affect run-time performance. For more information, see Chromium's
guide to
[Class Verification Failures](https://chromium.googlesource.com/chromium/src/+/HEAD/build/android/docs/class_verification_failures.md).

Methods in implementation-specific classes **must** be paired with the
`@DoNotInline` annotation to prevent them from being inlined.

```java {.good}
public static void saveAttributeDataForStyleable(@NonNull View view, ...) {
  if (Build.VERSION.SDK_INT >= 29) {
    Api29Impl.saveAttributeDataForStyleable(view, ...);
  }
}

@RequiresApi(29)
private static class Api29Impl {
  @DoNotInline
  static void saveAttributeDataForStyleable(@NonNull View view, ...) {
    view.saveAttributeDataForStyleable(...);
  }
}
```

Alternatively, in Kotlin sources:

```kotlin {.good}
@RequiresApi(29)
private object Api29Impl {
  @JvmStatic
  @DoNotInline
  fun saveAttributeDataForStyleable(view: View, ...) { ... }
}
```

When developing against pre-release SDKs where the `SDK_INT` has not been
finalized, SDK checks **must** use `BuildCompat.isAtLeastX()` methods.

```java {.good}
@NonNull
public static List<Window> getAllWindows() {
  if (BuildCompat.isAtLeastR()) {
    return ApiRImpl.getAllWindows();
  }
  return Collections.emptyList();
}
```

#### Device-specific issues {#compat-oem}

Library code may work around device- or manufacturer-specific issues -- issues
not present in AOSP builds of Android -- *only* if a corresponding CTS test
and/or CDD policy is added to the next revision of the Android platform. Doing
so ensures that such issues can be detected and fixed by OEMs.

#### Handling `minSdkVersion` disparity {#compat-minsdk}

Methods that only need to be accessible on newer devices, including
`to<PlatformClass>()` methods, may be annotated with `@RequiresApi(<sdk>)` to
indicate they will fail to link on older SDKs. This annotation is enforced at
build time by Lint.

#### Handling `targetSdkVersion` behavior changes {#compat-targetsdk}

To preserve application functionality, device behavior at a given API level may
change based on an application's `targetSdkVersion`. For example, if an app with
`targetSdkVersion` set to API level 22 runs on a device with API level 29, all
required permissions will be granted at installation time and the run-time
permissions framework will emulate earlier device behavior.

Libraries do not have control over the app's `targetSdkVersion` and -- in rare
cases -- may need to handle variations in platform behavior. Refer to the
following pages for version-specific behavior changes:

*   API level 29:
    [Android Q behavior changes: apps targeting Q](https://developer.android.com/preview/behavior-changes-q)
*   API level 28:
    [Behavior changes: apps targeting API level 28+](https://developer.android.com/about/versions/pie/android-9.0-changes-28)
*   API level 26:
    [Changes for apps targeting Android 8.0](https://developer.android.com/about/versions/oreo/android-8.0-changes#o-apps)
*   API level 24:
    [Changes for apps targeting Android 7.0](https://developer.android.com/about/versions/nougat/android-7.0-changes#n-apps)
*   API level 21:
    [Android 5.0 Behavior Changes](https://developer.android.com/about/versions/android-5.0-changes)
*   API level 19:
    [Android 4.4 APIs](https://developer.android.com/about/versions/android-4.4)

#### Working around Lint issues {#compat-lint}

In rare cases, Lint may fail to interpret API usages and yield a `NewApi` error
and require the use of `@TargetApi` or `@SuppressLint('NewApi')` annotations.
Both of these annotations are strongly discouraged and may only be used
temporarily. They **must never** be used in a stable release. Any usage of these
annotation **must** be associated with an active bug, and the usage must be
removed when the bug is resolved.

### Delegating to API-specific implementations {#delegating-to-api-specific-implementations}

#### SDK-dependent reflection

Starting in API level 28, the platform restricts which
[non-SDK interfaces](https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces)
can be accessed via reflection by apps and libraries. As a general rule, you
will **not** be able to use reflection to access hidden APIs on devices with
`SDK_INT` greater than `Build.VERSION_CODES.P` (28).

On earlier devices, reflection on hidden platform APIs is allowed **only** when
an alternative public platform API exists in a later revision of the Android
SDK. For example, the following implementation is allowed:

```java
public AccessibilityDelegate getAccessibilityDelegate(View v) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        // Retrieve the delegate using a public API.
        return v.getAccessibilityDelegate();
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        // Retrieve the delegate by reflecting on a private field. If the
        // field does not exist or cannot be accessed, this will no-op.
        if (sAccessibilityDelegateField == null) {
            try {
                sAccessibilityDelegateField = View.class
                        .getDeclaredField("mAccessibilityDelegate");
                sAccessibilityDelegateField.setAccessible(true);
            } catch (Throwable t) {
                sAccessibilityDelegateCheckFailed = true;
                return null;
            }
        }
        try {
            Object o = sAccessibilityDelegateField.get(v);
            if (o instanceof View.AccessibilityDelegate) {
                return (View.AccessibilityDelegate) o;
            }
            return null;
        } catch (Throwable t) {
            sAccessibilityDelegateCheckFailed = true;
            return null;
        }
    } else {
        // There is no way to retrieve the delegate, even via reflection.
        return null;
    }
```

Calls to public APIs added in pre-release revisions *must* be gated using
`BuildCompat`:

```java
if (BuildCompat.isAtLeastQ()) {
   // call new API added in Q
} else if (Build.SDK_INT.VERSION >= Build.VERSION_CODES.SOME_RELEASE) {
   // make a best-effort using APIs that we expect to be available
} else {
   // no-op or best-effort given no information
}
```

### Inter-process communication {#inter-process-communication}

Protocols and data structures used for IPC must support interoperability between
different versions of libraries and should be treated similarly to public API.

#### Data structures

**Do not** use `Parcelable` for any class that may be used for IPC or otherwise
exposed as public API. The wire format used by `Parcelable` does not provide any
compatibility guarantees and will result in crashes if fields are added or
removed between library versions.

**Do not** design your own serialization mechanism or wire format for disk
storage or inter-process communication. Preserving and verifying compatibility
is difficult and error-prone.

Developers **should** use protocol buffers for most cases. See
[Protobuf](#dependencies-protobuf) for more information on using protocol
buffers in your library. **Do** use protocol buffers if your data structure is
complex and likely to change over time. If your data includes `FileDescriptor`s,
`Binder`s, or other platform-defined `Parcelable` data structures, they will
need to be stored alongside the protobuf bytes in a `Bundle`.

Developers **may** use `Bundle` in simple cases that require sending `Binder`s,
`FileDescriptor`s, or platform `Parcelable`s across IPC
([example](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:core/core/src/main/java/androidx/core/graphics/drawable/IconCompat.java;l=820)).
Note that `Bundle` has several caveats:

-   When running on Android S and below, accessing *any* entry in a `Bundle`
    will result in the platform attempting to deserialize *every* entry. This
    has been fixed in Android T and later with "lazy" bundles, but developers
    should be careful when accessing `Bundle` on earlier platforms. If a single
    entry cannot be loaded -- for example if a developer added a custom
    `Parcelable` that doesn't exist in the receiver's classpath -- an exception
    will be thrown when accessing *any* entry.
-   On all platforms, library code that receives `Bundle`s data from outside the
    process **must** read the data defensively. See previous note regarding
    additional concerns for Android S and below.
-   On all platforms, library code that sends `Bundle`s outside the process
    *should* discourage clients from passing custom `Parcelable`s.
-   `Bundle` provides no versioning and Jetpack provides no affordances for
    tracking the keys or value types associated with a `Bundle`. Library owners
    are responsible for providing their own system for guaranteeing wire format
    compatibility between versions.

Developers **may** use `VersionedParcelable` in cases where they are already
using the library and understand its limitations.

In all cases, **do not** expose your serialization mechanism in your API
surface.

NOTE We are currently investigating the suitability of Square's
[`wire` library](https://github.com/square/wire) for handling protocol buffers
in Android libraries. If adopted, it will replace `proto` library dependencies.
Libraries that expose their serialization mechanism in their API surface *will
not be able to migrate*.

#### Communication protocols

Any communication prototcol, handshake, etc. must maintain compatibility
consistent with SemVer guidelines. Consider how your protocol will handle
addition and removal of operations or constants, compatibility-breaking changes,
and other modifications without crashing either the host or client process.

## Deprecation and removal

While SemVer's binary compatibility guarantees restrict the types of changes
that may be made within a library revision and make it difficult to remove an
API, there are many other ways to influence how developers interact with your
library.

### Deprecation (`@deprecated`)

Deprecation lets a developer know that they should stop using an API or class.
All deprecations must be marked with a `@Deprecated` Java annotation as well as
a `@deprecated <migration-docs>` docs annotation explaining how the developer
should migrate away from the API.

Deprecation is an non-breaking API change that must occur in a **major** or
**minor** release.

APIs that are added during a pre-release cycle and marked as `@Deprecated`
within the same cycle, e.g. added in `alpha01` and deprecated in `alpha06`,
[must be removed](versioning.md#beta-checklist) before moving to `beta01`.

### Soft removal (@removed)

Soft removal preserves binary compatibility while preventing source code from
compiling against an API. It is a *source-breaking change* and not recommended.

Soft removals **must** do the following:

*   Mark the API as deprecated for at least one stable release prior to removal.
*   Mark the API with a `@RestrictTo(LIBRARY)` Java annotation as well as a
    `@removed <reason>` docs annotation explaining why the API was removed.
*   Maintain binary compatibility, as the API may still be called by existing
    dependent libraries.
*   Maintain behavioral compatibility and existing tests.

This is a disruptive change and should be avoided when possible.

Soft removal is a source-breaking API change that must occur in a **major** or
**minor** release.

### Hard removal

Hard removal entails removing the entire implementation of an API that was
exposed in a public release. Prior to removal, an API must be marked as
`@deprecated` for a full **minor** version (`alpha`->`beta`->`rc`->stable),
prior to being hard removed.

This is a disruptive change and should be avoided when possible.

Hard removal is a binary-breaking API change that must occur in a **major**
release.

### For entire artifacts

We do not typically deprecate or remove entire artifacts; however, it may be
useful in cases where we want to halt development and focus elsewhere or
strongly discourage developers from using a library.

Halting development, either because of staffing or prioritization issues, leaves
the door open for future bug fixes or continued development. This quite simply
means we stop releasing updates but retain the source in our tree.

Deprecating an artifact provides developers with a migration path and strongly
encourages them -- through Lint warnings -- to migrate elsewhere. This is
accomplished by adding a `@Deprecated` and `@deprecated` (with migration
comment) annotation pair to *every* class and interface in the artifact.

Entire packages (including Kotlin) can be deprecated by using a
`package-info.java` file and applying the `@Deprecated` annotation there.

The fully-deprecated artifact will be released as a deprecation release -- it
will ship normally with accompanying release notes indicating the reason for
deprecation and migration strategy, and it will be the last version of the
artifact that ships. It will ship as a new minor stable release. For example, if
`1.0.0` was the last stable release, then the deprecation release will be
`1.1.0`. This is so Android Studio users will get a suggestion to update to a
new stable version, which will contain the `@deprecated` annotations.

After an artifact has been released as fully-deprecated, it can be removed from
the source tree.

## Resources {#resources}

Generally, follow the official Android guidelines for
[app resources](https://developer.android.com/guide/topics/resources/providing-resources).
Special guidelines for library resources are noted below.

### Defining new resources

Libraries may define new value and attribute resources using the standard
application directory structure used by Android Gradle Plugin:

```
src/main/res/
  values/
    attrs.xml   Theme attributes and styleables
    dimens.xml  Dimensional values
    public.xml  Public resource definitions
    ...
```

However, some libraries may still be using non-standard, legacy directory
structures such as `res-public` for their public resource declarations or a
top-level `res` directory and accompanying custom source set in `build.gradle`.
These libraries will eventually be migrated to follow standard guidelines.

#### Naming conventions

Libraries follow the Android platform's resource naming conventions, which use
`camelCase` for attributes and `underline_delimited` for values. For example,
`R.attr.fontProviderPackage` and `R.dimen.material_blue_grey_900`.

#### Attribute formats

At build time, attribute definitions are pooled globally across all libraries
used in an application, which means attribute `format`s *must* be identical for
a given `name` to avoid a conflict.

Within Jetpack, new attribute names *must* be globally unique. Libraries *may*
reference existing public attributes from their dependencies. See below for more
information on public attributes.

When adding a new attribute, the format should be defined *once* in an `<attr
/>` element in the definitions block at the top of `src/main/res/attrs.xml`.
Subsequent references in `<declare-styleable>` elements *must* not include a
`format`:

`src/main/res/attrs.xml`

```xml
<resources>
  <attr name="fontProviderPackage" format="string" />

  <declare-styleable name="FontFamily">
      <attr name="fontProviderPackage" />
  </declare-styleable>
</resources>
```

### Public resources

Library resources are private by default, which means developers are discouraged
from referencing any defined attributes or values from XML or code; however,
library resources may be declared public to make them available to developers.

Public library resources are considered API surface and are thus subject to the
same API consistency and documentation requirements as Java APIs.

Libraries will typically only expose theme attributes, ex. `<attr />` elements,
as public API so that developers can set and retrieve the values stored in
styles and themes. Exposing values -- such as `<dimen />` and `<string />` -- or
images -- such as drawable XML and PNGs -- locks the current state of those
elements as public API that cannot be changed without a major version bump. That
means changing a publicly-visible icon would be considered a breaking change.

#### Documentation

All public resource definitions should be documented, including top-level
definitions and re-uses inside `<styleable>` elements:

`src/main/res/attrs.xml`

```xml
<resources>
  <!-- String specifying the application package for a Font Provider. -->
  <attr name="fontProviderPackage" format="string" />

  <!-- Attributes that are read when parsing a <fontfamily> tag. -->
  <declare-styleable name="FontFamily">
      <!-- The package for the Font Provider to be used for the request. This is
           used to verify the identity of the provider. -->
      <attr name="fontProviderPackage" />
  </declare-styleable>
</resources>
```

`src/main/res/colors.xml`

```xml
<resources>
  <!-- Color for Material Blue-Grey 900. -->
  <color name="material_blue_grey_900">#ff263238</color>
</resources>
```

#### Public declaration

Resources are declared public by providing a separate `<public />` element with
a matching type:

`src/main/res/public.xml`

```xml
<resources>
  <public name="fontProviderPackage" type="attr" />
  <public name="material_blue_grey_900" type="color" />
</resources>
```

#### More information

See also the official Android Gradle Plugin documentation for
[Private Resources](https://developer.android.com/studio/projects/android-library#PrivateResources).

### Manifest entries (`AndroidManifest.xml`) {#resources-manifest}

#### Metadata tags (`<meta-data>`) {#resources-manifest-metadata}

Developers **must not** add `<application>`-level `<meta-data>` tags to library
manifests or advise developers to add such tags to their application manifests.
Doing so may *inadvertently cause denial-of-service attacks against other apps*.

Assume a library adds a single item of meta-data at the application level. When
an app uses the library, that meta-data will be merged into the resulting app's
application entry via manifest merger.

If another app attempts to obtain a list of all activities associated with the
primary app, that list will contain multiple copies of the `ApplicationInfo`,
each of which in turn contains a copy of the library's meta-data. As a result,
one `<metadata>` tag may become hundreds of KB on the binder call to obtain the
list -- resulting in apps hitting transaction too large exceptions and crashing.

```xml {.bad}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="androidx.librarypackage">
  <application>
    <meta-data
        android:name="keyName"
        android:value="@string/value" />
  </application>
</manifest>
```

Instead, developers may consider adding `<metadata>` nested inside of
placeholder `<service>` tags.

```xml {.good}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="androidx.librarypackage">
  <application>
    <service
        android:name="androidx.librarypackage.MetadataHolderService"
        android:enabled="false"
        android:exported="false">
      <meta-data
          android:name="androidx.librarypackage.MetadataHolderService.KEY_NAME"
          android:resource="@string/value" />
    </service>
  </application>
```

```java {.good}
package androidx.libraryname.featurename;

/**
 * A placeholder service to avoid adding application-level metadata. The service
 * is only used to expose metadata defined in the library's manifest. It is
 * never invoked.
 */
public final class MetadataHolderService {
  private MetadataHolderService() {}

  @Override
  public IBinder onBind(Intent intent) {
    throw new UnsupportedOperationException();
  }
}
```

## Dependencies {#dependencies}

Artifacts may depend on other artifacts within AndroidX as well as sanctioned
third-party libraries.

### Versioned artifacts {#dependencies-versioned}

One of the most difficult aspects of independently-versioned releases is
maintaining compatibility with public artifacts. In a mono repo such as Google's
repository or Android Git at master revision, it's easy for an artifact to
accidentally gain a dependency on a feature that may not be released on the same
schedule.

-   Project `project(":core:core")` uses the tip-of-tree sources for the
    `androidx.core:core` library and requires that they be loaded in the
    workspace.
-   Playground `projectOrArtifact(":core:core")` is used for
    [Playground](playground.md) projects and will use tip-of-tree sources, if
    present in the workspace, or `SNAPSHOT` prebuilt artifacts from
    [androidx.dev](http://androidx.dev) otherwise.
-   Explicit `"androidx.core:core:1.4.0"` uses the prebuilt AAR and requires
    that it be checked in to the `prebuilts/androidx/internal` local Maven
    repository.

Libraries should prefer explicit dependencies with the lowest possible versions
that include the APIs or behaviors required by the library, using project or
Playground specs only in cases where tip-of-tree APIs or behaviors are required.

#### Pre-release dependencies {#dependencies-pre-release}

Pre-release suffixes **must** propagate up the dependency tree. For example, if
your artifact has API-type dependencies on pre-release artifacts, ex.
`1.1.0-alpha01`, then your artifact must also carry the `alpha` suffix. If you
only have implementation-type dependencies, your artifact may carry either the
`alpha` or `beta` suffix.

Note: This does not apply to test dependencies: suffixes of test dependencies do
*not* carry over to your artifact.

#### Pinned versions {#dependencies-prebuilt}

To avoid issues with dependency versioning, consider pinning your artifact's
dependencies to the oldest version (available via local `maven_repo` or Google
Maven) that satisfies the artifact's API requirements. This will ensure that the
artifact's release schedule is not accidentally tied to that of another artifact
and will allow developers to use older libraries if desired.

```
dependencies {
   api("androidx.collection:collection:1.0.0")
   ...
}
```

Artifacts should be built and tested against both pinned and tip-of-tree
versions of their dependencies to ensure behavioral compatibility.

#### Tip-of-tree versions {#dependencies-project}

Below is an example of a non-pinned dependency. It ties the artifact's release
schedule to that of the dependency artifact, because the dependency will need to
be released at the same time.

```
dependencies {
   api(project(":collection"))
   ...
}
```

### Non-public APIs {#dependencies-non-public-apis}

Artifacts may depend on non-public (e.g. `@hide`) APIs exposed within their own
artifact or another artifact in the same `groupId`; however, cross-artifact
usages are subject to binary compatibility guarantees and
`@RestrictTo(Scope.LIBRARY_GROUP)` APIs must be tracked like public APIs.

```
Dependency versioning policies are enforced at build time in the createArchive task. This task will ensure that pre-release version suffixes are propagated appropriately.

Cross-artifact API usage policies are enforced by the checkApi and checkApiRelease tasks (see Life of a release).
```

### Third-party libraries {#dependencies-3p}

Artifacts may depend on libraries developed outside of AndroidX; however, they
must conform to the following guidelines:

*   Prebuilt **must** be checked into Android Git with both Maven and Make
    artifacts
    *   `prebuilts/maven_repo` is recommended if this dependency is only
        intended for use with AndroidX artifacts, otherwise please use
        `external`
*   Prebuilt directory **must** contains an `OWNERS` file identifying one or
    more individual owners (e.g. NOT a group alias)
*   Library **must** be approved by legal

Please see Jetpack's [open-source policy page](open_source.md) for more details
on using third-party libraries.

### Types of dependencies {#dependencies-types}

AndroidX allows dependencies to be specified as `api` or `implementation` with a
"pinned" Maven spec (ex. `androidx.core:core:1.0.0`) or a "tip-of-tree" project
spec (ex. `project(":core:core")`).

Projects used in Playground, the experimental GitHub workflow, should use a
"recent" project or artifact spec (ex. `projectOrArtifact(":core:core")`) which
will default to tip-of-tree when used outside of the Playground workflow or a
pinned `SNAPSHOT` artifact otherwise.

Regardless of which dependency spec is used, all projects are built against
tip-of-tree dependencies in CI to prevent regressions and enforce Jetpack's
compatible-at-head policy.

#### `api` versus `implementation` {#dependencies-api-vs-impl}

`api`-type dependencies will appear in clients' auto-complete as though they had
added the dependency directly to their project, and Studio will run any lint
checks bundled with `api`-type dependencies.

Dependencies whose APIs are exposed in a library's API surface **must** be
included as `api`-type. For example, if your library's API surface includes
`AccessibilityNodeInfoCompat` then you will use an `api`-type dependency on the
`androidx.core:core` library.

NOTE Libraries that provide client-facing lint checks, including
`annotation-experimental`, **must** be included as `api`-type to ensure that
lint checks are run in the clients' dependent projects.

`implementation`-type dependencies will be included in the classpath, but will
not be made available at design time (ex. in auto-complete) unless the client
explicitly adds them.

### System health {#dependencies-health}

Generally, Jetpack libraries should avoid dependencies that negatively impact
developers without providing substantial benefit. Libraries should consider the
system health implications of their dependencies, including:

-   Large dependencies where only a small portion is needed (e.g. APK bloat)
-   Dependencies that slow down build times through annotation processing or
    compiler overhead

#### Kotlin {#dependencies-kotlin}

Kotlin is *strongly recommended* for new libraries; however, it's important to
consider its size impact on clients. Currently, the Kotlin stdlib adds a minimum
of 40kB post-optimization. It may not make sense to use Kotlin for a library
that targets Java-only clients or space-constrained (ex. Android Go) clients.

Existing Java-based libraries are *strongly discouraged* from using Kotlin,
primarily because our documentation system does not currently provide a
Java-facing version of Kotlin API reference docs. Java-based libraries *may*
migrate to Kotlin, but they must consider the docs usability and size impacts on
existing Java-only and space-constrained clients.

#### Kotlin coroutines {#dependencies-coroutines}

Kotlin's coroutine library adds around 100kB post-shrinking. New libraries that
are written in Kotlin should prefer coroutines over `ListenableFuture`, but
existing libraries must consider the size impact on their clients. See
[Asynchronous work with return values](#async-return) for more details on using
Kotlin coroutines in Jetpack libraries.

#### Guava {#dependencies-guava}

The full Guava library is very large and *must not* be used. Libraries that
would like to depend on Guava's `ListenableFuture` may instead depend on the
standalone `com.google.guava:listenablefuture` artifact. See
[Asynchronous work with return values](#async-return) for more details on using
`ListenableFuture` in Jetpack libraries.

#### Java 8 {#dependencies-java8}

Libraries that take a dependency on a library targeting Java 8 must *also*
target Java 8, which will incur a ~5% build performance (as of 8/2019) hit for
clients. New libraries targeting Java 8 may use Java 8 dependencies.

The default language level for `androidx` libraries is Java 8, and we encourage
libraries to stay on Java 8. However, if you have a business need to target Java
7, you can specify Java 7 in your `build.gradle` as follows:

```groovy
android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_7
        targetCompatibility = JavaVersion.VERSION_1_7
    }
}
```

#### Protobuf {#dependencies-protobuf}

[Protocol buffers](https://developers.google.com/protocol-buffers) provide a
language- and platform-neutral mechanism for serializing structured data. The
implementation enables developers to maintain protocol compatibility across
library versions, meaning that two clients can communicate regardless of the
library versions included in their APKs.

The Protobuf library itself, however, does not guarantee ABI compatibility
across minor versions and a specific version **must** be bundled with a library
to avoid conflict with other dependencies used by the developer.

Additionally, the Java API surface generated by the Protobuf compiler is not
guaranteed to be stable and **must not** be exposed to developers. Library
owners should wrap the generated API surface with well-documented public APIs
that follow an appropriate language-specific paradigm for constructing data
classes, e.g. the Java `Builder` pattern.

### Open-source compatibility {#dependencies-aosp}

Jetpack's [open-source](open_source.md) principle requires that libraries
consider the open-source compatibility implications of their dependencies,
including:

-   Closed-source or proprietary libraries or services that may not be available
    on AOSP devices
-   Dependencies that may prevent developers from effectively isolating their
    tests from third-party libraries or services

Primary artifacts, e.g. `workmanager`, **must not** depend on closed-source
components including libraries and hard-coded references to packages,
permissions, or IPC mechanisms that may only be fulfulled by closed-source
components.

Optional artifacts, e.g. `workmanager-gcm`, *may* depend on closed-source
components or configure a primary artifact to be backed by a closed-source
component via service discovery or initialization.

Some examples of safely depending on closed-source components include:

-   WorkManager's GCM Network Manager integration, which uses
    [manifest metadata](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-master-dev:work/workmanager-gcm/src/main/AndroidManifest.xml)
    for service discovery and provides an optional artifact exposing the
    service.
-   Ads Identifier's Play Services integration, which provides a default backend
    and uses
    [`Intent` handling](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-master-dev:ads/ads-identifier-provider/src/main/java/androidx/ads/identifier/provider/AdvertisingIdProviderManager.java;l=108)
    as a service discovery mechanism for Play Services.
-   Downloadable Fonts integration with Play Services, which plugs in via a
    [`ContentProvider`](https://cs.android.com/androidx/platform/frameworks/support/+/androidx-master-dev:core/core/src/androidTest/java/androidx/core/provider/MockFontProvider.java)
    as a service discovery mechanism with developer-specified
    [signature verification](https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts#adding-certificates)
    for additional security.

Note that in all cases, the developer is not *required* to use GCM or Play
Services and may instead use another compatible service implementing the same
publicly-defined protocols.

## More API guidelines {#more-api-guidelines}

### Annotations {#annotation}

#### Annotation processors {#annotation-processor}

Annotation processors should opt-in to incremental annotation processing to
avoid triggering a full recompilation on every client source code change. See
Gradle's
[Incremental annotation processing](https://docs.gradle.org/current/userguide/java_plugin.html#sec:incremental_annotation_processing)
documentation for information on how to opt-in.

### `@RequiresOptIn` APIs {#experimental-api}

Jetpack libraries may choose to annotate API surfaces as unstable using either
Kotlin's
[`@RequiresOptIn` meta-annotation](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-requires-opt-in/)
for APIs written in Kotlin or Jetpack's
[`@RequiresOptIn` meta-annotation](https://developer.android.com/reference/kotlin/androidx/annotation/RequiresOptIn)
for APIs written in Java.

> `@RequiresOptIn` at-a-glance:
>
> *   Use for unstable API surfaces
> *   Can be called by anyone
> *   Documented in public documentation
> *   Does not maintain compatibility

For either annotation, API surfaces marked as opt-in are considered alpha and
will be excluded from API compatibility guarantees. Due to the lack of
compatibility guarantees, stable libraries *must never* call experimental APIs
exposed by other libraries outside of their
[same-version group](#same-version-atomic-groups) and *may not* use the `@OptIn`
annotation except in the following cases:

*   A library within a same-version group *may* call an experimental API exposed
    by another library **within its same-version group**. In this case, API
    compatibility guarantees are covered under the same-version group policies
    and the library *may* use the `@OptIn` annotation to prevent propagation of
    the experimental property. **Library owners must exercise care to ensure
    that post-alpha APIs backed by experimental APIs actually meet the release
    criteria for post-alpha APIs.**
*   An `alpha` library may use experimental APIs from outside its same-version
    group. These usages must be removed when the library moves to `beta`.

NOTE JetBrains's own usage of `@RequiresOptIn` in Kotlin language libraries
varies and may indicate binary instability, functional instability, or simply
that an API is really difficult to use. Jetpack libraries should treat instances
of `@RequiresOptIn` in JetBrains libraries as indicating **binary instability**
and avoid using them outside of `alpha`; however, teams are welcome to obtain
written assurance from JetBrains regarding binary stability of specific APIs.
`@RequiresOptIn` APIs that are guaranteed to remain binary compatible *may* be
used in `beta`, but usages must be removed when the library moves to `rc`.

#### When to mark an API surface as experimental

*Do not* use `@RequiresOptIn` for a stable API surface that is difficult to use.
It is not a substitute for a properly-designed API surface.

*Do not* use `@RequiresOptIn` for an API surface that is unreliable or unstable
because it is missing tests. It is not a substitute for a properly-tested API
surface, and all APIs -- including those in `alpha` -- are expected to be
functionally stable.

*Do not* use `@RequiresOptIn` for an internal-facing API surface. Use either the
appropriate language visibility (ex. `private` or `internal`) or `@RestrictTo`.

*Do not* use `@RequiresOptIn` for an API that you expect library developers to
call. Experimental APIs do not maintain binary compatibility guarantees, and you
will put external clients in a difficult situation.

*Do* use `@RequiresOptIn` for API surfaces that must be publicly available and
documented but need the flexibility to stay in `alpha` (and break compatibility)
during the rest of the library's `beta`, `rc`, or stable cycles.

#### How to mark an API surface as experimental

All libraries using `@RequiresOptIn` annotations *must* depend on the
`androidx.annotation:annotation-experimental` artifact regardless of whether
they are using the `androidx` or Kotlin annotation. This artifact provides Lint
enforcement of experimental usage restrictions for Kotlin callers as well as
Java (which the Kotlin annotation doesn't handle on its own, since it's a Kotlin
compiler feature). Libraries *may* include the dependency as `api`-type to make
`@OptIn` available to Java clients; however, this will also unnecessarily expose
the `@RequiresOptIn` annotation.

```java
dependencies {
    implementation(project(":annotation:annotation-experimental"))
}
```

See Kotlin's
[opt-in requirements documentation](https://kotlinlang.org/docs/reference/opt-in-requirements.html)
for general usage information. If you are writing experimental Java APIs, you
will use the Jetpack
[`@RequiresOptIn` annotation](https://developer.android.com/reference/kotlin/androidx/annotation/RequiresOptIn)
rather than the Kotlin compiler's annotation.

#### How to transition an API out of experimental

When an API surface is ready to transition out of experimental, the annotation
may only be removed during an alpha pre-release stage. Removing the experimental
marker from an API is equivalent to adding the API to the current API surface.

When transitioning an entire feature surface out of experimental, you *should*
remove the definition for the associated annotation.

When making any change to the experimental API surface, you *must* run
`./gradlew updateApi` prior to uploading your change.

### `@RestrictTo` APIs {#restricted-api}

Jetpack's library tooling supports hiding Java-visible (ex. `public` and
`protected`) APIs from developers using a combination of the `@RestrictTo`
source annotation, and the `@hide` docs annotation (`@suppress` in Kotlin).
These annotations **must** be paired together when used, and are validated as
part of presubmit checks for Java code.

> `@RestrictTo` at-a-glance:
>
> *   Use for internal-facing API surfaces
> *   Can be called within the specified `Scope`
> *   Does not appear in public documentation
> *   Does not maintain compatibility in most scopes

While restricted APIs do not appear in documentation and Android Studio will
warn against calling them, hiding an API does *not* provide strong guarantees
about usage:

*   There are no runtime restrictions on calling hidden APIs
*   Android Studio will not warn if hidden APIs are called using reflection
*   Hidden APIs will still show in Android Studio's auto-complete

#### When to use `@hide` {#restricted-api-usage}

In other cases, avoid using `@hide` / `@suppress`. These annotations indicates
that developers should not call an API that is *technically* public from a Java
visibility perspective. Hiding APIs is often a sign of a poorly-abstracted API
surface, and priority should be given to creating public, maintainable APIs and
using Java visibility modifiers.

*Do not* use `@hide`/`@suppress` to bypass API tracking and review for
production APIs; instead, rely on API+1 and API Council review to ensure APIs
are reviewed on a timely basis.

*Do not* use `@hide`/`@suppress` for implementation detail APIs that are used
between libraries and could reasonably be made public.

*Do* use `@hide`/`@suppress` paired with `@RestrictTo(LIBRARY)` for
implementation detail APIs used within a single library (but prefer Java
language `private` or `default` visibility).

#### `RestrictTo.Scope` and inter- versus intra-library API surfaces {#private-api-types}

To maintain binary compatibility between different versions of libraries,
restricted API surfaces that are used between libraries within Jetpack
(inter-library APIs) must follow the same Semantic Versioning rules as public
APIs. Inter-library APIs should be annotated with the
`@RestrictTo(LIBRARY_GROUP)` source annotation and `@hide` docs annotation.

Restricted API surfaces used within a single library (intra-library APIs), on
the other hand, may be added or removed without any compatibility
considerations. It is safe to assume that developers *never* call these APIs,
even though it is technically feasible. Intra-library APIs should be annotated
with the `@RestrictTo(LIBRARY)` source annotation and `@hide` docs annotation.

In all cases, correctness and compatibility tracking are handled by AndroidX's
build system and lint checks.

The following table shows the visibility of a hypothetical API within Maven
coordinate `androidx.concurrent:concurrent` when annotated with a variety of
scopes:

<table>
    <tr>
        <td><code>RestrictTo.Scope</code></td>
        <td>Visibility by Maven coordinate</td>
        <td>Versioning</td>
        <td>Note</td>
    </tr>
    <tr>
        <td><code>LIBRARY</code></td>
        <td><code>androidx.concurrent:concurrent</code></td>
        <td>No compatibility guarantees (same as private)</td>
        <td></td>
    </tr>
    <tr>
        <td><code>LIBRARY_GROUP</code></td>
        <td><code>androidx.concurrent:*</code></td>
        <td>Semantic versioning (including deprecation)</td>
        <td></td>
    </tr>
    <tr>
        <td><code>LIBRARY_GROUP_PREFIX</code></td>
        <td><code>androidx.*:*</code></td>
        <td>Semantic versioning (including deprecation)</td>
        <td></td>
    </tr>
    <tr>
        <td><code>TEST</code></td>
        <td><code>*</code></td>
        <td>No compatibility guarantees (same as private)</td>
        <td>Not recommended. Prefer language visibility, e.g. `internal` or package-private.</td>
    </tr>
</table>

#### `@IntDef` `@StringDef` and `@LongDef` and visibility

All `@IntDef`, `@StringDef`, and `@LongDef` will be stripped from resulting
artifacts to avoid issues where compiler inlining constants removes information
as to which `@IntDef` defined the value of `1`. The annotations are extracted
and packaged separately to be read by Android Studio and lint which enforces the
types in application code.

*   Libraries *must* `@hide` all `@IntDef`, `@StringDef`, and `@LongDef`
    declarations.
*   Libraries *must* expose constants used to define the `@IntDef` etc at the
    same Java visibility as the hidden `@IntDef`
*   Libraries *must* use `@RestrictTo` to create a warning when the type is used
    incorrectly.

Here is a complete example of an `@IntDef`

```java
// constants match Java visibility of ExifStreamType
// code outside this module interacting with ExifStreamType uses these constants
public static final int STREAM_TYPE_FULL_IMAGE_DATA = 1;
public static final int STREAM_TYPE_EXIF_DATA_ONLY = 2;

/** @hide */
@RestrictTo(RestrictTo.Scope.LIBRARY) // Don't export ExifStreamType outside module
@Retention(RetentionPolicy.SOURCE)
@IntDef({
  STREAM_TYPE_FULL_IMAGE_DATA,
  STREAM_TYPE_EXIF_DATA_ONLY,
})
public @interface ExifStreamType {}
```

Java visibilty should be set as appropriate for the code in question (`private`,
`package` or `public`) and is unrelated to hiding.

For more, read the section in
[Android API Council Guidelines](https://android.googlesource.com/platform/developers/docs/+/refs/heads/master/api-guidelines/index.md#no-public-typedefs)

### Constructors {#constructors}

#### View constructors {#view-constructors}

The four-arg View constructor -- `View(Context, AttributeSet, int, int)` -- was
added in SDK 21 and allows a developer to pass in an explicit default style
resource rather than relying on a theme attribute to resolve the default style
resource. Because this API was added in SDK 21, care must be taken to ensure
that it is not called through any < SDK 21 code path.

Views *may* implement a four-arg constructor in one of the following ways:

1.  Do not implement.
1.  Implement and annotate with `@RequiresApi(21)`. This means the three-arg
    constructor **must not** call into the four-arg constructor.

### Asynchronous work {#async}

#### With return values {#async-return}

###### Kotlin

Traditionally, asynchronous work on Android that results in an output value
would use a callback; however, better alternatives exist for libraries.

Kotlin libraries should consider
[coroutines](https://kotlinlang.org/docs/reference/coroutines-overview.html) and
`suspend` functions for APIs according to the following rules, but please refer
to the guidance on [allowable dependencies](#dependencies-coroutines) before
adding a new dependency on coroutines.

Kotlin suspend fun vs blocking       | Behavior
------------------------------------ | --------------------------
blocking function with @WorkerThread | API is blocking
suspend                              | API is async (e.g. Future)

In general, do not introduce a suspend function entirely to switch threads for
blocking calls. To do so correctly requires that we allow the developer to
configure the Dispatcher. As there is already a coroutines-based API for
changing dispatchers (withContext) that the caller may use to switch threads, it
is unecessary API overhead to provide a duplicate mechanism. In addition, it
unecessary limits callers to coroutine contexts.

```kotlin
// DO expose blocking calls as blocking calls
@WorkerThread
fun blockingCall()

// DON'T wrap in suspend functions (only to switch threads)
suspend fun blockingCallWrappedInSuspend(
  dispatcher: CoroutineDispatcher = Dispatchers.Default
) = withContext(dispatcher) { /* ... */ }

// DO expose async calls as suspend funs
suspend fun asyncCall(): ReturnValue

// DON'T expose async calls as a callback-based API (for the main API)
fun asyncCall(executor: Executor, callback: (ReturnValue) -> Unit)
```

###### Java

Java libraries should prefer `ListenableFuture` and the
[`CallbackToFutureAdapter`](https://developer.android.com/reference/androidx/concurrent/futures/CallbackToFutureAdapter)
implementation provided by the `androidx.concurrent:concurrent-futures` library.
Functions and methods that return `ListenableFuture` should be suffixed by,
`Async` to reserve the shorter, unmodified name for a `suspend` method or
extension function in Kotlin that returns the value normally in accordance with
structured concurrency.

Libraries **must not** use `java.util.concurrent.CompletableFuture`, as it has a
large API surface that permits arbitrary mutation of the future's value and has
error-prone defaults.

See the [Dependencies](#dependencies) section for more information on using
Kotlin coroutines and Guava in your library.

#### Cancellation

Libraries that expose APIs for performing asynchronous work should support
cancellation. There are *very few* cases where it is not feasible to support
cancellation.

Libraries that use `ListenableFuture` must be careful to follow the exact
specification of
[`Future.cancel(boolean mayInterruptIfRunning)`](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html?is-external=true#cancel-boolean-)
behavior.

```java {.bad}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
    // Does not support cancellation.
    return false;
}
```

```java {.bad}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
    // Aggressively does not support cancellation.
    throw new UnsupportedOperationException();
}
```

```java {.good}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
    // Pseudocode that ignores threading but follows the spec.
    if (mCompleted
            || mCancelled
            || mRunning && !mayInterruptIfRunning) {
        return false;
    }
    mCancelled = true;
    return true;
}
```

#### Avoid `synchronized` methods

Whenever multiple threads are interacting with shared (mutable) references those
reads and writes must be synchronized in some way. However synchronized blocks
make your code thread-safe at the expense of concurrent execution. Any time
execution enters a synchronized block or method any other thread trying to enter
a synchronized block on the same object has to wait; even if in practice the
operations are unrelated (e.g. they interact with different fields). This can
dramatically reduce the benefit of trying to write multi-threaded code in the
first place.

Locking with synchronized is a heavyweight form of ensuring ordering between
threads, and there are a number of common APIs and patterns that you can use
that are more lightweight, depending on your use case:

*   Compute a value once and make it available to all threads
*   Update Set and Map data structures across threads
*   Allow a group of threads to process a stream of data concurrently
*   Provide instances of a non-thread-safe type to multiple threads
*   Update a value from multiple threads atomically
*   Maintain granular control of your concurrency invariants

### Kotlin {#kotlin}

#### Nullability from Java (new APIs)

All new Java APIs should be annotated either `@Nullable` or `@NonNull` for all
reference parameters and reference return types.

```java
    @Nullable
    public Object someNewApi(@NonNull Thing arg1, @Nullable List<WhatsIt> arg2) {
        if(/** something **/) {
            return someObject;
        } else {
            return null;
    }
```

#### Nullability from Java (existing APIs)

Adding `@Nullable` or `@NonNull` annotations to existing APIs to document their
existing nullability is OK. This is a source breaking change for Kotlin
consumers, and you should ensure that it's noted in the release notes and try to
minimize the frequency of these updates in releases.

Changing the nullability of an API is a breaking change.

#### Extending APIs that expose types without nullability annotations

[Platform types](https://kotlinlang.org/docs/java-interop.html#null-safety-and-platform-types)
are exposed by Java types that do not have a `@Nullable` or `@NonNull`
annotation. In Kotlin they are indicated with the `!` suffix.

When interacting with an Android platform API that exposes APIs with unknown
nullability follow these rules:

1.  If wrapping the type in a new API, define and handle `@Nullable` or
    `@NonNull` in the library. Treat types with unknown nullability passed into
    or return from Android as `@Nullable` in the library.
2.  If extending an existing API (e.g. `@Override`), pass through the existing
    types with unknown nullability and annotate each with
    `@SuppressLint("UnknownNullness")`

In Kotlin, a type with unknown nullability is exposed as a "platform type"
(indicated with a `!` suffix) which has unknown nullability in the type checker,
and may bypass type checking leading to runtime errors. When possible, do not
directly expose types with unknown nullability in new public APIs.

#### Extending `@RecentlyNonNull` and `@RecentlyNullable` APIs

Platform APIs are annotated in the platform SDK artifacts with fake annotations
`@RecentlyNonNull` and `@RecentlyNullable` to avoid breaking builds when we
annotated platform APIs with nullability. These annotations cause warnings
instead of build failures. The `RecentlyNonNull` and `RecentlyNullable`
annotations are added by Metalava and do not appear in platform code.

When extending an API that is annotated `@RecentlyNonNull`, you should annotate
the override with `@NonNull`, and the same for `@RecentlyNullable` and
`@Nullable`.

For example `SpannableStringBuilder.append` is annotated `RecentlyNonNull` and
an override should look like:

```java
    @NonNull
    @Override
    public SpannableStringBuilder append(@SuppressLint("UnknownNullness") CharSequence text) {
        super.append(text);
        return this;
    }
```

#### Data classes {#kotlin-data}

Kotlin `data` classes provide a convenient way to define simple container
objects, where Kotlin will generate `equals()` and `hashCode()` for you.
However, they are not designed to preserve API/binary compatibility when members
are added. This is due to other methods which are generated for you -
[destructuring declarations](https://kotlinlang.org/docs/reference/multi-declarations.html),
and [copying](https://kotlinlang.org/docs/reference/data-classes.html#copying).

Example data class as tracked by metalava:

<pre>
  public final class TargetAnimation {
    ctor public TargetAnimation(float target, androidx.animation.AnimationBuilder animation);
    <b>method public float component1();</b>
    <b>method public androidx.animation.AnimationBuilder component2();</b>
    <b>method public androidx.animation.TargetAnimation copy(float target, androidx.animation.AnimationBuilder animation);</b>
    method public androidx.animation.AnimationBuilder getAnimation();
    method public float getTarget();
  }
</pre>

Because members are exposed as numbered components for destructuring, you can
only safely add members at the end of the member list. As `copy` is generated
with every member name in order as well, you'll also have to manually
re-implement any old `copy` variants as items are added. If these constraints
are acceptable, data classes may still be useful to you.

As a result, Kotlin `data` classes are *strongly discouraged* in library APIs.
Instead, follow best-practices for Java data classes including implementing
`equals`, `hashCode`, and `toString`.

See Jake Wharton's article on
[Public API challenges in Kotlin](https://jakewharton.com/public-api-challenges-in-kotlin/)
for more details.

#### Exhaustive `when` and `sealed class`/`enum class` {#exhaustive-when}

A key feature of Kotlin's `sealed class` and `enum class` declarations is that
they permit the use of **exhaustive `when` expressions.** For example:

```kotlin
enum class CommandResult { Permitted, DeniedByUser }

val message = when (commandResult) {
    Permitted -> "the operation was permitted"
    DeniedByUser -> "the user said no"
}

println(message)
```

This highlights challenges for library API design and compatibility. Consider
the following addition to the `CommandResult` possibilities:

```kotlin {.bad}
enum class CommandResult {
    Permitted,
    DeniedByUser,
    DeniedByAdmin // New in androidx.mylibrary:1.1.0!
}
```

This change is both **source and binary breaking.**

It is **source breaking** because the author of the `when` block above will see
a compiler error about not handling the new result value.

It is **binary breaking** because if the `when` block above was compiled as part
of a library `com.example.library:1.0.0` that transitively depends on
`androidx.mylibrary:1.0.0`, and an app declares the dependencies:

```kotlin
implementation("com.example.library:1.0.0")
implementation("androidx.mylibrary:1.1.0") // Updated!
```

`com.example.library:1.0.0` does not handle the new result value, leading to a
runtime exception.

**Note:** The above example is one where Kotlin's `enum class` is the correct
tool and the library should **not** add a new constant! Kotlin turns this
semantic API design problem into a compiler or runtime error. This type of
library API change could silently cause app logic errors or data corruption
without the protection provided by exhaustive `when`. See
[When to use exhaustive types](#when-to-use-exhaustive-types).

`sealed class` exhibits the same characteristic; adding a new subtype of an
existing sealed class is a breaking change for the following code:

```kotlin
val message = when (command) {
    is Command.Migrate -> "migrating to ${command.destination}"
    is Command.Quack -> "quack!"
}
```

##### Non-exhaustive alternatives to `enum class`

Kotlin's `@JvmInline value class` with a `private constructor` can be used to
create type-safe sets of non-exhaustive constants as of Kotlin 1.5. Compose's
`BlendMode` uses the following pattern:

```kotlin {.good}
@JvmInline
value class BlendMode private constructor(val value: Int) {
    companion object {
        /** Drop both the source and destination images, leaving nothing. */
        val Clear = BlendMode(0)
        /** Drop the destination image, only paint the source image. */
        val Src = BlendMode(1)
        // ...
    }
}
```

**Note:** This recommendation may be temporary. Kotlin may add new annotations
or other language features to declare non-exhaustive enum classes in the future.

Alternatively, the existing `@IntDef` mechanism used in Java-language androidx
libraries may also be used, but type checking of constants will only be
performed by lint, and functions overloaded with parameters of different value
class types are not supported. Prefer the `@JvmInline value class` solution for
new code unless it would break local consistency with other API in the same
module that already uses `@IntDef`.

##### Non-exhaustive alternatives to `sealed class`

Abstract classes with constructors marked as `internal` or `private` can
represent the same subclassing restrictions of sealed classes as seen from
outside of a library module's own codebase:

```kotlin
abstract class Command private constructor() {
    class Migrate(val destination: String) : Command()
    object Quack : Command()
}
```

Using an `internal` constructor will permit non-nested subclasses, but will
**not** restrict subclasses to the same package within the module, as sealed
classes do.

##### When to use exhaustive types

Use `enum class` or `sealed class` when the values or subtypes are intended to
be exhaustive by design from the API's initial release. Use non-exhaustive
alternatives when the set of constants or subtypes might expand in a minor
version release.

Consider using an **exhaustive** (`enum class` or `sealed class`) type
declaration if:

*   The developer is expected to **accept** values of the type
*   The developer is expected to **act** on **any and all** values received

Consider using a **non-exhaustive** type declaration if:

*   The developer is expected to **provide** values of the type to APIs exposed
    by the same module **only**
*   The developer is expected to **ignore** unknown values received

The `CommandResult` example above is a good example of a type that **should**
use the exhaustive `enum class`; `CommandResult`s are **returned** to the
developer and the developer cannot implement correct app behavior by ignoring
unrecognized result values. Adding a new result value would semantically break
existing code regardless of the language facility used to express the type.

```kotlin {.good}
enum class CommandResult { Permitted, DeniedByUser, DeniedByAdmin }
```

Compose's `BlendMode` is a good example of a type that **should not** use the
exhaustive `enum class`; blending modes are used as arguments to Compose
graphics APIs and are not intended for interpretation by app code. Additionally,
there is historical precedent from `android.graphics` for new blending modes to
be added in the future.

#### Extension and top-level functions {#kotlin-extension-functions}

If your Kotlin file contains any symbols outside of class-like types
(extension/top-level functions, properties, etc), the file must be annotated
with `@JvmName`. This ensures unanticipated use-cases from Java callers don't
get stuck using `BlahKt` files.

Example:

```kotlin {.bad}
package androidx.example

fun String.foo() = // ...
```

```kotlin {.good}
@file:JvmName("StringUtils")

package androidx.example

fun String.foo() = // ...
```

NOTE This guideline may be ignored for libraries that only work in Kotlin (think
Compose).

## Testing Guidelines

### [Do not Mock, AndroidX](do_not_mock.md)

## Android Lint Guidelines

### Suppression vs Baselines

Lint sometimes flags false positives, even though it is safe to ignore these
errors (for example WeakerAccess warnings when you are avoiding synthetic
access). There may also be lint failures when your library is in the middle of a
beta / rc / stable release, and cannot make the breaking changes needed to fix
the root cause. There are two ways of ignoring lint errors:

1.  Suppression - using `@SuppressLint` (for Java) or `@Suppress` annotations to
    ignore the warning per call site, per method, or per file. *Note
    `@SuppressLint` - Requires Android dependency*.
2.  Baselines - allowlisting errors in a lint-baseline.xml file at the root of
    the project directory.

Where possible, you should use a **suppression annotation at the call site**.
This helps ensure that you are only suppressing the *exact* failure, and this
also keeps the failure visible so it can be fixed later on. Only use a baseline
if you are in a Java library without Android dependencies, or when enabling a
new lint check, and it is prohibitively expensive / not possible to fix the
errors generated by enabling this lint check.

To update a lint baseline (`lint-baseline.xml`) after you have fixed issues, run
the `updateLintBaseline` task.

```shell
./gradlew :core:core:updateLintBaseline
```

## Metalava API Lint

As well as Android Lint, which runs on all source code, Metalava will also run
checks on the public API surface of each library. Similar to with Android Lint,
there can sometimes be false positives / intended deviations from the API
guidelines that Metalava will lint your API surface against. When this happens,
you can suppress Metalava API lint issues using `@SuppressLint` (for Java) or
`@Suppress` annotations. In cases where it is not possible, update Metalava's
baseline with the `updateApiLintBaseline` task.

```shell
./gradlew :core:core:updateApiLintBaseline
```

This will create/amend the `api_lint.ignore` file that lives in a library's
`api` directory.

## Build Output Guidelines

In order to more easily identify the root cause of build failures, we want to
keep the amount of output generated by a successful build to a minimum.
Consequently, we track build output similarly to the way in which we track Lint
warnings.

### Invoking build output validation

You can add `-Pandroidx.validateNoUnrecognizedMessages` to any other AndroidX
gradlew command to enable validation of build output. For example:

```shell
/gradlew -Pandroidx.validateNoUnrecognizedMessages :help
```

### Exempting new build output messages

Please avoid exempting new build output and instead fix or suppress the warnings
themselves, because that will take effect not only on the build server but also
in Android Studio, and will also run more quickly.

If you cannot prevent the message from being generating and must exempt the
message anyway, follow the instructions in the error:

```shell
$ ./gradlew -Pandroidx.validateNoUnrecognizedMessages :help

Error: build_log_simplifier.py found 15 new messages found in /usr/local/google/workspace/aosp-androidx-git/out/dist/gradle.log.

Please fix or suppress these new messages in the tool that generates them.
If you cannot, then you can exempt them by doing:

  1. cp /usr/local/google/workspace/aosp-androidx-git/out/dist/gradle.log.ignore /usr/local/google/workspace/aosp-androidx-git/frameworks/support/development/build_log_simplifier/messages.ignore
  2. modify the new lines to be appropriately generalized
```

Each line in this exemptions file is a regular expressing matching one or more
lines of output to be exempted. You may want to make these expressions as
specific as possible to ensure that the addition of new, similar messages will
also be detected (for example, discovering an existing warning in a new source
file).

## Behavior changes

### Changes that affect API documentation

Do not make behavior changes that require altering API documentation in a way
that would break existing clients, even if such changes are technically binary
compatible. For example, changing the meaning of a method's return value to
return true rather than false in a given state would be considered a breaking
change. Because this change is binary-compatible, it will not be caught by
tooling and is effectively invisible to clients.

Instead, add new methods and deprecate the existing ones if necessary, noting
behavior changes in the deprecation message.

### High-risk behavior changes

Behavior changes that conform to documented API contracts but are highly complex
and difficult to comprehensively test are considered high-risk and should be
implemented using behavior flags. These changes may be flagged on initially, but
the original behaviors must be preserved until the library enters release
candidate stage and the behavior changes have been appropriately verified by
integration testing against public pre-release
revisions.

It may be necessary to soft-revert a high-risk behavior change with only 24-hour
notice, which should be achievable by flipping the behavior flag to off.

```java
// Flag for whether to throw exceptions when the state is known to be bad. This
// is expected to be a high-risk change since apps may be working fine even with
// a bad state, so we may need to disable this as a hotfix.
private static final boolean FLAG_EXCEPTION_ON_BAD_STATE = false;
```

```java
/**
 * Allows a developer to toggle throwing exceptions when the state is known to
 * be bad. This method is intended to give developers time to update their code.
 * It is temporary and will be removed in a future release.
 */
@TemporaryFeatureFlag
public void setExceptionOnBadStateEnabled(boolean enabled);
```

Avoid adding multiple high-risk changes during a feature cycle, as verifying the
interaction of multiple feature flags leads to unnecessary complexity and
exposes clients to high risk even when a single change is flagged off. Instead,
wait until one high-risk change has landed in RC before moving on to the next.

#### Testing

Relevant tests should be run for the behavior change in both the on and off
flagged states to prevent regressions.

## Sample code in Kotlin modules

### Background

Public API can (and should!) have small corresponding code snippets that
demonstrate functionality and usage of a particular API. These are often exposed
inline in the documentation for the function / class - this causes consistency
and correctness issues as this code is not compiled against, and the underlying
implementation can easily change.

KDoc (JavaDoc for Kotlin) supports a `@sample` tag, which allows referencing the
body of a function from documentation. This means that code samples can be just
written as a normal function, compiled and linted against, and reused from other
modules such as tests! This allows for some guarantees on the correctness of a
sample, and ensuring that it is always kept up to date.

### Enforcement

There are still some visibility issues here - it can be hard to tell if a
function is a sample, and is used from public documentation - so as a result we
have lint checks to ensure sample correctness.

Primarily, there are three requirements when using sample links:

1.  All functions linked to from a `@sample` KDoc tag must be annotated with
    `@Sampled`
2.  All sample functions annotated with `@Sampled` must be linked to from a
    `@sample` KDoc tag
3.  All sample functions must live inside a separate `samples` library
    submodule - see the section on module configuration below for more
    information.

This enforces visibility guarantees, and make it easier to know that a sample is
a sample. This also prevents orphaned samples that aren't used, and remain
unmaintained and outdated.

### Sample usage

The follow demonstrates how to reference sample functions from public API. It is
also recommended to reuse these samples in unit tests / integration tests / test
apps / library demos where possible to help ensure that the samples work as
intended.

**Public API:**

```
/*
 * Fancy prints the given [string]
 *
 * @sample androidx.printer.samples.fancySample
 */
fun fancyPrint(str: String) ...
```

**Sample function:**

```
package androidx.printer.samples

import androidx.printer.fancyPrint

@Sampled
fun fancySample() {
   fancyPrint("Fancy!")
}
```

**Generated documentation visible on d.android.com / within Android Studio**

```
fun fancyPrint(str: String)

Fancy prints the given [string]

<code>
 import androidx.printer.fancyPrint

 fancyPrint("Fancy!")
<code>
```

Warning: Only the body of the function is used in generated documentation, so
any other references to elements defined outside the body of the function (such
as variables defined within the sample file) will not be visible. To ensure that
samples can be easily copy and pasted without errors, make sure that any
references are defined within the body of the function.

### Module configuration

The following module setups should be used for sample functions:

**Per-module samples**

For library groups with relatively independent sub-libraries. This is the
recommended project setup, and should be used in most cases.

Gradle project name: `:foo-library:foo-module:foo-module-samples`

```
foo-library/
  foo-module/
    samples/
```

**Group-level samples**

For library groups with strongly related samples that want to share code and be
reused across a library group, a singular shared samples library can be created.
In most cases this is discouraged - samples should be small and show the usage
of a particular API / small set of APIs, instead of more complicated usage
combining multiple APIs from across libraries. For these cases a sample
application is more appropriate.

Gradle project name: `:foo-library:foo-library-samples`

```
foo-library/
  foo-module/
  bar-module/
  samples/
```

**Samples module configuration**

Samples modules are published to GMaven so that they are available to Android
Studio, which displays referenced samples as hover-over pop-ups.

To achieve this, samples modules must declare the same MavenGroup and `publish`
as the library(s) they are samples for.
