[fenix] Bug 1812087 - Migrate Fenix wiki pages into the docs folder

pull/600/head
Gabriel Luong 1 year ago committed by mergify[bot]
parent e2b346c69f
commit 4fa35e3d37

@ -0,0 +1,7 @@
Instructions to enable the "secret settings" in the Settings menu for Firefox Nightly. This lets you access "Secret Settings" and "Secret Debug Info" in the Settings menu.
1. Tap on three-dot menu in the toolbar
2. Tap on Settings
3. Scroll down and select "About Firefox Nightly"
4. Tap the Firefox logo until you see the "Debug menu: (#) click(s) left to enable" helper message
5. Once the Debug menu has been enabled, go back to Settings and you will see "Secret Settings" and "Secret Debug Info" menu items

@ -0,0 +1,14 @@
Explanations of common acronyms that are seen in the Fenix project boards and issues.
**AC**: "[Android Components](https://github.com/mozilla-mobile/android-components)", the Mozilla team responsible for componentization.
**AS**: "[Application Services](https://github.com/mozilla/application-services)", the Mozilla team responsible for sync and storage (logins, bookmarks, etc).
**CFR**: "Contextual feature recommendation", i.e. popup windows.
**CTA**: "Call to action", a marketing/product term for things that pop up and ask for user interaction.
**ETP**: "Enhanced tracking protection". The shield icon.
**PWA**: "[Progressive web application](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps)", Fenix can act as a host for these applications.

@ -0,0 +1,104 @@
To keep Fenix in a good shape, the performance team weekly runs multiple performance tests to identify regressions. The results are kept and maintained [here](https://earthangel-b40313e5.influxcloud.net/d/s3AT6t7nk/fenix-startup-nightly-via-backfill-py?orgId=1).
The main tests are:
* MAIN first frame:
Simulates a COLD MAIN (app icon launch) launch to report FullyDrawn, e.g when the user sees the app fully drawn after launching it.
* COLD VIEW Nav start:
An app link launch to load a page. It measures until "navigation starts" which is an internal Gecko event that indicates we're starting to load a page.
### What to do after a performance regression is reported.
Weekly after, the performance team runs the tests, if there is any regression, they will open a ticket, providing the dates between when was the last non-regressing and regressing version (an [example](https://github.com/mozilla-mobile/fenix/issues/25253) ticket). **These dates are important** for us to discover which commit introduced the regression. As we would like to identify which commit is the offending one, we need to bitset the commit range from non-regressing to regressing version. Fortunately for us, the performance team has a tool that can help us with that its called [backfil](https://github.com/mozilla-mobile/perf-tools/blob/main/backfill.py).
The tool can take a commit range start/end, build all the APKs, run the performance tests and provide the same data that its plotted [here](https://earthangel-b40313e5.influxcloud.net/d/s3AT6t7nk/fenix-startup-nightly-via-backfill-py?orgId=1). With it we can identify the offending commit.
### Install the required dependencies.
* Pull the [perf-tools](https://github.com/mozilla-mobile/perf-tools) repository, and on it follow the [configuration instructions](https://github.com/mozilla-mobile/perf-tools#configuration).
* Make you can run `adb` on the terminal, as the performance tools we use it through the scripts.
### Finding the regressing commit.
Now that you have all the dependencies installed, we will need to find the commit hash, where there the regression was reported and when the regression was not present, as [backfill](https://github.com/mozilla-mobile/perf-tools/blob/main/backfill.py), need them as parameters.
On the reported [ticket](https://github.com/mozilla-mobile/fenix/issues/25253), the performance team gave us the date when the regression was introduced (5/10), and when it wasn't present (5/9).
![image](https://user-images.githubusercontent.com/773158/174879320-ace21f51-2892-4b1c-8c25-a10ee8d0174e.png)
We can find each commit hash date by downloading the APKs, from Task Cluster and going to the about page.
For example:
**For 05/10**.
[https://firefox-ci-tc.services.mozilla.com/tasks/index/mobile.v2.fenix.nightly.2022.05.10.latest/armeabi-v7a](https://firefox-ci-tc.services.mozilla.com/tasks/index/mobile.v2.fenix.nightly.2022.06.06.latest/armeabi-v7a)
<img width="503" alt="image" src="https://user-images.githubusercontent.com/773158/174894842-3341aff6-185f-4402-9c30-3cd5c56dcd3d.png">
From it, we can find [2f7f5988f](https://github.com/mozilla-mobile/fenix/commit/2f7f5988fccad2cf2043eed4b6849b32a4c76048) when the regression was spotted.
**For 05/09**.
[https://firefox-ci-tc.services.mozilla.com/tasks/index/mobile.v2.fenix.nightly.2022.05.10.latest/armeabi-v7a](https://firefox-ci-tc.services.mozilla.com/tasks/index/mobile.v2.fenix.nightly.2022.06.06.latest/armeabi-v7a)
<img width="499" alt="image" src="https://user-images.githubusercontent.com/773158/174894896-a3a66219-ba0e-4174-b4fa-842e049e8d6d.png">
When the regression was not present [98455c01e](https://github.com/mozilla-mobile/fenix/commit/98455c01eeba7c63775f18817cd079f5d08b4513)
Using the commits we can construct this range:
https://github.com/mozilla-mobile/fenix/compare/98455c01eeba7c63775f18817cd079f5d08b4513...2f7f5988fccad2cf2043eed4b6849b32a4c76048
<img width="856" alt="commit range" src="https://user-images.githubusercontent.com/773158/175076734-9c585df2-7c5d-4b17-9135-9447643fb5d0.png">
With it we can see each commit that could introduced the regression.
### Using backfill.py
With the info that we found above, execute `backfill.py`
```
perf-tools-main % python3 backfill.py --tests cold_main_first_frame --startcommit 98455c01eeba7c63775f18817cd079f5d08b4513 --endcommit 2f7f5988fccad2cf2043eed4b6849b32a4c76048 --git_remote_name https://github.com/mozilla-mobile/fenix.git --repository_to_test_path ../fenix fenix nightly armeabi-v7a commitsRange
```
Where:
* **cold_main_first_frame**: it's the test we would like to run, we could also pass `cold_view_nav_start` depending on the regression type.
* **--startcommit**: it's the commit before the regression.
* **--endcommit** it's the commit where the regression appears.
* **--repository_to_test_path** is the path where your local Fenix repository is.
**Note**: Make sure your repository includes all the tokens (Sentry, Nimbus, … etc) that we include in our release builds, as not adding them could affect the test results, as we want the APKs to be the same [experience as normal users will have](https://wiki.mozilla.org/Performance/Fenix#How_to_measure_what_users_experience). Part of this is making sure you have [autosignReleaseWithDebugKey in your local.properties](https://github.com/mozilla-mobile/fenix#automatically-sign-release-builds).
🕐 Be patient, as we will have to build an APK for each possible commit in the range and for this range there [are 19 commits](https://github.com/mozilla-mobile/fenix/compare/98455c01eeba7c63775f18817cd079f5d08b4513...2f7f5988fccad2cf2043eed4b6849b32a4c76048) then we will build 19 APKs, and run the performance test for each one.
As the script progress, we will start to see some activity on the `perf-tools` **directory**, as each APKs will go there with the format `apk_commit_<HASH>.apk`
![image](https://user-images.githubusercontent.com/773158/174896260-7273afae-02de-49bf-be78-da0e08aa05ff.png)
After all the APKs are built, the script will continue with the testing phase, it will run the tests per each commit/APKs, and create a directory named `backfill_output` where it will create two **.txt files per commit** `apk_commit_<HASH>-cold_main_first_frame-analysis.txt` and `apk_commit_<HASH>-cold_main_first_frame-durations.txt`
![image](https://user-images.githubusercontent.com/773158/174896536-6b798764-b81d-4e3a-bab0-1a1a31a57664.png)
These files are the output of the script:
* **Cold_main_first_frame-analysis.txt**: Will contain key information about the test results like max,mean,median, and min.
* **Cold_main_first_frame-durations.txt**: Will contain the raw information of each repetition of the test.
With these files, we can identify which commit, introduced the regression by checking file by file which results are closer to the ones reported one the regression ticket.
After we found the regressing commit, we just have to update the ticket, posting our finding and tagging the person that introduced to research how to optimize the patch. Normally if the regression is significant we will ask to undo the commit until the patch is optimized.
## Extra tips:
* In case you would like to run the same test that are run via `backfil` for an specific APK, you can find more information [here](https://wiki.mozilla.org/Performance/Fenix/Performance_reviews#Measuring_cold_start_up_duration).
* If you would like to graph the results you can use `python3 analyze_durations.py --graph results.txt`.
*Just keep in mind, the results provide from the Performance team are from running the tests on a Moto G 5. Running on a more powerful device could cause the results to diverge.
* In case, you need to start recording a profile in startup https://profiler.firefox.com/docs/#/./guide-startup-shutdown?id=firefox-for-android.
### Identifying the source of the regression.
Our main task, when looking for a performance regression is just to identify the faulty commit, but if we would like to figure out what is the exact cause, we will need to take [profile](https://wiki.mozilla.org/Performance/Fenix/Performance_reviews#Profile) from regressing version, and the version before to try to identify what could be causing the issue, checking the code path of the regressing commit could give us some hints to where to look.

@ -0,0 +1,93 @@
For an overview of our current architecture, please see [this document](https://github.com/mozilla-mobile/fenix/blob/master/docs/architecture-overview.md)
---
These are some of the major architecture decisions we've made so far in Fenix. [Why?](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions)
---
# Overview
Several apps have suffered from insufficient attention to appropriate Android application architecture. This leads to spaghetti code, God objects, and leaky abstractions that make testing and maintaining our apps significantly more costly and challenging.
---
# Goals
Our architecture should:
* Have classes which aim to fulfill a single responsibility, thereby separating concerns.
* Improve the ability of developers to write effective automated unit and UI tests.
* Make the bulk of application code more readable, easing onboarding of contributors.
* Improve the ability to debug application errors with useful stack traces.
* Be amenable to code reuse when desirable.
* Handle A/B experimentation without vast code branches or confusion.
---
# Special Concerns
As a browser, Fenix will need to interface with the Android Components and the GeckoView rendering engine. This means any architecture we choose must not require that all components of the app are implemented similarly. Also, our application state will need to synchronize with the engines state as the two will not always be in perfect sync due to hidden internals.
---
# Component Architecture
## Context
A/B testing of layout and UX is a fundamental necessity of Fenix. We have a lot of hypotheses needing validation and actual usage data about what might make a browser better to acquire and retain more users. A lot of questionable decisions have been made in older mobile browsers that do not seem ideal for mobile devices, but we need data to tell us if our assumptions are correct.
## Decision
We did a review of modern app architectures used by companies throughout the tech industry and came across the Netflix "componentization" architecture. Netflix had a special desire to A/B test a lot of different layouts for their app's user interface and built their architecture for this express purpose.
Netflix's architecture moves all UX-related code away from activities and fragments. Instead, fragments subscribe to components through RxJava and components inflate themselves.
The actual components' inflated views are dropped into ConstraintLayouts and are tied together by applying programmatic ConstraintSets. ConstraintLayouts and ConstraintSets also tie nicely into the new and ultra-powerful MotionLayouts to empower rich animations.
Here are some videos of Juliano Moraes of Netflix describing their architecture:
[DroidCon NYC part 1 video](https://www.youtube.com/watch?v=dS9gho9Rxn4)
[DroidCon SF part 2 video](https://www.youtube.com/watch?v=1cWwfh_5ZQs)
Here's a [sample repository](https://github.com/julianomoraes/componentizationArch) demonstrating in a very simple form how it functions.
The goal of software architecture is to minimize the cost of change. This decision is possibly the biggest factor for reducing the cost of changes to Fenix. It also plays well with the Android Components project, which provides so many of the components that will make up this project.
## Consequences
We will package the UI into components which are reusable and can be remixed for A/B layout tests.
We will keep all UI/UX code out of activities and fragments to obey the [Single Responsibility Principle](https://blog.cleancoder.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html). These classes will exist to handle OS business logic and to bind components.
One downside of this is the extra cost of getting contributors to avoid making UI/UX changes directly from activities and fragments. Another is programmatic layouts don't play well with previewing layouts. We'll all need to learn how to use ConstraintLayouts and ConstraintSets effectively.
---
# Localized, MVI (Model-View-Intent) Unidirectional Architecture
## Context
Race conditions are the bane of Android apps everywhere. They often happen because multiple systems cannot agree about state.
## Decision
The best solution is to have all state changes flow in a functional, reactive manner out from a single source of truth with careful thread locking as required. This solution will be familiar to anyone who has worked with Redux or Flux.
Within each component, we'd like state changes to occur in a cycle. The user interface's contents are rendered by presenting an initial ViewState to the screen. When the user interacts with the app, a Change object is passed to a state reducer. The reducer function copies the current, immutable state with the requested changes and passes it to the Model. The View subscribes to these state changes and updates itself reactively.
In this manner, the UX of the app only flows in a single direction from a source of truth. Because all changes happen in a serialized RxKotlin Observable, they will be applied in the order they happen.
However, unlike some MVI architectures, we will not focus on keeping a global ViewState that encompasses all state. There are times when we want OS calls, NDK calls, and third party component calls to be the source of truth. Rather than trying to make a single ViewState that contains all state, we'll be able to observe a merged observable of all actions and state changes. This will be invaluable for debugging the app.
Here's a [state diagram of the MVI architecture](https://staltz.com/img/mvi-unidir-ui-arch.jpg).
## Consequences
We will experiment with writing new components using MVI unidirectional principles. We will need to take care when passing data between components that we do not override a more authoritative source of truth.
Because all changes can be represented by a single, merged and serialized Observable or Flowable, we should be able to use this for debugging. All ViewStates, Changes, and Actions/Intents will be easily loggable to observe the causes of state issues.
---

@ -0,0 +1,40 @@
## Important
* The main goal here is not to file an issue for every single distinct crash report, but to find regressions of new problems that need to be addressed.
* Once you're familiar with the process this should not take more than 10 mins in the morning.
* Quick links that you should check everyday [Sentry Query](https://sentry.io/organizations/mozilla/issues/?groupStatsPeriod=auto&page=0&project=6295546&query=is%3Aunresolved+level%3Afatal+firstSeen%3A-1w&sort=freq&statsPeriod=14d) and [Socorro Query](https://crash-stats.mozilla.org/topcrashers/?product=Fenix&days=3&_range_type=build&process_type=any)
## Things to note before starting:
* Since we are focused on Java crashes, Sentry currently is the better choice.
* Ignore `level:info` issues (blue labels in Sentry). These issues are informational only.
## What to do when monitoring crashes:
* Look at Sentry Fenix-nightly overview. Go though trending issues. [Sentry Dashboard](https://sentry.io/organizations/mozilla/projects/fenix-nightly/?project=6295546).
* Look at Sentry custom search [Sentry Query](https://sentry.io/organizations/mozilla/issues/?groupStatsPeriod=auto&page=0&project=6295546&query=is%3Aunresolved+level%3Afatal+firstSeen%3A-1w&sort=freq&statsPeriod=14d).
* Sign up for https://groups.google.com/a/mozilla.org/g/stability to get a daily email on the stability of Fenix.
## How to determine a crash requires actions:
* Crashes that have level either Fatal or Error.
* Crashes that are occurring on latest Fenix and A-C versions.
* Crashes that are spiking.
* Crashes that are new.
* Crashes that happen repeatedly and often.
* Crashes that are happening to multiple users.
## When a crash report requires actions:
* Is this a crash due to a recent change? If so, contact the developer.
* The histogram on the right side can help determine this along with checking the Firefox-Beta and Firefox Sentry products.
* Triage the crash to determine if the issue is real and requires a GitHub issue to track it.
* When filing an issue add a link to it as a comment in the Sentry crash for the products (nightly, beta, release) where the crash appears.
* If a GitHub issue is required to track the crash, put the issue in the [Android Team Backlog Staging Board](https://github.com/orgs/mozilla-mobile/projects/70).
* Notify the relevant teams on Slack/Matrix that there's a new crash in Nightly that needs urgent attention, e.g. **#synced-client-integrations** for all things involving application services (A-S), **#nimbus-rust-sdk** for Nimbus, and **[GeckoView on Matrix](https://chat.mozilla.org/#/room/#geckoview:mozilla.org)**.
## What can you do to help when not monitoring crashes
* If you recently landed a new module / change that is significant, contact the crash monitor so they are aware of it.
## Crash monitoring with Socorro
* Look at [Top Crashers for Fenix Nightly](https://crash-stats.mozilla.org/topcrashers/?product=Fenix&days=3&_range_type=build&process_type=any) for reports on Nightly builds.
* This will return zero results if GV build ID is greater than 3 days old. Change to the 7 day view and ask #releaseduty-mobile in Slack about the GV upgrade task being broken.
* Use Sentry, GitHub, and Bugzilla to determine if the crash has already been reported. If a Bugzilla bug has been filed for a crash, a link to the bug should be listed in Socorro's "Bugzilla IDs" column.
* If the crash is new and the volume is high, then consider filing an issue.
* If the crash is a native crash, file a bug using the crash-stats Bugzilla tab from a crash ID.
* If the crash is a Java crash, then consider opening an issue on GitHub.

@ -0,0 +1,67 @@
These are instructions for preparing a release branch for Fenix Beta release. For reference, the AC release checklist can be found at https://mozac.org/contributing/release-checklist.
## [Release Management] Creating a new Beta release branch
**This part is 100% covered by the Release Management team. The dev team should not perform these steps.**
1. Create a branch name with the format `releases_v[beta_version].0.0` (for example: `releases_v87.0.0`) off of the `main` branch using the GitHub UI. `[beta_version]` should follow the Firefox Beta version number. See [Firefox Release Calendar](https://wiki.mozilla.org/Release_Management/Calendar).
2. Verify that `version.txt` already refers to the Fenix Beta release version `[beta_version].0b1` in the `releases_v[beta_version].0.0` branch. Bump it manually if necessary.
3. In the `main` branch, create a pull request to update `version.txt` to `[nightly_version].0b1`. Land the updated `version.txt` into `main` with a review from someone from RelMan (#releaseduty-mobile). See [#26177](https://github.com/mozilla-mobile/fenix/pull/26177) for example.
4. Notify the dev team that they can start the new Nightly development cycle per the steps given in the next section ⬇️
5. Once the new AC `v[beta_version].0b1` release is ready (see the [AC release checklist](https://mozac.org/contributing/release-checklist)), create a pull request targeting the `releases_v[beta_version].0.0` branch to pin the Android Components `VERSION` to `[beta_version].0b1`. The commit message should be `Set Android-Components version to [beta_version].0b1`.
```diff
diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt
--- a/buildSrc/src/main/java/AndroidComponents.kt
+++ b/buildSrc/src/main/java/AndroidComponents.kt
@@ -3,5 +3,5 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
object AndroidComponents {
- const val VERSION = "110.0.20230115143320"
+ const val VERSION = "110.0b1"
}
```
6. Announce the new `releases_v[beta_version].0.0` branch on Slack in #releaseduty-mobile.
7. Once the AC version bump has landed, create the new Fenix Beta release in [Ship-It](https://shipit.mozilla-releng.net/) per normal practice.
## [Dev Team] Starting the next Nightly development cycle
**Release Management will take care of updating `version.txt` for the `main` branch in order to prepare beta versions of our Nightly release.**
### [Dev Team] Create new milestone
Create a new [milestone](https://github.com/mozilla-mobile/fenix/milestones) for the `[nightly_version]` and close the existing `[beta_version]` milestone.
The milestone is an indicator of the Fenix version where the code related to the issue is landed, and does not need to reflect when the issue is closed by QA verified. This is useful for keeping track of when a feature is shipped.
Examine all the remaining open issues in the closed milestone to see if the issue should be closed or remove the tagged milestone depending on what is appropriate. If an issue is still in "eng:qa-needed", then it is fine to let it remain in the current closed milestone and open. If an issue clearly doesn't require "eng:qa-needed" (eg, Remove strings in 104, Fix typo, etc), then remove the label and close the issue. If an issue is clearly unresolved due to being reopened by QA and work still continues, remove the milestone.
### [Dev Team] Renew telemetry
After the Beta cut, another task is to renew/remove all soon to expire telemetry probes. What we're looking for is to create a list of telemetry that will expire in `[nightly_version add 2]`. See [Firefox Release Calendar](https://wiki.mozilla.org/Release_Management/Calendar) for the current Release version. There is a script that will help with finding these soon to expire telemetry.
1. Use the helper in tools folder `python3 data_renewal_generate.py [nightly_version add 2]` to detected and generate files that will help create the following files:
- `[nightly_version add 2]`_expiry_list.csv
- `[nightly_version add 2]`_renewal_request.txt
2. Upload the `[nightly_version add 2]`_expiry_list.csv to Google sheet in this [shared Google Drive](https://drive.google.com/drive/folders/1_ertMvn59eE9JmN721RqOjW6nNtxq9oS?usp=sharing) and contact product to review. For each telemetry listed answer decide for:
- Renew the metric (Recommendation is to use nightly_version + 12)
- Choose not to renew (but not delete)
- Choose to remove the metric
- Renew the metric and set to never expire (this should only be for business critical metrics)
3. Note that `metrics.yaml` is also modified. Once the review is over, continue to modify `metrics.yaml` to match the decision made in the Google sheet. Make sure to add the PR link and if the telemetry never expires, add the email of the owner as contact.
4. File an issue for telemetry renewal so that a patch can target it and assign the issue to Product for increased visibility, as a reminder to to address the expiring metrics. See [issue 28190](https://github.com/mozilla-mobile/fenix/issues/28190) for an example.
5. Create a PR for review. Modify `[nightly_version add 2]`_renewal_request.txt and paste it to the PR for data review. This comment can be auto-generated using the filled `[nightly_version add 2]`_expiry_list.csv and the `tools/data_renewal_request.py` helper. Copy the filled CSV into the tools directory and run the script to create a `[nightly_version add 2]`_filled_renewal_request.txt file that will contain the text required for data review. Make sure it includes (or add manually if necessary):
- When will this collection now expire?
- Why was the initial period of collection insufficient?
6. Please also check if you're responsible for Focus telemetry renewal.
### [Dev Team] Remove unused strings
Now that we made the Beta cut, we can remove all the unused strings marked moz:removedIn <= `[release_version subtract 1]`. `[release_version]` should follow the Firefox Release version. See [Firefox Release Calendar](https://wiki.mozilla.org/Release_Management/Calendar) for the current Release version.
1. File a GitHub issue named "Remove all unused strings marked moz:removedIn <= `[release_version subtract 1]`".
2. Search and remove all strings marked `moz:removedIn="[release_version subtract 1]"`.
3. Put up a pull request.
4. Please also check if you're responsible for Focus as well.
### Ask for Help
If you run into any problems, please ask any questions on Slack in #releaseduty-mobile.

@ -0,0 +1,23 @@
## This document outlines how data is collected in Firefox Preview.
### Telemetry
When a user has "Telemetry" enabled under Data Choices in the browser settings, Firefox Preview sends a "core" ping and an "event" ping to Mozilla's telemetry service. "core" ping using the same format documented on firefox-source-docs.mozilla.org.
[Here](https://github.com/mozilla-mobile/fenix/blob/master/docs/metrics.md) is a list of Event Pings, Metrics Pings, and Activation Pings.
**User can disable telemetry by turning the Telemetry toggle off under Data Choices.**
***
### Adjust
See [here](https://github.com/mozilla-mobile/fenix/wiki/Adjust-Usage) for details on Adjust usage in Firefox Preview.
***
### Sentry
Sentry collects a stack trace for each crash in Fenix.
If the user has "Telemetry" enabled under Data Choices in the browser settings, then Sentry collects breadcrumbs containing the name of each Android Fragment in the app. This helps an engineer diagnose the cause of the crash by seeing the internal names of screens visited before the crash occurred, i.e. Browser, Search, Home, etc. No information is stored about any arguments passed to any Fragments.

@ -0,0 +1,23 @@
It's important to know where we require tests and where they don't add significant value. This document intends to lay out that distinction.
In general, it's not necessary to test that the Android framework does what it says it does. If a code path sets the value of a TextView, one does not need to write an Espresso or Robolectric test to check that the TextView was set. This is why the Android framework team at Google has tests. Espresso tests are expensive in terms of runtime and should be used to ensure that all units of our software are correctly integrated together as a whole. Even Robolectric imposes a noticeable cost on test runtime, but it has proper uses.
### Components
Our app architecture is tied together by components that render UI. Generally, it's smart to write a set of unit tests for every UI component, but to mock the view. This can be accomplished by creating a Spy for the component. One may observe inputs and outputs of the component under test using RxKotlin TestObservers.
When testing Components, it's important to test any significant logic. If a reducer has more logic than mere Kotlin copy() operators, it should be tested.
### UIViews
When testing UIViews, we don't need to verify TextView set calls are made, but we should verify any branching logic that exists. If the ViewState is not basically ready to display, those transformations probably belong in the component and should be tested there. If the UIView class is simply a straight conduit from the ViewState directly to the UI, then there is no need for unit tests.
### Fragments
Fragments can get complicated. In theory, there should not be much View logic if the architecture is correctly integrated. One can mock out any components and the extension methods which perform layout and then use Robolectric to verify significant logic.
Generally, there shouldn't be large, branching blocks directly inside Android lifecycle callbacks. These should be broken out into methods, which can be tested on their own.
### Activities
Activities should exist only as entry points to the app in order to display fragments. The logic should be limited and should be testable as Robolectric tests with TestNavigators for testing navigation.

@ -0,0 +1,134 @@
Project board: https://github.com/orgs/mozilla-mobile/projects/40
# 📱 Testing
⚠️ **Warning**: Replacing a _Fennec_ (Firefox for Android) installation with _Fenix_ (Firefox Preview) can (and at the time of writing this definitely **will**) result in **DATA LOSS**. Do not replace an installation of Fennec (Firefox for Android) that contains data you do not want to risk losing (e.g. open tabs, history, bookmarks, top sites, ..).
## Release
The following links point to the latest *Fenix* (Firefox Preview) builds (Nightly; from `main`) that are setup to **replace** a *Fennec* (Firefox for Android) release version (`org.mozilla.firefox`).
* [ARM64/Aarch64 devices (64 bit; Android 5+)](https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/project.mobile.fenix.v2.fennec-production.latest/artifacts/public/build/arm64-v8a/geckoBeta/target.apk)
* [ARM devices (32 bit; Android 5+)](https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/project.mobile.fenix.v2.fennec-production.latest/artifacts/public/build/armeabi-v7a/geckoBeta/target.apk)
* [x86_64 devices (64 bit; Android 5+)](https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/project.mobile.fenix.v2.fennec-production.latest/artifacts/public/build/x86_64/geckoBeta/target.apk)
* [x86 devices (32 bit; Android 5+)](https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/project.mobile.fenix.v2.fennec-production.latest/artifacts/public/build/x86/geckoBeta/target.apk)
## Beta
The following links point to the latest *Fenix* (Firefox Preview) builds (Nightly; from `main`) that are setup to **replace** a *Fennec Beta* (Firefox for Android - Beta) release version (`org.mozilla.firefox.beta`).
* [ARM64/Aarch64 devices (64 bit; Android 5+)](https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/project.mobile.fenix.v2.fennec-beta.latest/artifacts/public/build/arm64-v8a/geckoBeta/target.apk)
* [ARM devices (32 bit; Android 5+)](https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/project.mobile.fenix.v2.fennec-beta.latest/artifacts/public/build/armeabi-v7a/geckoBeta/target.apk)
* [x86_64 devices (64 bit; Android 5+)](https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/project.mobile.fenix.v2.fennec-beta.latest/artifacts/public/build/x86_64/geckoBeta/target.apk)
* [x86 devices (32 bit; Android 5+)](https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/project.mobile.fenix.v2.fennec-beta.latest/artifacts/public/build/x86/geckoBeta/target.apk)
## Nightly
The following links point to the latest *Fenix* (Firefox Preview) builds (Nightly; from `main`) that are setup to **replace** a *Fennec Nightly* (Firefox for Android - Nightly) release version (`org.mozilla.fennec_aurora`).
* [ARM64/Aarch64 devices (64 bit; Android 5+)](https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/mobile.v2.fenix.nightly.latest.arm64-v8a/artifacts/public/build/arm64-v8a/target.apk)
* [ARM devices (32 bit; Android 5+)](https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/mobile.v2.fenix.nightly.latest.armeabi-v7a/artifacts/public/build/armeabi-v7a/target.apk)
* [x86_64 devices (64 bit; Android 5+)](https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/mobile.v2.fenix.nightly.latest.x86_64/artifacts/public/build/x86_64/target.apk)
* [x86 devices (32 bit; Android 5+)](https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/mobile.v2.fenix.nightly.latest.x86/artifacts/public/build/x86/target.apk)
# 📝 Changelog
The data migration work is tracked on the following project board:
https://github.com/orgs/mozilla-mobile/projects/40
* **2019-09-05** - The first [migration builds](https://tools.taskcluster.net/index/project.mobile.fenix.v2.fennec-production/latest) are available now. A Firefox for Android (release) installation can be replaced with them. No actual migration code is in those builds yet. The replaced build is a "clean" Fenix installation.
* **2019-10-22** - First iteration of migration code to migrate history, bookmarks and open tabs landed in builds.
* **2019-11-02** - Firefox Account users remain logged in after migrating to Fenix.
# 💻 Development
When working on migration code it is helpful to have a local Fennec build and a local Fenix build that can replace the Fennec build. The following manual setup is needed to achieve that.
In the example commands below, we assume you are replacing a **Fennec Nightly** build with a **Fenix Nightly** build.
## Fennec
Download the latest version of Fennec:
- [ARM64/Aarch64 devices (64 bit; Android 5+)](https://archive.mozilla.org/pub/mobile/nightly/latest-mozilla-esr68-android-aarch64/)
- [ARM devices (32 bit; Android 5+)](https://archive.mozilla.org/pub/mobile/nightly/latest-mozilla-esr68-android-api-16/)
- [x86_64 devices (64 bit; Android 5+)](https://archive.mozilla.org/pub/mobile/nightly/latest-mozilla-esr68-android-x86_64/)
- [x86 devices (32 bit; Android 5+)](https://archive.mozilla.org/pub/mobile/nightly/latest-mozilla-esr68-android-x86/)
Strip out the original signature:
```
zip --delete fennec.apk "META-INF/*"
```
Re-sign the APK with your own debug key (that will also be used later for Fenix):
```
jarsigner -verbose -keystore ~/.android/debug.keystore -storepass android -keypass android fennec.apk androiddebugkey
```
You can now install this APk that is ready to be used for migration:
```
adb install fennec.apk
```
## Fenix
In the `app/build.gradle`, add the following line in the correct scope to sign your app with the same debug key used on the Fennec APK:
```groovy
android {
buildTypes {
fennecNightly {
signingConfig signingConfigs.debug
}
}
}
```
Follow the build instructions in the [README](https://github.com/mozilla-mobile/fenix/blob/main/README.md) to get a Fenix build setup.
Now select the `geckoNightlyFennecNightly` build variant in Android Studio and deploy it. This build should have replaced your Fennec build now.
## Sample browser
When working on migration code that lives in the [Android Components repository](https://github.com/mozilla-mobile/android-components) it can be helpful to replace a local Fennec build with the sample browser (instead of Fenix). The following setup is needed for that.
Add the sharedUserId to the AndroidManifest.xml of sample browser:
```XML
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:sharedUserId="org.mozilla.fennec_$USERNAME.sharedID"
[..]
```
Modify the application id in `build.gradle` of the `samples-browser` module and use a versionCode that is higher than your Fennec build (`2100000000` is the highest allowed version code and therefore should always work).
```Groovy
defaultConfig {
applicationId "org.mozilla.fennec_$USERNAME"
[..]
versionCode 2100000000
```
Click on "Sync Project with Gradle Files" and deploy the sample browser. This build should have replaced your Fennec build now.
## Emulator snapshots
When testing migration code the following process has to be repeated multiple times:
* (1) Uninstall an already existing Fennec/Fenix installation
* (2) Install Fennec
* (3) Use Fennec to create the necessary data for testing the migration
* (4) Install Fenix
* (5) Debug / Test
Steps (1) to (3) can be quite time consuming. Emulator snapshots can help with that:
* Launch an emulator and perform steps 1 to 3. You may need to modify your Fennec build to create an X86 build for your emulator (target `i686-linux-android`).
* Click on the three dot menu in the emulator toolbar and select "Snapshots". Press the "Take Snapshot" button. If needed give you snapshot a descriptive name in case you will need to have multiple "test snapshots".
* With the "Play" button you can always reset your emulator to that state and repeat the migration process.

@ -0,0 +1,111 @@
## Communication channels
We have a variety of communication channels for internal dev, and best practices are [documented here](https://docs.google.com/document/d/1Qr-uVqbTO9mGGCvF1IW0s0OM2Cdkr2UYwCzrIzqVdnA/edit#).
## Creating Features
See [Feature Workflow](https://github.com/mozilla-mobile/fenix/wiki/Feature-Workflow)
## Design Feasibility
Who: Design lead, designer, engineering lead, engineer, product lead, product manager
Purpose: meet any time we start design for a new feature (esp large ones) to discuss:
* Overall concept and user goals
* Where the feature fits within the Fenix system
* Any existing technical constraints or dependencies (on Android OS, or other Firefox Mobile teams like GV or A-C)
* Alignment on user stories
Design Handoff
Who: designer, engineer, product manager, QA lead
Purpose: before engineering sprint for a feature starts to discuss:
* Overall purpose of feature and how it relates to or interacts with existing features
* Discuss expectations for functionality
* Discuss visual and interactive design elements
* Negotiate scope and discuss changes if tasks are too large for a single sprint
## Triage
* The team triages GitHub issues asynchronously. This involves reviewing all new issues (bugs, crashes, and feature requests) to determine whether they should be addressed in MVP or added to backlog for future sprints.
### Process
* Add appropriate labels for [features](https://github.com/mozilla-mobile/fenix/labels?q=Feature)
* Add to appropriate Projects ([1](https://github.com/orgs/mozilla-mobile/projects), [2](https://github.com/mozilla-mobile/fenix/projects))
* Note any urgent issues and tag the Product Team when needed
## Sprint Planning
### Sprint pre-planning:
* Build sprint plan based on what is ready (UX/dependencies), priority, and complexity.
### During Sprint Planning:
* Assign stories/bugs to sprint up to capacity, and resolve any open questions.
* Size stories as needed. Most sizing is happening asynchronously.
* Go over UX Sprint Plan
## Backlog Grooming
* During Backlog Grooming, review and all user stories assigned to Backlog that have not been sized.
* ...
## During Sprint
* Engineers will label stories as “in progress” as they work begin work on them, and assign story to themselves.
* IF a user story has a UX component that needs review, when it is ready for review, engineer will add a screenshot/gif and @mention the designer in the user story. Add the [needs:ux-review](https://github.com/mozilla-mobile/fenix/labels/needs%3AUX-review) label to the PR.
* When a PR has been merged in, the Merger verify that Milestone this code will ship in to the issue. (Careful around soft code freeze! The release may have already been cut, which affects the current milestone.)
* Engineers will label stories with [eng:qa:needed](https://github.com/mozilla-mobile/fenix/labels/eng%3Aqa%3Aneeded) when the ticket is ready to be tested.
* QA will label the story as [eng:qa:verified](https://github.com/mozilla-mobile/fenix/labels/eng%3Aqa%3Averified) and close the ticket (which will move it to the “Done” column).
* If a ticket becomes blocked and will miss the sprint, engineers will label it “waiting” and notify the Product Team with the reason. This issue will be moved back to the appropriate backlog.
* Engineers will remove the “waiting” label and re-apply the appropriate label (“in progress,” “QA needed”).
## UX Review
IF a user story has a UX component that needs review, when it is ready for review:
* Consider hopping on a call to do a desk check with the Designer*
* Engineer will add a gif/screenshot/apk (as applicable to the issue)
* Engineer will @mention the designer in the user story and ping the Designer on Slack, and add the `needs:UX-feedback` label
UX designer reviews the component (consider hopping on a call to work through minor changes). Communication is key to here between designer and engineer in how they want to go through edits.
We will also go through UX review during Sprint Demos.
## Copy Review
IF a user story has a String that needs a review, when it is ready for review:
* Raise an issue in Fenix as feature request.
* Add the needs:strings label.
* Add the screenshot where the string will be applied.
* Add detail explanation of the use case.
* Comment asking the UX designer to review.
## Engineering review
Use tags on open PRs to show which part of the process it is on. Some notable ones:
1. [needs:review](https://github.com/mozilla-mobile/fenix/labels/needs%3Areview) - PR that needs a review. Anyone should jump on any reviews with this label and help out with reviews. Thanks in advance.
2. [pr:needs-ac](https://github.com/mozilla-mobile/fenix/labels/needs%3Aac) - PR that is waiting for a AC bump. Typically, we use “waiting”, but this provides us with a bit more context.
3. [pr:approved](https://github.com/mozilla-mobile/fenix/labels/pr%3Aapproved) - PR that has been approved. This one is a bit easier to parse visually compare to the Approved in the GitHub summary
4. [pr:waiting-for-authors](https://github.com/mozilla-mobile/fenix/labels/pr%3Awaiting-for-authors) - PR that has been approved and awaiting any changes before they can land. Usually a PR might be approved, but has not been landed because it is waiting for followup changes.
## QA
* Engineers will label stories as [eng:qa:needed](https://github.com/mozilla-mobile/fenix/labels/eng%3Aqa%3Aneeded) when the ticket is ready to be tested (which will move the ticket to the Ready for QA column).
* QA will review the ticket and determine whether it can be manually tested. If no QA is needed, QA will close the ticket and move it to the Done column.
IF a defect is found:
* a comment is added to the story @mentioning the engineer
* the defect is linked as a dependency for the story
* The QA Needed label is removed.
* The related story is set to In Progress.
* When the defect has been fixed, the Engineer will add the QA Needed label to the story again.
* When all critical defects have been fixed, QA will label the story as “QA verified” and close the ticket (which will move it to the “Done” column).
## Testing Performance Impact of Code Changes
- The Performance team wrote this up for reference: https://wiki.mozilla.org/Performance/Fenix/Performance_reviews
## Accessibility
* During design reviews, we should ask ourselves if custom UI is necessary to accomplish the desired behavior. Oftentimes, out of the box android UI has accessibility and localization built in, whereas with custom pieces we need to build it ourselves.
* For new features that have UI elements that are unique to Fenix or have user interaction, test them personally with TalkBack (just as you would test to make sure the feature works before submitting a patch)
* Before submitting a patch, run the Accessibility Scanner over the screens affected to ensure no new issues are introduced (and post a screenshot of your results)
* QA should test tickets that have “eng:qa:needed” with accessibility services (like TalkBack) enabled and only mark them as “eng:qa:verified” if these services work well with the new feature
* As mentioned in the ticket, QA team will be adding accessibility checks to UI tests over time
* Remember: the earlier we catch issues in the process (closer to dev coding or UX designing) the less work it is for everyone involved! So please be diligent about going through these checks before submitting a patch.
## Templates
- We've created templates for new issues with instruction on how to fill them out based on their request/nature [here](https://github.com/mozilla-mobile/fenix/issues/new/choose)
More details in [link to Process Doc & Flowchart](https://docs.google.com/document/d/1w_6G4uCfQjyBh0ilQZKz3G-0IvBhzExlg80kaJrBA3c/)
## Adding Locales
The completion rate of different locales can be seen on [Pontoon](https://pontoon.mozilla.org/projects/android-l10n/).
While the project is in Preview stage, all locales will be the same between Firefox Preview and Firefox Preview Nightly.
Before we do our next large, milestone release, we'll update the Release locales to match the ones approved by L10N to have reached sufficient localization completion.

@ -0,0 +1,52 @@
# Guide to merging contributor PRs for Firefox Android team members
Contributor PRs will run only a specific suite of CI tests (excluding UI tests) in order to protect secrets. Once a Firefox Android team member has reviewed the PR and deemed it safe, we can use the following steps to run the full CI suite and land the patch.
## Command line instructions
_Note: these instructions use https://cli.github.com/_
1. Fetch upstream changes and locally check out the contributor's branch onto your fork
```sh
git fetch --all
gh pr checkout <PR number>` or `gh pr checkout <PR number> -R mozilla-mobile/fenix
# Example:
gh pr checkout 12345 -R mozilla-mobile/fenix # for https://github.com/mozilla-mobile/fenix/pull/12345
```
2. Rename your local branch's name
```
git branch -m <new branch name>
# Example: If the contributor's branch is named `eliserichards:my-fun-branch1`
git branch -m ci-for-my-fun-branch1
```
3. Push branch to your fork using any branch name:
```sh
git push origin <pr-branch-name>
# Example: If the contributor's branch is named `eliserichards:my-fun-branch1`
git push origin ci-for-my-fun-branch1
```
4. Create a PR from _your fork's_ copy of the branch e.g. https://github.com/mozilla-mobile/fenix/compare/main...eliserichards:my-fun-branch1
* Please note in the PR description which PR you are running CI for. Example: https://github.com/mozilla-mobile/fenix/pull/27530
***
**Once you create this PR, the CI for both the original and the duplicate PRs will run. When everything is green, you can merge either of them.**
5. To land the duplicate, close the original PR first, refresh mergify (`@Mergifyio refresh`), and then add `needs-landing` label to your PR.
* Mergify wont merge the duplicate while the original is open, since they both have the same SHA and mergify does honour the first one over those created consequently.
OR
5. To land the original:
* i. Make sure that contributor's branch hasn't diverged from yours (they must have the same SHA).
* ii. The change has to be on the top of the main branch when it is first in line in the merge queue.
* iii. It requires the needs-landing label.
**NB**: Adding `needs-landing` label while failing to ensure the same SHA will block the mergify queue and will require manual intervention: mergify will trigger CI for the original PR again and wait for it to finish, but CI wont run all the checks because there is no PR with the same SHA any more that backs it up. If that happens, talk to the release team.

@ -0,0 +1,31 @@
# Firefox for Android (Fenix Project)
Firefox for Android is Mozilla's new browser for Android devices. Powered by GeckoView and built on Android Components, Fenix is a pilot for early adopters, developers, and anyone who wants to help make a better, more private Firefox for Android.
Firefox for Android is the first step in building a better mobile browser: one thats faster, more secure and more independent than any mobile Firefox browser before it. It will combine the speed, privacy, control, and easy-to-use features you have come to expect from Firefox.
*Don't see what you're looking for? Check out our shared docs: https://github.com/mozilla-mobile/shared-docs.*
## User support
* Support articles: https://support.mozilla.org/en-US/products/mobile
* Support forum: https://support.mozilla.org/en-US/questions/mobile
## Download
* Google Play: [Release](https://play.google.com/store/apps/details?id=org.mozilla.firefox)
* Google Play: [Beta](https://play.google.com/store/apps/details?id=org.mozilla.firefox_beta)
* Google Play: [Nightly](https://play.google.com/store/apps/details?id=org.mozilla.fenix)
* Release APKs: https://github.com/mozilla-mobile/fenix/releases
* Nightly APKs: https://firefox-ci-tc.services.mozilla.com/tasks/index/mobile.v2.fenix.nightly.latest
## Contribute
* [Contributing (Writing code, translating the app, testing the app)](https://github.com/mozilla-mobile/shared-docs/blob/master/android/CONTRIBUTING.md)
* [List of good first issues for new contributors](https://github.com/mozilla-mobile/fenix/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22+)
* [Mozilla Community Participation Guidelines](https://www.mozilla.org/en-US/about/governance/policies/participation/)
## Communication
* External: [#fenix](https://chat.mozilla.org/#/room/#fenix:mozilla.org) on [Element](https://wiki.mozilla.org/Matrix)
* External: [Firefox on Android discourse](https://discourse.mozilla.org/c/firefox-android/468)
* Internal: Find us on slack #fenix-team

@ -0,0 +1,44 @@
## Things to note before implementation:
* Understand that telemetry is important, it is not just a checkmark for feature completion.
* The consumer of the telemetry is the data science team.
* When in doubt, please follow the example implementation, documentation and data review format linked below.
* Avoid using SharedPreferences.
* Write unit tests.
## Procedure to follow before implementing the telemetry:
1. Contact Product team to understand the feature that we are adding telemetry to.
2. Contact the Data Science team to get the full requirements. This includes:
* The categories that the Data Science team expects data from?
* What are the telemetries the Data Science team expects in each category?
* What type of data for each telemetry?
3. Work with the Data Science team to raise/lower expectations. Refine the requirements until every telemetry is clearly specified. This includes:
* Inform the Data Science team which telemetry is not achievable. (if exists)
* Inform the Data Science team other possible telemetry that they might not know about.
* Inform the Data Science team what might not make sense to collection. (Ex: B always happens when A happens)
* Help the Data Science team collect the best telemetry data possible.
4. Consult with the Glean team if theres any questions. (Ex: What type of data to use)
## Procedure to follow when implementing a Glean telemetry event
* A full example of adding an event with keys can be found [here](https://github.com/mozilla-mobile/android-components/pull/10837) (Android Components), [here](https://github.com/mozilla-mobile/fenix/pull/20909) (Fenix) and [here](https://github.com/mozilla/glean-annotations/pull/77) (Glean Annotation)
1. Create an event in [metrics.yaml](https://github.com/mozilla-mobile/fenix/blob/master/app/metrics.yaml) and do a project rebuild to generate the event
2. To add feature tags see steps [here](https://github.com/mozilla-mobile/fenix/wiki/Metric-Feature-Tags).
5. Send the event from the proper place in the code with the appropriate generated method (e.g. `GeneratedClassMetrics.generatedEvent.record()`)
6. Create pull requests
7. Submit a data review ([example here](https://github.com/mozilla-mobile/fenix/pull/20909#issuecomment-902119039)). There's also a [command-line tool for generating Data Review Requests](https://chuttenblog.wordpress.com/2021/09/07/this-week-in-glean-data-reviews-are-important-glean-parser-makes-them-easy/)
8. Update the [metrics.yaml](https://github.com/mozilla-mobile/fenix/blob/master/app/metrics.yaml) with the data review
9. For startup metrics, make sure to [manually test it](https://github.com/mozilla-mobile/fenix/wiki/Test-telemetry-pings)
## Review
See example [here](https://github.com/mozilla-mobile/fenix/pull/20909)
* Add a developer that understands telemetry to review your change.
* Add a developer from the Glean team as reviewer if needed.
* Data review format [here](https://github.com/mozilla/data-review/blob/main/request.md). ([example here](https://github.com/mozilla-mobile/fenix/pull/20909#issuecomment-902119039))
## After Merge
1. Make a note to revisit your telemetry changes when it makes it to beta/release.
* for events, go to Glean dictionary and find the event you want to verify. Click on the Looker link on the bottom of the page to confirm that the event is being reported. (For example, for credit_cards.modified, the Glean dictionary link is https://dictionary.telemetry.mozilla.org/apps/fenix/metrics/credit_cards_modified. On the bottom click on the "credit_cards.modified" link next to Looker to see event count)
* for metrics, create a query (ex: https://sql.telemetry.mozilla.org/queries/82373) to confirm that metric is being reported.
2. Work with the data science team to make sure that they are seeing data that meet their requirements.
## Renewing Expiring Telemetry
See steps [here](https://github.com/mozilla-mobile/fenix/wiki/Creating-a-release-branch#renew-telemetry)

@ -0,0 +1,12 @@
Follow instructions in https://experimenter.info/mobile-feature-api. Example implementation [here](https://github.com/mozilla-mobile/fenix/pull/23996)
Nimbus FML https://experimenter.info/fml-spec/
There are some clarification on how to test your Nimbus implementation:
1. Add `nimbus.remote-settings.url=https://settings-cdn.stage.mozaws.net` to local.properties.
2. After building Fenix, make sure you turn on `Secret Settings` -> `Use Nimbus Preview Collections`.
3. The experiment in https://stage.experimenter.nonprod.dataops.mozgcp.net/nimbus/ does not have to be live for the test. In preview is sufficient.
4. Example of a test is [here](https://stage.experimenter.nonprod.dataops.mozgcp.net/nimbus/unified-search-test)
5. Make sure you archive the test after you're done with it.
6. In your PR, make sure to submit the change for .experimenter.yaml as well.

@ -0,0 +1,51 @@
To profile background threads using the Firefox Profiler, you need to specify their names. It uses a case-insensitive substring match, e.g. specifying `default` will match all threads in the kotlin default dispatcher which have a name like, `DefaultDispatcher-worker-*`. This document is a list of the threads in fenix (via `ThreadGroup.list()` as of Mar 2022) to make using this functionality easier:
```
AutoSave-thread-1
BrowserIcons-thread-1
BrowserIcons-thread-2
BrowserIcons-thread-3
BrowserStore-thread-1
ConnectivityThread
DefaultDispatcher-worker-1
DefaultDispatcher-worker-2
DefaultDispatcher-worker-3
DefaultDispatcher-worker-4
DefaultDispatcher-worker-5
DefaultDispatcher-worker-6
DefaultDispatcher-worker-7
DefaultDispatcher-worker-8
FinalizerDaemon
FinalizerWatchdogDaemon
FxaAccountManager-thread-1
Gecko
GeckoInputConnection
GleanAPIPool
HeapTaskDaemon
HistoryMetadataService-thread-1
LeakCanary-Heap-Dump
NimbusDbScope-thread-1
NimbusFetchScope-thread-1
PlacesStorageWriteScope-thread-1
ReferenceQueueDaemon
ThumbnailStorage-thread-1
ThumbnailStorage-thread-2
ThumbnailStorage-thread-3
WM.task-1
WM.task-2
WM.task-3
WM.task-4
androidx.work-1
androidx.work-2
arch_disk_io_0
arch_disk_io_1
arch_disk_io_2
arch_disk_io_3
glean.MetricsPingScheduler
main
pool-23-thread-1
pool-9-thread-1
pool-9-thread-2
queued-work-looper
```
Note that `arch_disk_io_*` represents the kotlin io dispatcher.

@ -0,0 +1,54 @@
# Retrieving crash reports from the application
* Open Firefox
* Tap on the `3 dot menu`
* Tap `Settings`
* Scroll to the bottom of Settings
* Tap `About Firefox`
* Tap `Crashes`
* Tap on the Socorro link
* Copy and paste that address into a new [Github Issue: 🐞 Bug report](https://github.com/mozilla-mobile/fenix/issues/new/choose) or an existing issue
* If you have many crash reports it can be helpful to include several of the recent crash URLs
![Screenshot showing where to find the settings and About Firefox elements of the app. The bulleted steps above contain the same information.](https://user-images.githubusercontent.com/250273/84347868-7bc9e980-ab68-11ea-990d-7284968c458a.png)
![Screenshot showing where to find the Crashes item in About Firefox and the Socorro link for the crash. ](https://user-images.githubusercontent.com/250273/84347924-a156f300-ab68-11ea-9d02-c984a030249f.png)
# Using adb logcat to get crash information
Please use the above directions as a first way to get info. Use the following directions if your crash does not show up in the crash window of Firefox or if the crash prevents you from accessing the settings of Firefox.
To get information about a crash you will need an Android device that reproduces a crash, a computer running Windows, macOS or Linux and a USB cable that connects your device to your computer.
## Configuring your phone
* Enable Developer Mode
* On stock Android open the Android Settings and use the search at the top to find `build number`
* Tap the build number 7 times
* For other devices use your favorite search engine or YouTube to find steps for your device.
* Enable Android USB debugging
* On stock Android Open the Android Settings and use the search at the top to find `USB debugging` and enable it
* Connect your device to the computer using a USB cable
## Downloading the Android SDK Platform tools
* Download the [Android SDK Platform tools](https://developer.android.com/studio/releases/platform-tools) for your operating system
* Use your operating system tools to extract the zip file that was downloaded
## Checking that adb can see your phone and is authorized
* Connect your device to the computer using a USB cable
* Open a command prompt or terminal and change to the directory to the platform tools directory that was extracted
* On Windows run the command `adb devices` on macOS and Linux run `./adb devices`
* If it returns unauthorized you will need to authorize the phone to connect to the computer by accepting the connection dialog on the phone
## Reproducing the crash
* Connect your device to the computer using a USB cable
* Open a command prompt or terminal and change to the directory to the platform tools directory that was extracted
* On Windows run `adb logcat -v time` on macOS and Linux run `./adb logcat -v time`
* Reproduce the crash
* Submit the crash report(s)
* Unplug the device
* Copy all the information in the terminal
* Paste the information into a Gist https://gist.github.com/ and save logcat information
* Add the Gist URL to the issue for the crash
## Optional Cleanup
* It is recommended to disable USB debugging once you are done collecting this information
* You can remove the Android SDK Platform tools by deleting the folders and zip file

@ -0,0 +1,35 @@
To help find metrics in the [Glean Dictionary] and other tools, metrics should contain tag metadata corresponding to the
feature area(s) that they belong to. In the case of Firefox for Android, tag information is based off of the GitHub feature labels for this repository:
https://github.com/mozilla-mobile/fenix/labels?q=feature%3A
You can see how tag information is rendered here:
https://dictionary.telemetry.mozilla.org/apps/fenix?itemType=tags&page=1
## Adding feature tags to metrics
Adding tag information to a metric used to involve editing the [Glean Annotations repository], but you can now add this
information directly when adding or modifying `metrics.yaml`. Just add a section called `metadata` to the metric and add a list of tags that correspond to it.
For example:
```yaml
search_bar_tapped:
type: event
description: |
A user tapped the search bar
metadata:
tags:
- Search
...
```
## Updating the feature tags
The set of valid tags is documented in a file called `tags.yaml`, but should never be updated by hand.
If a feature labels is ever added or removed, you can synchronize the tags file in the source tree by running `./tools/update-glean-tags.py` in the root of the repository.
Note that a tag *must* be specified in `tags.yaml` for it to be usable in a metric, so if a tag is removed from `tags.yaml` all uses of it must be removed from `metrics.yaml`.
[Glean Dictionary]: https://dictionary.telemetry.mozilla.org
[Glean Annotations repository]: https://github.com/mozilla/glean-annotations

@ -0,0 +1,107 @@
See https://github.com/mozilla-mobile/fenix/wiki/Telemetry-Checklist for the steps to implement new probes.
# Creating Glean Annotations
Glean Annotations repository: https://github.com/mozilla/glean-annotations
See [Add a Glean Annotation for an event](https://github.com/mozilla-mobile/fenix/wiki/Add-a-Glean-Annotation-for-an-event) for instructions.
More info [here](https://mozilla.github.io/glean-annotations/contributing/creating/)
# Data review
Data reviews are needed on all PRs that add new telemetry or modify existing telemetry.
1. The implementer must complete the forms for [data renewal](https://github.com/mozilla/data-review/blob/main/renewal_request.md) or [a new data request](https://github.com/mozilla/data-review/blob/main/request.md) and put them as a comment in their PR.
2. Once the form is complete, contact a [Data Steward](https://wiki.mozilla.org/Data_Collection) to arrange a review. Note: a data review does not replace code review! The PR should not land without both a data review and a code review.
3. Once the data review is complete, add the link to the approval in the `data_reviews` sub-section of your metric in the `metrics.yaml` file.
Example:
```
download_notification:
resume:
type: event
description: |
A user resumed a download in the download notification
bugs:
- https://github.com/mozilla-mobile/fenix/issues/5583
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/6554
- https://github.com/mozilla-mobile/fenix/pull/13958#issuecomment-676857877
- https://github.com/mozilla-mobile/fenix/pull/18143
data_sensitivity:
- interaction
notification_emails:
- fenix-core@mozilla.com
expires: "2021-07-01"
```
When a telemetry probe is being renewed, do not remove the old data review links from `metrics.yaml`. The new approval should be added to the existing list.
Make sure you are selecting the correct Category of data that is being collected: https://wiki.mozilla.org/Data_Collection#Data_Collection_Categories
# Renewing existing telemetry
1. Collect a list of metrics from metrics.yaml file in Fenix that will be expiring in that month
a. Currently compiling these in [this doc](https://docs.google.com/document/d/1NGlnTa9TPyTnd3ciUPbwujbITjkX8p8vJybXcZrrM2w/edit#)
b. This should be done at least a few weeks prior to the events/metrics' expiration date
c. Including metric name, original data review PR link, description (if its unclear from the name)
2. Figure out the owner for each of the metrics (who needs to give the OK to renew/remove)
a. Most renewals will need product approval
b. Other approvals could come from the engineering team (e.g. `preferences.remote_debugging_enabled`), GV, App Services, Performance (e.g. `startup.timeline.framework_primary`), etc.
3. Answer any open questions for the metric owners, and get approval from them to:
a. Renew the metric (for how long? 6 months? 1 year?)
b. Choose not to renew (but not delete)
c. Choose to remove the metric
d. Renew the metric and set to never expire (this should only be for business critical metrics)
4. Fill out the [renewal request](https://github.com/mozilla/data-review/blob/main/renewal_request.md) for each metric, with question 3 (“Why was the initial period of collection insufficient?”) being answered by the owner
5. Open a PR for the renewals
a. Sometimes its easier to split up the renewals into multiple PRs if there are multiple owners: e.g. [product renewals](https://github.com/mozilla-mobile/fenix/pull/21788), [perf renewals](https://github.com/mozilla-mobile/fenix/pull/21315), [Fission renewals](https://github.com/mozilla-mobile/fenix/pull/21779) for December 2021
6. Get a data review for your [renewal request](https://github.com/mozilla/data-review/blob/main/renewal_request.md) and update each of the metrics data-reviews in metrics.yaml to reflect this
## Approval process
For each telemetry probe that we want to renew, the data-review will ask us [these questions](https://github.com/mozilla/data-review/blob/main/renewal_request.md). Each probe/group of related probes should have answers to those questions ([example](https://github.com/mozilla-mobile/fenix/pull/20517#issuecomment-887038794)).
### Example renewal data request
```
# Request for Data Collection Renewal
`search_shortcuts:`
selected
1) Provide a link to the initial Data Collection Review Request for this collection.
- https://github.com/mozilla-mobile/fenix/pull/1202#issuecomment-476870449
- https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068
- https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789
2) When will this collection now expire? 08/01/2022
3) Why was the initial period of collection insufficient?
Important for revenue tracking and optimization.
`Toolbar_settings:`
changed_position:
1) Provide a link to the initial Data Collection Review Request for this collection.
- https://github.com/mozilla-mobile/fenix/pull/6608
- https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068
- https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789
2) When will this collection now expire? 08/01/2022
3) Why was the initial period of collection insufficient?
The data didnt initially tell us what we wanted (there were bugs), so we want to continue tracking this so we can answer our questions.
`login_dialog:`
displayed:
cancelled
saved
never_save
1) Provide a link to the initial Data Collection Review Request for this collection.
- https://github.com/mozilla-mobile/fenix/pull/13050
- https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789
2) When will this collection now expire? 08/01/2022
3) Why was the initial period of collection insufficient?
Still need to optimize this feature and we want trends from 6+mo of data.
```
For product-defined telemetry, this will involve meeting with a product manager and discussing each probe. There are three options: renew the probe for another length of time (usually 6 months), let the probe expire to evaluate later if the probe is still needed, or remove the probe entirely.

@ -0,0 +1,77 @@
Watch a step by step [video](https://user-images.githubusercontent.com/6579541/170517089-7266b93e-7ff8-4ebb-ae01-4f2a7e558c66.mp4)
1. To send data by default. apply this patch:
``` diff
diff --git a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt
index 4cb11de43..0c6fab136 100644
--- a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt
+++ b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt
@@ -293,9 +293,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
}
private fun startMetricsIfEnabled() {
- if (settings().isTelemetryEnabled) {
- components.analytics.metrics.start(MetricServiceType.Data)
- }
+ components.analytics.metrics.start(MetricServiceType.Data)
if (settings().isMarketingTelemetryEnabled) {
components.analytics.metrics.start(MetricServiceType.Marketing)
diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt
index c38ebb62d..3ae102d97 100644
--- a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt
+++ b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt
@@ -50,7 +50,7 @@ interface MetricController {
isMarketingDataTelemetryEnabled: () -> Boolean,
settings: Settings
): MetricController {
- return if (BuildConfig.TELEMETRY) {
+ return if (true) {
ReleaseMetricController(
services,
isDataTelemetryEnabled,
```
2. Trigger your pings.
3. Sends the ping sing this command:
```
adb shell am start -n org.mozilla.fenix.debug/mozilla.telemetry.glean.debug.GleanDebugActivity \
--ez logPings true \
--es sendPing metrics \
--es debugViewTag test-metrics-ping
```
4. See the results on https://debug-ping-preview.firebaseapp.com/
The parameters `sendPing` can be `metrics` or `events` depending or your needs, additionally `debugViewTag` can be customize to your preferred tag `debugViewTag your-metrics-ping`.

@ -0,0 +1,27 @@
## Marking an unused string to be removed
Removing strings manually could cause crashes in **Beta** and **Release** versions 💥 , as the removed strings could be [uplifted to release branches](https://github.com/mozilla-mobile/fenix/pull/20364) by mistake, where strings are still needed. For this reason, we need a special process to remove them.
Any landed string that is not removed while in development in Nightly will persist through 3 Firefox releases (Nightly, Beta, Release) before we can remove them from our code base. For example,
if you want to remove a string that has already shipped prior to **Firefox Nightly 93**, the same string will still be in-use in **Firefox Beta 92** and **Firefox Release 91**. This means the string will be marked as unused and removed in 93 while still riding the train, and it can be removed safely when **Firefox Release 93** no longer ships, for instance, **Firefox Release 94** and beyond.
To keep us safe when you want to remove strings from nightly:
1. Add these attribute to the target strings `moz:removedIn="<<ACTUAL_NIGHTLY_VERSION>>"` and `tools:ignore="UnusedResources"`.
```xml
<string name="onboarding_close" moz:removedIn="93" tools:ignore="UnusedResources">Close</string>
```
Example PR https://github.com/mozilla-mobile/fenix/pull/20980.
## When to remove an unused string and how
Strings that have been tagged with `moz:removedIn` attributes are safe to be removed after the marked version is no longer shipping and no longer in-use or needed.
Consult the [Firefox release calendar](https://wiki.mozilla.org/Release_Management/Calendar). Let's say the Beta cut just happened and we are at Firefox Nightly 109, Firefox Beta 108 and Firefox Release 107. Everything marked with `moz:removedIn` <= 106 can now be removed.
You only need to remove the en-US strings within [values/strings.xml](https://searchfox.org/mozilla-mobile/source/fenix/app/src/main/res/values/strings.xml), and this change will propagate to the other locales.
## Future
It would be nice to add some automatization to delete the strings that have the `moz:removedIn` attributes where a full cycle has happen (3 releases versions from the actual release version).
Loading…
Cancel
Save