Telemetry

For clients that have “send anonymous usage data” enabled Focus sends a “core” ping and an “event” ping to Mozilla’s telemetry service. Sending telemetry can be disabled in the app’s settings. Builds of “Focus for Android” have telemetry enabled by default (“opt-out”) while builds of “Klar for Android” have telemetry disabled by default.

Core ping

Focus for Android creates and tries to send a “core” ping whenever the app goes to the background. This core ping uses the same format as Firefox for Android and is documented on firefox-source-docs.mozilla.org.

Event ping

In addition to the core ping an event ping for UI telemetry is generated and sent as soon as the app is sent to the background.

Settings

As part of the event ping the most recent state of the user’s setting is sent (default values in bold):

Setting Key Value(*)
Default search engine pref_search_engine bundled engine name/custom(**)
Block ad trackers pref_privacy_block_ads true/false
Block analytics trackers pref_privacy_block_analytics true/false
Block social trackers pref_privacy_block_social true/false
Block content trackers pref_privacy_block_other true/false
Block web fonts pref_performance_block_webfonts true/false
Block images pref_performance_block_images true/false
Locale override pref_locale empty string/locale-code(***)
Default browser pref_default_browser true/false
Stealth mode pref_secure true/false
Autocomplete (Default) pref_autocomplete_preinstalled true/false
Autocomplete (Custom) pref_autocomplete_custom true/false
Show tips on Firefox Focus home screen pref_key_tips true/false

(*) All values are sent as a String.

(**) If the default is one of the bundled engines, the name of the engine. Otherwise, just custom.

(***) An empty string value indicates “System Default” locale is selected.

Events

The event ping contains a list of events (see event format on readthedocs.io) for the following actions:

Sessions

Event category method object value
Start session (App is in the foreground) action foreground app
Stop session (App is in the background) action background app

Browsing

Event category method object value extras.
URL entered action type_url search_bar
Search entered action type_query search_bar
Search hint clicked ("Search for ..") action select_query search_bar
Link from third-party app action intent_url app
Text selection action from app action text_selection_intent app
Long press on image / link action long_press browser
"Pull to refresh" action swipe browser reload
Autofill popup is shown action show autofill
Autofill performed action click autofill
Enable Search Suggestion from prompt action click search_suggestion_prompt true/false

Custom Tabs

Event category method object value extra
Custom tab opened action intent_custom_tab app options*
"Close" button clicked action click custom_tab_close_bu tabs*
"Action" button clicked action click custom_tab_action_bu
Custom menu item selected action open menu custom_tab

(*) options is a JSON map of enabled custom tab options as requested by the third-party app, e.g. [hasToolbarColor, hasCloseButton]

(*) tabs is a JSON map containing the position of the currently selected tab and the total number of open tabs:

{
  "selected": "2"  // Currently selected tab (Zero-based numbering; -1 if no tab is selected)
  "total": "5"     // Total number of open tabs
}

Context Menu

Event category method object value
Link context menu dismissed action cancel browser_contextmenu link
Share Link menu item selected action share browser_contextmenu link
Copy link menu item selected action copy browser_contextmenu link
Image context menu dismissed action cancel browser_contextmenu image
Share Image menu item selected action share browser_contextmenu image
Copy Image menu item selected action copy browser_contextmenu image
Save Image menu item selected action save browser_contextmenu image
Image with Link context menu dismissed action cancel browser_contextmenu image+link
Open link in new tab action open browser_contextmenu tab
Open new tab in Focus from customtab context menu action open browser_contextmenu full_browser

Erasing session

Event category method object value extras
Floating action button clicked action click erase_button tabs*
Back button clicked: Home screen action click back_button erase_home tabs*
Back button clicked: Previous app action click back_button erase_app tabs*
Notification clicked action click notification erase tabs*
Notification "Erase and Open" click action click notification_action erase_open tabs*
Home screen shortcut clicked action click shortcut erase tabs*
Erase history in tabs tray action click tabs_tray erase tabs*
App removed by user from "recent apps" action click recent_apps erase tabs*

(*) tabs is a JSON map containing the position of the currently selected tab and the total number of open tabs:

{
  "selected": "2"  // Currently selected tab (Zero-based numbering; -1 if no tab is selected)
  "total": "5"     // Total number of open tabs
}

Notification

Event category method object value extras
Notification clicked (Erase) action click notification erase
Action "Open" clicked action click notification_action open
Action "Erase and Open" clicked action click notification_action erase_open tabs*

(*) tabs is a JSON map containing the position of the currently selected tab and the total number of open tabs:

{
  "selected": "2"  // Currently selected tab (Zero-based numbering; -1 if no tab is selected)
  "total": "5"     // Total number of open tabs
}

Page Load Time Histogram

Event category method object extras
Histogram for Page Load Times for Foreground Session histogram foreground browser histogram*

(*) There are 200 extras attached to this event, each a bucket of 100 ms each, with the key as the minimum value in the bucket and the value as the corresponding number of events in the bucket. Anything over 20,000 is put in the last bucket. For example:

{”0":"2"}
{“100”:"3"}
...
{"19900", "4"}

URI Count

Event category method object extra
The count of the total non-unique http(s) URIs visited in a subsession, including page reloads, after the session has been restored. This does not include background page requests and URIs from embedded pages or private browsing action open browser {"total_uri_count": num }
The count of the unique domains visited in a subsession, after the session has been restored. Subdomains under eTLD are aggregated after the first level (i.e. test.example.com and other.example.com are only counted once). This does not include background page requests and domains from embedded pages or private browsing. action open browser {"unique_domains_count": num }

Downloads

Event category method object value
Clicked "Download" action click download_dialog download
Clicked "Cancel" action click download_dialog cancel

Open Focus From Icon

Event category method object value
Launched Focus From Icon action click app_icon open
Resume Focus From Icon action click app_icon resume

Add to Home screen

Event category method object value
Clicked "Add to Home screen" in dialog action click add_to_homescreen_dialog add_to_homescreen
Clicked "Cancel" in dialog action click add_to_homescreen_dialog cancel
Open Focus from Home screen shortcut action click homescreen_shortcut open

Share to Focus Event

Event category method object value
Shared URL to Focus action share_intent app url
Shared Search Terms to Focus action share_intent app search

Settings

Event category method object value extras
Setting changed action change setting { "to": <value> }
Autocomplete domain added action save autocomplete_domain { "source": <value> }
Autocomplete domain removed action remove autocomplete_domain { "total": 5 }
Autocomplete domain reordered action reorder autocomplete_domain options*
Open Exceptions Setting action open allowlist
Remove Exceptions Domains action remove allowlist { "total": 5 }
Remove All Exceptions Domains action remove_all allowlist
Default search engine clicked action open search_engine_setting
Change default search engine action save search_engine_setting {"source": src* }
Select "Remove" engines screen action remove search_engine_setting
Delete search engines remove remove remove_search_engines {"selected": num* }
Restore bundled engines action restore search_engine_setting
Select "Add another engine" action show custom_search_engine
Save custom search engine action save custom_search_engine {"success": bool* }
Click "Add search engine" ℹ️ action click search_engine_learn_more
Open with default browser prompt action show make_default_browser_open_with
Settings default browser prompt action show make_default_browser_settings

(*) options is a JSON map containing:

{
  "from": 5
  "to":   2
}

(*) src can be either bundled or custom

(*) num number of engines selected for deletion

(*) bool true if successfully saved, false if validation error

Firstrun

Event category method object value
Showing a first run page action show firstrun page*
Skip button pressed action click firstrun skip
Finish button pressed action click firstrun finish

(*) Page numbers start at 0. Initially when the firstrun tour is shown an event for the first page (0) is fired.

Multitasking / Tabs

Event category method object value extras
Context menu: Open link in new tab action open browser_contextmenu tab tabs*
Open the tabs tray action show tabs_tray
Close the tabs tray (back / click outside) action hide tabs_tray
Switch to tab in tabs tray action click tabs_tray tab tabs*
Erase history in tabs tray action click tabs_tray erase tabs*

(*) tabs is a JSON map containing the position of the currently selected tab and the total number of open tabs:

{
  "selected": "2"  // Currently selected tab (Zero-based numbering; -1 if no tab is selected)
  "total": "5"     // Total number of open tabs
}

Homescreen Tips

Event category method object value
Open in new tab tip displayed action show tip open_in_new_tab_tip
Add to homescreen tip displayed action show tip add_to_homescreen_tip
Disable tracking protection tip displayed action show tip disable_tracking_protection_tip
Disable tips on home screen tip displayed action show tip disable_tips_tip
Set default browser tip displayed action show tip default_browser_tip
Autocomplete URL tip displayed action show tip add_autocomplete_url_tip
Open in new tab tip tapped action click tip open_in_new_tab_tip
Add to homescreen tip tapped action click tip add_to_homescreen_tip
Disable tips tip tapped action click tip disable_tips_tip
Set default browser tip tapped action click tip default_browser_tip
Autocomplete URL tip tapped action click tip add_autocomplete_url_tip
Homescreen tips enabled/disabled action click tip add_to_homescreen_tip
Survey tip displayed action show tip survey_tip
Survey tip tapped action click tip survey_tip
Survey (es) tip displayed action show tip survey_tip_es
Survey (es) tip tapped action click tip survey_tip_es
Survey (fr) tip displayed action show tip survey_tip_fr
Survey (fr) tip tapped action click tip survey_tip_fr

SSL Errors

Event category method object extras
SSL Error From Page error page browser error*
SSL Error From Resource error resource browser error*

(*)error is a JSON map containing the primary SSL Error

{
  "error_code": "SSL_DATE_INVALID"  // Primary SSL Error
}
Possible Error Codes
SSL_DATE_INVALID
SSL_EXPIRED
SSL_IDMISMATCH
SSL_NOTYETVALID
SSL_UNTRUSTED
SSL_INVALID
Undefined SSL Error

Limits

  • An event ping will contain up to but no more than 500 events

  • No more than 40 pings per type (core/event) are stored on disk for upload at a later time

  • No more than 100 pings are sent per day

Implementation notes

  • Event pings are generated (and stored on disk) whenever the onStop() callback of the main activity is triggered. This happens whenever the main screen of the app is no longer visible (The app is in the background or another screen is displayed on top of the app).

  • Whenever we are storing pings we are also scheduling an upload. We are using Android’s JobScheduler API for that. This allows the system to run the background task whenever it is convenient and certain criterias are met. The only criteria we are specifying is that we require an active network connection. In most cases this job is executed immediately after the app is in the background.

  • Whenever an upload fails we are scheduling a retry. The first retry will happen after 30 seconds (or later if there’s no active network connection at this time). For further retries a exponential backoff policy is used: [30 seconds] * 2 ^ (num_failures - 1)

  • An earlier retry of the upload can happen whenever the app is coming to the foreground and sent to the background again (the previous scheduled job is reset and we are starting all over again).