SDK Runtime

Provide feedback

The Android platform uses the concept of app sandboxing to maintain robust execution and security boundaries for app code, along process boundaries. It's a common practice for apps to include third-party code, often in the form of SDKs such as ads SDKs or analytics SDKs. This reuse enables app developers to focus on their app's differentiation while leveraging the work of subject matter experts to scale their execution beyond what they could easily do on their own.

Like most operating systems, in Android SDKs are executed within the host app's sandbox, and inherit the same privileges and permissions of their host app as well as access to the host app's memory and storage. While this architecture enables SDKs and apps to flexibly integrate, it also creates the potential for undisclosed user data collection and sharing. Moreover, app developers may not be fully aware of the extent of a third-party SDK's functionality and the data it accesses, making it challenging to account for the data collection and sharing practices of their app.

In Android 13, we have added a new platform capability that allows third-party SDKs to run in a dedicated runtime environment called the SDK Runtime. The SDK Runtime provides the following stronger safeguards and guarantees around user data collection and sharing:

  • A modified execution environment
  • Well-defined permissions and data access rights for SDKs

Goals

This proposal seeks to achieve the following goals:

  • Reduce undisclosed access and sharing of a user's app data by third-party SDKs through process isolation and well-defined API and data access control. Learn more about process isolation in a separate section of this document.
  • Reduce undisclosed tracking of a user's app usage by third-party SDKs by limiting unique, persistent identifiers from being accessed by SDKs.
  • Securely accelerate the distribution of SDK updates to apps by reducing the burden on app developers and end users. Learn more about the proposed trusted SDK distribution model in another section of this document.
  • Help app developers better account for the data access and sharing practices of their app.
  • Help SDK developers prevent tampering by other SDKs through the limiting of certain unsafe language constructs such as JNI code.
  • Help ads SDKs detect and prevent invalid traffic and ad fraud through full control over the remote views displaying media.
  • Minimize undue impact to app and SDK developers as much as possible.

SDKs execute in an isolated process

The proposed SDK Runtime enables compatible SDKs—referred to throughout the remainder of this document as runtime-enabled (RE) SDKs—to operate in a separate process for the app. The platform facilitates bi-directional communication between the app's process and its SDK Runtime. See the communications section of this document for detail. Non-RE SDKs would remain in the app's process as they do today. Figure 1 illustrates these changes:

Before:


After:

Figure 1. Relative locations of runtime-enabled SDKs before and after being added to the SDK Runtime. The "before" diagram (first) shows that the SDK-calling code, along with the SDKs that receive the calls from this code, all reside in the app's process. The "after" diagram (second) shows that, in the app's foreground process, the SDK calling code communicates with SDK interfaces. These interfaces then cross a process boundary into the SDK Runtime process to call into the SDKs themselves.

New trusted distribution model for SDKs

This proposed separation of SDK from app motivates another separation concept, one for SDK and app distribution. Our proposal requires a trusted distribution and installation mechanism, to ensure the correct SDKs are installed in an app's SDK Runtime. This helps protect users and app developers from invalid SDKs being loaded, while enabling app stores to significantly reduce the burden of SDK distribution from app developers.

SDKs would no longer need to be statically linked and packaged together with their apps before being uploaded to an app store for distribution. The following process would occur instead:

  1. SDK developers could upload their versioned SDKs to the app stores, separate from the apps themselves.
  2. App developers could specify their SDK dependencies by version, build, and upload an app release that doesn't include the actual SDK dependencies.
  3. When a user downloads this app, the installation process could use the app's specified SDK dependencies to then download them from the app store.

This novel distribution mechanism would enable SDK developers to make non-breaking changes (that is, no changes to APIs or their semantics) to their SDKs and distribute to devices without any involvement from app developers. These non-breaking SDK changes could be deployed or rolled back, without necessarily needing to wait for app developers to rebuild their apps with the new SDKs, or waiting for end users to update their apps. Breaking changes would still need to be updated by app developers, but SDK developers could get their latest non-breaking changes and fixes out more quickly and more uniformly to more people, ideally minimizing version support.

Figure 2 illustrates the proposed changes in SDK distribution:

Before:

Before diagram

After:

After diagram
Figure 2. SDK distribution design, before and after the introduction of the SDK Runtime. SDK developers would no longer send their SDKs directly to apps; instead, the SDK developers would use an SDK upload UI to publish their SDKs to an app store. The app store would then handle the distribution of apps, along with any SDK dependencies, to end-user devices.

Changes to how SDKs and apps are built, run, and distributed

This is an initial proposal for a flexible SDK Runtime and distribution technology. The following sections propose a series of changes across the following broad categories:

  • Access: Permissions, memory, storage
  • Execution: Languages, runtime changes, lifecycle, media rendering
  • Communications: App-to-SDK and SDK-to-SDK
  • Development: How to build, debug, test in this model
  • Distribution: How to distribute, update, roll back across versions of Android, apps and SDKs

This document also includes an FAQ to help address common questions.

This is an initial design proposal, and we understand this may be a meaningful change for some members of the ecosystem. This is why we are actively soliciting your feedback and ask that you do so through the issue tracker.

Access

Managing the privacy of a system implies managing how different parties can access different resources. To meet our privacy value proposition we propose updating the model for accessing apps, SDKs, and user data to follow the principle of least privilege to prevent undisclosed access of potentially sensitive data.

SDK permissions

As a separate process, the SDK Runtime would have its own well-defined set of permissions, rather than inherit those that the user granted the app. Based on preliminary research on the permissions used by ads-related SDKs, we're proposing that the following permissions would be accessible to SDKs in the SDK Runtime by default:

  • INTERNET: Access to the internet to be able to communicate with a web service.
  • ACCESS_NETWORK_STATE: Access information about networks.
  • Permissions to access the privacy-preserving APIs, which provide core advertising capabilities without needing access to cross-app identifiers.
  • AD_ID: Ability to request the advertising ID. This would also be gated by the app's access to this permission.
  • BIND_GET_INSTALL_REFERRER_SERVICE: Ability to use the Google Play Install Referrer API to attribute the source of an app's installation.

We are currently investigating whether and how to authorize additional permissions, limiting the impact on end users from both a privacy and a usability perspective. We request feedback on any use cases that may not be met by this set of permissions.

Memory

The SDK Runtime would have its own isolated memory space by virtue of having its own process. This structure by default would deny the SDK access to the app's memory space, and the application would similarly not be able to access the SDK's memory space. We propose keeping this default behavior to keep aligned with the principle of least privilege.

Storage

This proposal intends to balance the need for SDKs to access storage for their normal operation and minimize cross-app and across-process tracking using persistent storage. We are proposing the following update to how storage is accessed today:

  • An app won't be able to directly access its SDKs storage, and vice versa.
  • The device's external storage won't be accessible to SDKs.
  • Within each SDK Runtime, there would be both storage accessible to all SDKs, and storage that's private to a given SDK.

Like the current storage model, the storage itself won't have arbitrary limits in size. SDKs can use storage for caching assets. This storage is periodically cleared when the SDK is not actively running.

Execution

To ensure a private system between apps, SDKs, and users, the execution context itself (code formats, language constructs, accessible APIs, and system data) needs to reinforce these privacy boundaries, or at the very least not introduce opportunities to circumvent them. At the same time, we want to preserve access to the rich platform and the majority of runtime capabilities that SDKs currently have. Here we propose a set of updates to the runtime environment to strike this balance.

Code

Android code (apps and SDKs) is predominantly interpreted by the Android Runtime (ART), whether the code was written in Kotlin or Java. The richness of the ART and the language constructs it offers, coupled with the verifiability it offers when compared with alternatives—in particular native code—seems to appropriately balance functionality and privacy. We propose that runtime-enabled SDK code consist exclusively of Dex bytecode, rather than support JNI access.

We are aware that there are use cases, such as the use of custom packaged SQLite, which, given the use of native code, will need to be replaced with an alternative such as the Android SDK's built-in version of SQLite.

SELinux

On Android, each process (including those running as root) runs with a specific SELinux context, allowing the kernel to manage access control to system services, files, devices, and other processes. In seeking to preserve the majority of SDK use cases while minimizing circumvention of the privacy protections we are trying to move forward, we are proposing the following updates from a non-system app's SELinux context for the SDK Runtime:

  • A limited set of system services would be accessible. (under active design)
  • SDKs would only be able to load and execute the code in their APK.
  • A limited set of system properties would be accessible. (under active design)

APIs

The use of reflection and invoking APIs within the SDK runtime is allowed. However, an SDK will not be allowed to use reflection or invoke APIs on another runtime-enabled SDK. We will share a full proposal of prohibited APIs in a future update.

In addition, recent Android platform releases have increasingly restricted access to persistent identifiers in order to improve privacy. For the SDK Runtime we propose further limiting access to identifiers which could be used for cross-app tracking.

SDK Runtime APIs are only accessible from apps running in the foreground. Attempting to access SdkSandboxManager APIs from apps in the background results in a SecurityException being thrown.

Lastly, RE-SDKs can't use the notifications APIs to send user notifications at any point in time.

Lifecycle

App SDKs currently follow the lifecycle of their host app, meaning when the app enters or leaves the foreground, shuts down, or gets force-stopped by the operating system due to memory pressure, the app's SDKs do so as well. Our proposal to separate an app's SDKs into a different process implies the following lifecycle changes:

  • The app can be terminated by the user or the operating system. The SDK Runtime would automatically terminate immediately after.
  • The SDK Runtime can be terminated by the operating system due to memory pressure, or an unhandled exception in an SDK for example.

    For Android 13, when an app is in the foreground, the SDK Runtime runs in a high priority and is unlikely to get terminated. When the app goes to the background, the priority of the SDK Runtime process lowers and it becomes eligible for termination. The priority of the SDK Runtime process remains low even if the app comes back to the foreground. Consequently, it is very likely that it would be terminated under memory pressure compared to the app.

    For Android 14 and later, the process priorities of the app and the SDK Runtime are aligned. Process priorities for ActivityManager.RunningAppProcessInfo.importance for the app and the SDK Runtime should be roughly the same.

    In the case that the SDK Runtime terminates while the app is alive—for example, if there's an unhandled exception in the SDK—the SDK Runtime state, including all previously loaded SDKs and remote views, is lost. The app developer can deal with SDK Runtime termination using any of the following methods:

    • The proposal offers related lifecycle callback methods to app developers to detect when termination of the SDK Runtime has occurred.
    • If the SDK Runtime terminates while ads are being displayed, ads might not work as expected. For example, views might be frozen on screen and be no longer interactive. The app can remove the ad view if it does not affect user experience.
    • The app can make another attempt to load SDKs and request ads.
    • For Android 14, if the SDK Runtime terminates while it has SDKs loaded, and if the app developer has not registered the aforementioned lifecycle callback methods, the app terminates by default. Only the app processes that have loaded SDKs terminate and exit normally.
    • Binder objects returned by the SDK to communicate with it (such as SandboxedSdk) throw a DeadObjectException if used by the app.

    This lifecycle model is subject to change in future updates.

    In the case of persistent failures, the app developer should plan for graceful degradation without the SDK or notify the user if the SDK is crucial to the app's core functionality. For further detail on this app-to-SDK interaction, see the communications section of this document.

Non-RE SDKs can continue to use standard OS primitives available to their embedded app—including services, activities, and broadcasts—whereas RE SDKs cannot.

Special cases

The following cases are unsupported, and might yield unexpected behavior:

  • If multiple apps share the same UID, the SDK Runtime might not function properly. Support for shared UIDs might be added in the future.
  • For apps with multiple processes, loading the SDK should be done in the main process.

Media rendering

There are SDKs that render content such as text, images, and video in an app-specified view. To accomplish this we propose a remote-rendering approach where the SDK will render the media from within the SDK Runtime, but use the SurfaceControlViewHost API to allow for the media to render in an app-specified view. This offers the SDK the capability to render this media in a manner that is private for the user, while helping prevent and detect invalid or fraudulent user interactions with the rendered media.

Native ads, those that are not rendered by the SDK but instead by the app, would be supported by SDKs in the SDK Runtime. The signal gathering and creative fetching process would happen consistently with non-native ads. This is an active area of investigation.

In-stream video ads are those that run instream with a video, shown in a player within an app. Given that the video plays within a player in the app, rather than a player or view in the SDK, the rendering model differs from other ad formats. We are actively exploring mechanisms to support both server-side ad insertion and SDK-based ad insertion.

System health

We seek to minimize the system health impact the SDK Runtime has on end-user devices, and are designing ways to do so. Most likely however, some entry-level Android 13 devices with very limited system resources, such as Android (Go edition), will not support the SDK Runtime due to the system health impact. We will soon share the minimum requirements necessary to successfully use the SDK Runtime.

Communications

Since apps and SDKs currently run in the same process, communication between them is uninhibited and unmediated. In addition, Android allows for inter-app communication even if the communication starts and ends with SDKs. This free-flowing communication model enables various use cases while at the same time introducing the possibility for undisclosed data sharing between apps and between SDKs within and between apps. We are proposing the following updates to this communication model seeking to strike a balance between the value of such communication and the realization of our stated goals.

App-to-SDK

The interface between the app and the SDK is the most common communication path to an SDK, and an SDK's API is where much of the user-facing differentiation and innovation reside. We seek to preserve SDKs' ability to innovate and differentiate here. Consequently, our proposal empowers SDKs to expose APIs to apps, and ensure that apps can benefit from all of that innovation.

Given the process boundary structure of the SDK Runtime, we are proposing to build a marshaling layer, accessible within the app, to carry the API calls and responses or callbacks across this boundary between the app and the SDK. We are proposing that the interface to this marshaling layer would be defined by SDK developers, and generated by official open-source build tools that we would develop.

With this proposal we seek to remove the boilerplate marshaling work from app and SDK developers, while providing flexibility for SDK developers and ensuring that SDK code runs in the SDK Runtime to realize our privacy goals. Should we take this path, the API definition language and tooling would need to be designed with your input.

The general interaction model would be as follows:

  • App calls the SDK through the interface, passing in callbacks.
  • SDK asynchronously satisfies the requests and responds using the callbacks.
  • This can be generalized to any publisher-subscriber model, meaning an app can subscribe to events in the SDK with callbacks, and when these events happen, the callbacks would be triggered.

A consequence of the new cross-process structure of this proposal is that there are two process lifecycles that would need to be managed: one for the app itself and the other for the SDK Runtime. Our proposal seeks to automate as much of this as possible, minimizing impact to app and SDK developers. Figure 3 shows an approach we're considering:

Diagram
Figure 3. Sequence diagram that shows the app-to-SDK interactions during app and SDK startup.

The platform would expose new APIs for apps to dynamically load SDKs into the SDK Runtime process, get notified about changes to the state of the process, and interact with SDKs loaded into the SDK Runtime.

The graph in figure 3 demonstrates app-to-SDK communication at a lower level, without the marshaling layer.

The app communicates with SDK running in the SDK Runtime process through the following steps:

  1. Before an app could interact with an SDK, the app would request that the platform load the SDK. To ensure the integrity of the system, apps would specify the SDKs they intend to load in their manifest file, and these SDKs would be the only ones allowed to be loaded.

    The following code snippet provides an illustrative API example:

    SdkSandboxManager.loadSdk(String sdkName, Bundle data, Executor executor,
        OutcomeReceiver<SandboxedSdk, LoadSdkException> receiver)
    
  2. The SDK gets notified that it's been loaded and it returns its interface. This interface is meant to be used by the app process. To share the interface outside the process boundary, it has to be returned as an IBinder object.

    The bound services guide provides different ways to provide IBinder. Whichever way you choose, it must be consistent between the SDK and the caller app. The graph in figure 3 uses AIDL as an example.

  3. The SdkSandboxManager receives the IBinder interface and returns it to the app.

  4. The app gets the IBinder and casts it into the SDK interface, calling its functions:

    IBinder binder = sandboxSdk.getInterface();
    ISdkInterface mySdkInterface = ISdkInterface.Stub.asInterface(binder);
    mySdkInterface.something();
    

The app can also render media from the SDK by following these steps:

  1. As explained in the media rendering section of this document, in order for an app to get an SDK to render media in a view, the app could make a call to requestSurfacePackage() and fetch the appropriate SurfaceControlViewHost.SurfacePackage.

    The following code snippet provides an illustrative API example:

    SdkSandboxManager.requestSurfacePackage(String sdkName, Bundle extraParams,
            Executor executor,
            OutcomeReceiver<Bundle, RequestSurfacePackageException> receiver)
    
  2. The app could then embed the returned SurfacePackage into the SurfaceView via the setChildSurfacePackage API in SurfaceView.

    The following code snippet provides an illustrative API example:

    SurfaceView.setChildSurfacePackage(SurfacePackage surfacePackage)
    

Our proposal is that the IBinder and requestSurfacePackage() APIs be generic and not intended to be called by the apps directly. Instead, these API would be called by the generated API reference discussed above, in a "shim" layer, to reduce the burden on app developers.

SDK-to-SDK

Two SDKs in the same app often need to communicate. This can happen when a given SDK is architected to be composed of constituent SDKs, and can happen when two SDKs from different parties need to collaborate to satisfy a request from the calling app.

There are two key cases to consider:

  • When both SDKs are runtime-enabled. In this case, both SDKs are running in the SDK Runtime with all its protections. SDKs are not able to communicate as they do within an app today. Consequently, an API in SdkSandboxController has been added to enable fetching SandboxedSdk objects for all loaded RE-SDKs. This allows a RE-SDK to communicate with other SDKs loaded in the SDK Runtime.
  • When only one SDK is runtime-enabled.
    • If the calling SDK is running in the app, this works no differently from the app itself calling into the second SDK within the SDK Runtime.
    • If the calling SDK is running within the SDK Runtime, this proposal recommends exposing a method using the IBinder described in the app-to-SDK section that code in the app listens for, processes, and responds with the provided callbacks.
    • Ad SDKs that are not runtime-enabled may not be able to register themselves, we propose the creation of a mediator SDK which includes any partner or app SDKs as direct dependencies of the app and handles registration. This mediator SDK establishes communication between non runtime-enabled SDKs or other app dependencies and the runtime enabled mediator acting as an adapter.

The feature set for SDK-SDK communication has been split into the following categories:

  • SDK-SDK communication within the SDK Runtime (available in the latest Developer Preview)
  • SDK-SDK communication between and app and the SDK Runtime (available in the latest Developer Preview)
  • How views and remote rendering should work for mediation (proposal in development)

The following use cases are under consideration as the primitives are being designed:

  1. Mediation and Bidding. Many advertising SDKs offer a mediation or bidding capability whereby the SDK calls various other SDKs for an ad impression (mediation), or for signal gathering to run an auction (bidding). Typically the coordinating SDK calls other SDKs through an adapter furnished by the coordinating SDK. Given the primitives above, the coordinating SDK, RE or not, should be able to access all RE and non-RE SDKs for normal operation. Rendering in this context is an active area of investigation.
  2. Feature discovery. Some SDK products consist of smaller SDKs which, through a process of inter-SDK discovery, determine the ultimate feature set that is exposed to the app developer. Registration and discovery primitives are expected to enable this use case.
  3. Publisher-subscription models. Some SDKs are designed to have a central publisher of events that other SDKs or apps can subscribe to for notifications through callbacks. The primitives above should support this use case.

App-to-app

App-to-app communication is where at least one of the two processes communicating is a runtime-enabled SDK, and is a potential vector for undisclosed data sharing. Consequently, the SDK Runtime is unable to establish a direct communication channel with any app other than the client application, or with SDKs in another SDK runtime that is created for another app. This is achieved in the following ways:

  • The SDK can't define components like <service>, <contentprovider>, or <activity> in its manifest.
  • The SDK can't publish a ContentProvider or send a broadcast.
  • The SDK can launch an activity belonging to another app, but with limits on what can be sent in the Intent. For instance, no extras or custom actions can be added to this Intent.
  • The SDK can only start or bind to an allowlist of services.
  • The SDK is only able to access a subset of the system ContentProvider (such as com.android.providers.settings.SettingsProvider), where obtained data lacks identifiers and can't be used to build a fingerprint of the user. These checks also apply to accessing ContentProvider using ContentResolver.
  • The SDK is only able to access a subset of protected broadcast receivers (such as android.intent.action.AIRPLANE_MODE).

Manifest tags

When the SDK is installed, PackageManager parses the SDK's manifest and fails to install the SDK if banned manifest tags are present. For example, the SDK may not define components like <service>, <activity>, <provider>, or <receiver> and may not declare a <permission> in the manifest. Tags that fail installation are not supported in the SDK Runtime. Tags that don't fail installation but are silently ignored may be supported in future Android versions.

These checks might also be applied by any build time tools the SDK uses to create the SDK bundle, and at the time of uploading to the application store.

Activity support

SDKs in the SDK Runtime environment can't add an activity tag to their manifest file and can't start their own activities using Context.startActivity. Instead, the platform creates the activities for the SDKs when requested and shares them with SDKs.

The platform activity is of type android.app.Activity. The platform activity starts from one of the app's activities and is part of the app task. FLAG_ACTIVITY_NEW_TASK is not supported.

For an SDK to start activity, it should register an instance of type SdkSandboxActivityHandler which is used to notify about activity creation when the app calls SdkSandboxManager::startSdkSandboxActivity(Activity, IBinder) to start the activity.

The flow of requesting an activity is shown in the following graph.

Diagram
Figure 4. Sequence diagram that shows the flow of starting an activity.

Development

A key principle in this proposal is minimizing the impact to the developer ecosystem to the extent possible. This proposal offers developers a comprehensive set of development tools to write, build, debug RE apps and SDKs. To ensure the integrity of this proposal, there are some changes to how RE apps and SDKs are configured, authored, and built.

Authoring

Android Studio and related tooling will be updated to be SDK Runtime-aware, helping ensure that developers have correctly configured their RE apps and SDKs, and ensuring that legacy or unsupported calls are updated to their newer alternatives where relevant. During the authoring phase, there are some steps our proposal would require developers to take.

App developers

Apps would need to specify their RE SDK and SDK certificate dependencies in their app manifest. In our proposal we treat this as the source of truth from the application developer throughout this proposal. For example:

  • Name: Package name of the SDK or library.
  • Major version: Major version code of the SDK.
  • Certificate digest: The certificate digest of the SDK build. For a given build, we propose the SDK developer obtain and register this value through the relevant app store.

This applies to app store-distributed SDKs only, whether RE or not. Apps statically linking SDKs would use current dependency mechanisms.

Given our goal of minimal impact to developers, it is important that once a target API level supporting the SDK Runtime is specified, app developers only ever need to have a single build whether that build runs on devices that do or do not support the SDK Runtime.

SDK developers

In our proposed design, RE SDK developers need to explicitly declare a new element representing the SDK or library entity in the manifest. Additionally, a similar set of values as the dependency would need to be provided plus a minor version:

  • Name: Package name of the SDK or library.
  • Major version: Major version code of the SDK.
  • Minor version: Minor version code of the SDK.

Should RE SDK developers have other RE SDKs as build-time dependencies, they will likely need to declare them in a manner identical to how an app developer would declare the same dependency. RE SDKs depending on non-RE SDKs would statically link them. This may introduce issues that would be detected at build time or during test passes if the non-RE SDKs require functionality the SDK Runtime does not support, or if it must run in the app's process.

RE SDK developers will likely want to continue support for non-RE-enabled devices, such as Android 12 or lower and as mentioned in the System Health section of the document, entry-level Android 13 devices with very limited system resources. We are working through approaches to ensure SDK developers can retain a single code-base to support RE and non-RE environments.

Builds

App developers

We expect app developers would experience little change in the build step. SDK dependencies, whether locally distributed or app store-distributed (RE or not), would need to exist on the machine for linting, compilation, and builds. We are proposing that Android Studio abstract these details from the app developer with normal usage and make this as transparent as possible.

Although we expect a DEBUG build would need to include all the code and symbols to be present in the DEBUG build for debuggability, RELEASE builds would optionally have all the app store-distributed SDKs (RE or not) removed from the final artifact.

We are earlier in our design phase here and will share more as it materializes.

SDK developers

We are working on a path to ensure that non-RE and RE versions of an SDK can be built into a single artifact for distribution. This would prevent app developers from needing to support separate builds for RE and non-RE versions of an SDK.

Much like for apps, any app store-distributed dependency SDKs would need to exist on the machine for linting, compilation, and builds, and we expect Android Studio should facilitate this seamlessly.

Testing

App developers

As described in our proposal, app developers would be able to test their apps on devices running Android 13 how they normally would. After they've built their app, the app would be able to be installed on an RE device or emulator. This installation process would ensure the correct SDKs get installed into the SDK Runtime for the device or emulator, whether the SDKs were pulled from a remote SDK repository or cache from the build system.

SDK developers

SDK developers generally use in-house test apps on devices and emulators to test their development. Our proposal doesn't change this, and in-app validation would follow the same steps as outlined for app developers above, with a single build artifact for both RE and non-RE apps. SDK developers will be able to step through their code whether it's in the SDK Runtime or not, though there may be some limitations on advanced debugging and profiling tools. This is an active area of investigation.

Distribution

Our design proposal for the separation of an app from its SDKs has created the possibility for app store distribution of SDKs. This is a general possibility, not unique to any particular app store. The benefits are clear:

  • Ensure the quality and consistency of SDKs.
  • Streamline publication for SDK developers.
  • Expedite rollout of SDK minor version updates to installed apps.

In order to support SDK distribution, an app store would likely need to provide most of the following capabilities:

  • A mechanism for SDK developers to upload their app store-distributable SDKs to the store, update them, roll them back and possibly remove them.
  • A mechanism to ensure the integrity of an SDK and its provenance, and an app and its provenance, and resolve their dependencies.
  • A mechanism to deploy them onto devices in a consistently reliable and performant manner.

Evolving restrictions over time

We expect the restrictions faced by code in the SDK runtime to evolve with later versions of Android. To ensure application compatibility, we won't change these restrictions with mainline module updates for a given SDK level. Behavior associated with a given targetSdkVersion is preserved until support for that targetSdkVersion is deprecated through app store policy, and targetSdkVersion deprecation might happen at a faster cadence than for apps. Expect restrictions to change frequently across Android SDK versions, especially in the first few releases.

Additionally, we're building a canary mechanism to allow external and internal testers to join a group that gets the proposed set of restrictions for the next version of Android. This will help us get feedback and confidence on the proposed changes to the set of restrictions.

FAQ

  1. What is an advertising-related SDK?

    An ad-related SDK is one that facilitates any part of the targeting of users with messages for commercial ends, on apps that are not owned by the advertiser. This includes, but is not limited to, analytics SDKs where user groups can be created for subsequent targeting, ad serving SDKs, anti-abuse and anti-fraud SDKs for ads, engagement SDKs, and attribution SDKs.

  2. Can any SDK run in the SDK Runtime?

    Although the initial focus is for ad-related SDKs, developers of non-ad-related SDKs that seek a pro-privacy posture and believe they can operate under the conditions outlined above can share feedback about their SDKs running in the SDK Runtime. The SDK Runtime isn't designed to be compatible with all SDK designs, however. Beyond the documented limitations, the SDK Runtime is likely unsuitable for SDKs that need real-time or high throughput communications with the hosting app.

  3. Why choose process isolation instead of isolation within a process's Java-based runtime?

    Currently, the Java-based runtime doesn't readily facilitate the security boundaries necessary for the privacy guarantees that are desired for Android users. Attempting to implement something like this would likely require a multi-year effort, without a guarantee of success. Therefore, the Privacy Sandbox uses use process boundaries, a time-tested and well-understood technology.

  4. Would moving SDKs into the SDK Runtime process provide download size or space savings?

    If multiple apps are integrated with runtime-enabled SDKs of the same version, then this can reduce download size and disk space.

  5. What kind of app lifecycle events such as when the app goes to the background, will SDKs have access to in the SDK Runtime?

    We are actively working on design support for notifying SDK runtime on app-level lifecycle events of its client application (e.g. app going into background, app going into foreground). Design and sample code will be shared in an upcoming developer preview.