Skip to content

Setting up package:unified_analytics within devtools #7084

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 38 commits into from
Feb 13, 2024

Conversation

eliasyishak
Copy link
Contributor

@eliasyishak eliasyishak commented Jan 22, 2024

Part of tracker issue:

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read the Flutter Style Guide recently, and have followed its advice.
  • I signed the CLA.
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or there is a reason for not adding tests.

build.yaml badge

If you need help, consider asking for help on Discord.

Comment on lines 23 to 31
final Analytics analytics = Analytics.development(
tool: DashTool.devtools,
dartVersion: 'TBD',
clientIde: 'TBD',
enabledFeatures: 'feature1-feature2',
flutterChannel: 'TBD',
flutterVersion: 'TBD',
);

Copy link
Contributor Author

@eliasyishak eliasyishak Jan 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swap placeholders out

Copy link
Contributor Author

@eliasyishak eliasyishak Feb 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kenzieschmoll any recommendations for where I should create the Analytics instance? Ideally it can be somewhere it can get imported from or somewhere near the entrypoint so you can direct inject it into where it is needed

Also what's the best way to resolve these parameters?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we get these values from other tools?

Since this code is on the devtools_server where we have access to dart:io, one idea is to run flutter --version and parse the output. We have a class that parses the output from Flutter Tools' registered flutterVersion service here: https://github.com/flutter/devtools/blob/master/packages/devtools_app_shared/lib/src/service/flutter_version.dart/#L16. We could move this class to devtools_shared if it was useful for parsing the output from flutter --version.

A couple things we will need to be careful about:

  • using the flutter that this DevTools server instance is being run from, since a user could have multiple flutter's on their machine / path.
  • ensuring these values can be null when flutter is not on the user's machine (for example if DevTools was being used from a pure Dart user who only writes Dart CLI apps or Dart web apps.

WRT for where to create the Analytics instance, where do we create the Analytics instance for other tools? Near the root of initialization? Some ideas I have:

both of these scenarios would require that the Analytics instance is passed in as a parameter to ServerApi.handle (similar to how extensionsManager and deepLinkManager are passed in): https://github.com/flutter/devtools/blob/master/packages/devtools_shared/lib/src/server/server_api.dart/#L37

It is also worth noting that ServerApi.handle is called from google3 on a separate path, so we'd have to make sure we create the Analytics instance properly there too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using the flutter that this DevTools server instance is being run from, since a user could have multiple flutter's on their machine / path.

Yeah this was the first thing I was concerned about, since devtools also downloads its own separate flutter sdk in /devtools/tool/flutter-sdk, wouldn't running flutter --version --machine return versioning information for flutter that is on the path?

For example, the flutter sdk that is in the devtools directory is version "frameworkVersion": "3.20.0-0.0.pre", while my flutter in path resolves to "frameworkVersion": "3.20.0-2.0.pre.9",... which of these values would we want to report for analytics?

Copy link
Member

@kenzieschmoll kenzieschmoll Feb 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tool/flutter-sdk Fluter isn't used in production. This is just for all of our repository management scripts as well as for the workflows we run on the CI.

We care about the Dart or Flutter SDK from which DevTools was started by the IDE. I believe the IDEs run the dart devtools command to start a DevTools server instance.

Copy link
Member

@kenzieschmoll kenzieschmoll left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had another thought WRT opt-in logic. Since we are going to continue to send events to the old analytics ID and through the new unified_analytics package, should we keep the opt in states separate for those? So old analytics would check out existing logic and new analytics would use the unified_analytics opt in logic? This would mean we'd need different apiGetDevToolsEnabled and apiSetDevToolsEnabled endpoints for both legacy analytics and new analytics.

@eliasyishak
Copy link
Contributor Author

hmm so are you suggesting we would have to perform 2 separate actions if we wanted to opt out of analytics completely as a devtools user? Or is this more of a suggestion to have another case clause in the server_api.dart?

Having to perform 2 separate actions to opt out may confuse some of our users

@eliasyishak eliasyishak marked this pull request as ready for review February 8, 2024 16:47
@eliasyishak eliasyishak requested a review from a team as a code owner February 8, 2024 16:47
@eliasyishak eliasyishak requested review from polina-c and removed request for a team February 8, 2024 16:47
Comment on lines +805 to +806
/// that the consent message has successfully been shown and to allow events
/// to be recorded if the user has decided to remain opted in.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"and to allow...". This part is a little confusing to me. What if the user has selected 'no thanks'? We still need to mark the consent message as shown right? But this makes it sound like this method not only marks the consent message as shown, but also opts in to analytics.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I made the decision to automatically mark the message as shown when we show the text. If the user was previously opted out through other dash tools, then they will remain opted out. If they press the accept button, we will change the their telemetry status to opted in for all dash tools.

But in both cases, marking the message as shown just tells the package to add it to the configuration file and log the date the message was shown

text: 'DevTools reports feature usage statistics and basic '
'crash reports to Google in order to help Google improve '
'the tool over time. See Google\'s ',
text: consentMessageRegExpResults[0],
style: textTheme.titleMedium,
),
TextSpan(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cleanup nit: we can use the helper LinkTextSpan for this. If you do use that helper, the ga properties for Link can be made optional.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, i made the fields Link.gaScreenName and Link.gaSelectedItemDescription nullable. I also added conditionals for where we call ga.select() with those two fields to not send anything if they are null

);
case apiGetDevToolsEnabled:
// Is DevTools Analytics collection enabled?
final isEnabled =
_devToolsUsage.analyticsEnabled && analytics.telemetryEnabled;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when these diverge, should we be setting the value of _devtoolsUsage.analyticsEnabled to analytics.telemetryEnabled?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think once we have fully migrated, we could probably get rid of _devtoolsUsage all together since the package will check itself when an event is attempted to be sent. Example below of how we do it in the flutter-tool by just calling the send method without any wrapping class

https://github.com/flutter/flutter/blob/master/packages/flutter_tools/lib/runner.dart#L190

@eliasyishak eliasyishak merged commit d377718 into flutter:master Feb 13, 2024
@eliasyishak eliasyishak deleted the setup-unified-analytics branch February 13, 2024 21:30
@eliasyishak eliasyishak mentioned this pull request Feb 14, 2024
7 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants