for #12573, added telemetry for startup type #13494
Conversation
Tested scenariosApp starting fresh
App is already launched
|
Codecov Report
@@ Coverage Diff @@
## master #13494 +/- ##
============================================
+ Coverage 29.65% 29.72% +0.07%
- Complexity 1147 1159 +12
============================================
Files 440 440
Lines 17792 17824 +32
Branches 2309 2315 +6
============================================
+ Hits 5276 5298 +22
- Misses 12132 12140 +8
- Partials 384 386 +2
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks good for what it's doing but I still have to test it. However, I feel like we should be merging this with the app_link, custom_tab, etc. data as it helps guarantee we're not getting wonky numbers (e.g. one probe reports more invocations than another probe). What do you think?
I wrote all of these comments (mostly nits) before I thought of ^ so try to reinterpret them in that lens and, if we do merge the probes, maybe avoid tackling them until we get there.
app/src/main/java/org/mozilla/fenix/components/metrics/AppStartupTypeTelemetry.kt
Outdated
Show resolved
Hide resolved
app/src/test/java/org/mozilla/fenix/components/metrics/AppStartupTypeTelemetryTest.kt
Outdated
Show resolved
Hide resolved
app/src/test/java/org/mozilla/fenix/components/metrics/AppStartupTypeTelemetryTest.kt
Outdated
Show resolved
Hide resolved
app/src/test/java/org/mozilla/fenix/components/metrics/AppStartupTypeTelemetryTest.kt
Outdated
Show resolved
Hide resolved
app/src/test/java/org/mozilla/fenix/components/metrics/AppStartupTypeTelemetryTest.kt
Outdated
Show resolved
Hide resolved
app/src/test/java/org/mozilla/fenix/components/metrics/AppStartupTypeTelemetryTest.kt
Outdated
Show resolved
Hide resolved
5f60e64
to
b9f8d60
Compare
@mcomella I made all the changes to merge together the two metrics (app startup source and type). Let me know if this is what you were looking for? If not I can revert back to the previous commit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks like it'll work but I think it's hard to say given the current formulation – I'm wondering if we can make it clearer, especially the onRestart
flow. Let's see what you can come up with (timebox it?) and if not feasible or it's not a good use of time, I can re-review this with nits and maybe land it as is.
app/src/main/java/org/mozilla/fenix/components/metrics/AppAllSourceStartTelemetry.kt
Show resolved
Hide resolved
app/src/test/java/org/mozilla/fenix/components/metrics/AppStartupTelemetryTest.kt
Show resolved
Hide resolved
app/src/test/java/org/mozilla/fenix/components/metrics/AppStartupTelemetryTest.kt
Outdated
Show resolved
Hide resolved
app/src/test/java/org/mozilla/fenix/components/metrics/AppStartupTelemetryTest.kt
Outdated
Show resolved
Hide resolved
app/src/test/java/org/mozilla/fenix/components/metrics/AppStartupTelemetryTest.kt
Outdated
Show resolved
Hide resolved
app/src/test/java/org/mozilla/fenix/components/metrics/AppStartupTelemetryTest.kt
Outdated
Show resolved
Hide resolved
app/src/test/java/org/mozilla/fenix/components/metrics/AppStartupTelemetryTest.kt
Outdated
Show resolved
Hide resolved
265f47e
to
6350053
Compare
6350053
to
fa8836e
Compare
app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/org/mozilla/fenix/components/metrics/AppStartupTelemetry.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/org/mozilla/fenix/components/metrics/AppStartupTelemetry.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/org/mozilla/fenix/components/metrics/AppStartupTelemetry.kt
Outdated
Show resolved
Hide resolved
fa8836e
to
fcaccd6
Compare
Request for data collection review formAll questions are mandatory. You must receive a review from a data steward peer on your responses to these questions before shipping new data collection. 1. What questions will you answer with this data? What type of startup user uses most? For example, cold, warm, hot. What type of startup source users uses most? For example, app_icon, link, custom_tab 2. Why does Mozilla need to answer these questions? Are there benefits for users? Do we need this information to address product or business requirements? Some example responses: Creating an accurate understanding of real-world usage to prioritize performance improvements 3. What alternative methods did you consider to answer these questions? Why were they not sufficient? There is no existing metrics that answer this question. 4. Can current instrumentation answer these questions? No, we are modifying the existing probe to add additional startup data. 5. List all proposed measurements and indicate the category of data collection for each measurement, using the Firefox data collection categories found on the Mozilla wiki. data is Interaction data. What type of startup user use most. Options
6. Please provide a link to the documentation for this data collection which describes the ultimate data set in a public, complete, and accurate way. This is documented in the metrics.md file 7. How long will this data be collected? Until 2021-02-01 8. What populations will you measure? All release, beta, and nightly users with telemetry enabled. 9. If this data collection is default on, what is the opt-out mechanism for users? default on, opt out by Settings ->Data collection 10. Please provide a general description of how you will analyze this data. we can set up better tests and prioritize analyses to improve performance in the most impactful areas. 11. Where do you intend to share the results of your analysis? Glean, Amplitude, and mobile teams. 12. Is there a third-party tool (i.e. not Telemetry) that you are proposing to use for this data collection? If so: N/A |
82a02ea
to
2decee4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks functional but I still think we can clean this up a bit more (sorry for all the nits). Also, I think we should restore the UNKNOWN case or similar.
app/src/main/java/org/mozilla/fenix/components/metrics/AppStartupTelemetry.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/org/mozilla/fenix/components/metrics/AppStartupTelemetry.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/org/mozilla/fenix/components/metrics/AppStartupTelemetry.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/org/mozilla/fenix/components/metrics/AppStartupTelemetry.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/org/mozilla/fenix/components/metrics/AppStartupTelemetry.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/org/mozilla/fenix/components/metrics/AppStartupTelemetry.kt
Outdated
Show resolved
Hide resolved
83ca9bc
to
ce95adf
Compare
Seems like we might never get So whenever I open a specific email on Gmail (maybe it's a Gmail thing), our application seems to start right away (probably because its a default browser). So before even clicking a link to open the custom tab, the application is already started. You might already know this? or maybe it's specific to certain API or apps? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe the error case isn't handled quite right.
app/src/main/java/org/mozilla/fenix/components/metrics/AppStartupTelemetry.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/org/mozilla/fenix/components/metrics/AppStartupTelemetry.kt
Outdated
Show resolved
Hide resolved
* therefore source either gets set in oncreate() or onNewIntent(). | ||
*/ | ||
fun onHomeActivityOnRestart() { | ||
onRestartData = Pair(HOT, false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just noticed: since it's always false
, can't we just omit this extra in the telemetry? (e.g. a nullable field in the metric class that, when null, does not add the extra)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure what you mean by omit extra in telemetry?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of recording [HOT, APP_ICON, false], record [HOT, APP_ICON]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Be sure to document the fact that it's optional
app/src/main/java/org/mozilla/fenix/components/metrics/AppStartupTelemetry.kt
Show resolved
Hide resolved
app/src/main/java/org/mozilla/fenix/components/metrics/AppStartupTelemetry.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/org/mozilla/fenix/components/metrics/AppStartupTelemetry.kt
Outdated
Show resolved
Hide resolved
1c05d73
to
4b2863b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at the metrics.yaml for the data review only here
It looks like this is updating an existing probe with more detail, and adding some more extras
Data Review Form (to be filled by Data Stewards)
- Is there or will there be documentation that describes the schema for the ultimate data set in a public, complete, and accurate way?
Yes, this is updating the app_opened_all_startup
perf telemetry event
- Is there a control mechanism that allows the user to turn the data collection on and off?
Yes, this will also be controlled by the Fenix telemetry settings
- If the request is for permanent data collection, is there someone who will monitor the data over time?
No, there is expiry for this probe
- Using the category system of data types on the Mozilla wiki, what collection type of data do the requested measurements fall under?
Type 2 entry point of startup and whether this is returning to a saved app instance
- Is the data collection request for default-on or default-off?
Default on
- Does the instrumentation include the addition of any new identifiers (whether anonymous or otherwise; e.g., username, random IDs, etc. See the appendix for more details)?
No
-
Is the data collection covered by the existing Firefox privacy notice?
Yes -
Does there need to be a check-in in the future to determine whether to renew the data? (Yes/No)
No -
Does the data collection use a third-party collection tool?
No
app/src/main/java/org/mozilla/fenix/components/metrics/AppStartupTelemetry.kt
Outdated
Show resolved
Hide resolved
* therefore source either gets set in oncreate() or onNewIntent(). | ||
*/ | ||
fun onHomeActivityOnRestart() { | ||
onRestartData = Pair(HOT, false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Be sure to document the fact that it's optional
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initial thoughts: I'll keep looking through the tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests are looking good – it looks like we're capturing all the major cases.
I think the major areas remaining are from the previous comment block:
- simplify
mergeOnRestart...
- Try to omit
savedInstanceState
when it's not relevant (i.e.onCreate
is not called)
app/src/test/java/org/mozilla/fenix/components/metrics/AppStartupTelemetryTest.kt
Outdated
Show resolved
Hide resolved
every { intent.action } returns Intent.ACTION_VIEW | ||
every { intent.categories } returns categories | ||
} | ||
else -> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: You should avoid using else
if possible: e.g. if we add a new case, someone might be less likely to notice they need to update this code. The underlying coding principle: it's frequently better to be explicit.
-> UNKNOWN, CUSTOM_TAB -> {
Also, being explicit makes you ask questions as a developer. For example, the CUSTOM_TAB
intent isn't a MAIN action, right? So that means this setupIntentMock
function isn't accurate for that case and that might cause people issues when adding future tests.
app/src/test/java/org/mozilla/fenix/components/metrics/AppStartupTelemetryTest.kt
Show resolved
Hide resolved
appStartupTelemetry.onHomeActivityOnResume() | ||
|
||
// have to clear the mock function calls so it doesnt interfere with tests | ||
clearMocks(metricController, answers = false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does answers = false do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't really find something official and clear but it's consistent so I went on to use it. basically, it is clearing up calls to metricController.
For example,
metricController.track(something)
clearMocks(metricController, answers = false)
metricController.track(anotherThing)
verify(exactly = 1) { metricController.track(any()) } // this will be true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need answers = false
or does clearMocks(metricController)
work? I would prefer we do the latter if it does and are not sure what the arguments do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need the answers
part. otherwise, we need to re-init the mock every time.
} | ||
|
||
@Test | ||
fun `GIVEN, application exists and is backgrounded, WHEN application is launched again through url link and HomeActivity is recreated THEN records the correct values`() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No action needed
Note: I notice you're writing a test for many combinations: 3 startup types foreground, 3 startup types background, etc.
I probably would have written all these tests 😅 but it probably is a perfect is the enemy of the good situation where it's probably not necessary: doing all the combinations in one type of test and hitting all the other types of tests is probably good enough.
That being said, junit supports a feature called parameterized tests which would make writing all these tests combinations much less code but I haven't ever been able to set it up.
@sraturi btw, there is also a UI test failure now – I assume it's intermittent given what we're changing. |
4b2863b
to
80deae3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, thanks for sticking in there through this lengthy PR!
I tested COLD, WARM, HOT across LINK, CUSTOM_TAB, APP_ICON, and the app switcher case and it appears to be working correctly. I wasn't able to replicate the hasSavedInstanceState
case (maybe Don't Keep Activities?) but the code looks simple enough so I think it should be fine.
It looks like you'll need to rebase though.
} | ||
|
||
@Test | ||
fun `WHEN AppAllStartup does not have savedInstanceState THEN do not return savedInstanceState`() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These AppAllStartup
tests should technically be in the corresponding test file for where AppAllStartup
is defined.
However, let's avoid another back and forth: let's land it as is and if you have time and you're feeling inspired afterwards, you can move it. :) Thanks for writing tests for these cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The events have tons of data classes so would it make sense to create a single Events test file and put all the tests for all the classes there? or make a folder called event, and put all the individual files there?
I think with a single file, before/after
might get confusing? unless we use Junit5? which has nested support.
Note: This metric does not record souce when app opened from | ||
task switcher: open application -> press home button -> open | ||
recent tasks -> choose fenix. In this case will report | ||
[source = unknown, type = hot, has_saved_instance_state = false]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In a follow-up PR (so we can get this landed), can we document two additional things:
- that custom tab never sees COLD start and briefly explain why?
- that if you click "Open in Firefox Preview" from a custom tab, a second event is not recorded
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there are places where custom tab might have a cold start. One case would be me: launch gmail (fenix in background), close fenix from recent tasks, and launch a link from gmail.
422982a
to
18fcdb7
Compare
…s to app_startup_type telemetry
18fcdb7
to
ba73c6e
Compare
Pull Request checklist
After merge
To download an APK when reviewing a PR: