Get Installed Related Apps API

Draft Community Group Report,

This version:
https://wicg.github.io/get-installed-related-apps/spec/
Issue Tracking:
GitHub
Inline In Spec
Editor:
(Google)

Abstract

The Get Installed Related Apps API allows web apps to detect if related apps are installed on the current device.

Status of this document

This specification was published by the Web Platform Incubator Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups.

1. Introduction

As the capabilities of the web grow, the functionality of web apps begins to match that of corresponding native apps. The situation of users having a web app and the corresponding native app both installed on the same device will become more common, and the feature sets of these apps will converge.

It is important to allow websites to detect if an app is installed, whether a native app or a web app, to allow them to disable functionality that should be provided by the other app.

1.1. Example

const installedApps = await navigator.getInstalledRelatedApps();
const nativeApp = installedApps.find(app => app.id === 'com.example.myapp');

if (nativeApp && doesVersionSendPushMessages(nativeApp.version)) {
  // There’s an installed native app that handles sending push messages.
  // No need to do anything.
  return;
}

// Create a push subscription.

In the above example, doesVersionSendPushMessages is a developer-defined function.

2. Privacy Considerations

This API is only enabled in secure top-level contexts. This ensures that the website cannot be spoofed, and that the association between the site and application is valid.

The association between the web app and its counterpart is bidirectional, meaning that the web app has to declare its association with the related app, and the related app has to declare its association with the web app. This prevents malicious websites from fingerprinting users and getting a list of their installed applications.

The user agent MAY limit the number of related applications to be matched, to limit fingerprinting.

The user agent MUST NOT return installed applications when running in a privacy preserving mode, for example Incognito in Chrome or Private Browsing in Firefox.

3. Infrastructure

3.1. Platform

A platform is an OS-specific concept, which groups applications of the same class together. It is represented by a USVString.

An OS has installed apps, a map where the keys are platforms, and the values are lists of installed apps.

3.2. Installed App

An installed app represents an application that is installed on the user’s device.

An installed app consists of:

An installed app also has an associated platform.

4. Algorithms

4.1. Match an installed app

To match an installed app for relatedApp (an ExternalApplicationResource) and manifestURL (a URL), run these steps:
  1. Let platform be relatedApp’s platform.

  2. If installed apps[platform] does not exist, return null.

  3. Let installedApps be installed apps[platform].

  4. For each installedApp in installedApps:

    1. If relatedApp’s id is not equal to installedApp’s id, and relatedApp’s url is not equal to installedApp’s id, continue.

    2. Let minVersion be relatedApp’s min_version if present, otherwise the empty string.

    3. If minVersion is not the empty string and minVersion is greater than installedApp’s version, return null.

      Note: `greater` is a platform-specific concept for ordering application versions. It does not have to be lexicographic order.

    4. Let fingerprints be relatedApp’s fingerprints if present, otherwise an empty list.

    5. For each fingerprint of fingerprints:

      1. If installedApp’s fingerprints does not contain fingerprint, return null.

    6. If installedApp’s relatedURLs does not contain manifestURL, return null.

    7. Return installedApp.

  5. Return null.

5. API

dictionary RelatedApplication {
    required USVString platform;
    USVString url;
    DOMString id;
    USVString version;
};

Each RelatedApplication represents an installed app that was matched with the provided ExternalApplicationResources from the WebAppManifest.

5.2. Extensions to Navigator

[Exposed=Window]
partial interface Navigator {
  [SecureContext] Promise<sequence<RelatedApplication>> getInstalledRelatedApps();
};
The getInstalledRelatedApps() method, when invoked, runs these steps:
  1. Let relevantBrowsingContext be the context object's relevant settings object's responsible browsing context.

  2. If relevantBrowsingContext is not a top-level browsing context, then return a promise rejected with an InvalidStateError DOMException.

    Should this restriction be removed? (#11)

  3. Let promise be a new promise.

  4. Run the following steps in parallel:

    1. Let manifest and manifestURL be the results of obtaining the manifest. If this fails, resolve promise with an empty list and abort these steps.

    2. Let relatedApplications be manifest’s related_applications.

    3. Optionally:

      1. Let maxRelatedApps be a user agent determined number.

      2. If relatedApplicationssize is greater than maxRelatedApps, truncate relatedApplications to a size of maxRelatedApps.

      Note: This limits how many native applications a website can know are installed. The extra items need to be truncated so the same ExternalApplicationResources are returned every time.

    4. Let installedApps be an empty list.

    5. For each relatedApplication in relatedApplications:

      1. Let matchedApp be the result of running match an installed app with relatedApplication and manifestURL.

      2. If matchedApp is null, continue.

      3. Let installedApp be a new RelatedApplication with:

        platform

        relatedApplication’s platform

        url

        relatedApplication’s url

        id

        relatedApplication’s id

        version

        matchedApp’s version

      4. Append installedApp to installedApps.

    6. Resolve promise with installedApps.

  5. Return promise.

Conformance

Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Conformant Algorithms

Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.

Conformance requirements phrased as algorithms or specific steps can be implemented in any manner, so long as the end result is equivalent. In particular, the algorithms defined in this specification are intended to be easy to understand and are not intended to be performant. Implementers are encouraged to optimize.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[APPMANIFEST]
Marcos Caceres; et al. Web Application Manifest. 5 March 2021. WD. URL: https://www.w3.org/TR/appmanifest/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/
[WebIDL]
Boris Zbarsky. Web IDL. 15 December 2016. ED. URL: https://heycam.github.io/webidl/

IDL Index

dictionary RelatedApplication {
    required USVString platform;
    USVString url;
    DOMString id;
    USVString version;
};

[Exposed=Window]
partial interface Navigator {
  [SecureContext] Promise<sequence<RelatedApplication>> getInstalledRelatedApps();
};

Issues Index

Should this restriction be removed? (#11)