Add analytics package + setTelemetry method attached (#124015)
The first of many PRs for transitioning to `package:unified_analytics`. This PR is only focused on disabling and enabling telemetry via the `flutter config --[no-]analytics` flag Fixes: https://github.com/flutter/flutter/issues/121617 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview [Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [test-exempt]: https://github.com/flutter/flutter/wiki/Tree-hygiene#tests [Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo [Features we expect every widget to implement]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/wiki/Chat --------- Co-authored-by: Christopher Fujino <fujino@google.com> Co-authored-by: Christopher Fujino <christopherfujino@gmail.com>
This commit is contained in:
parent
eca86e8c62
commit
a32f0bb7a0
@ -22,6 +22,7 @@ import 'src/context_runner.dart';
|
||||
import 'src/doctor.dart';
|
||||
import 'src/globals.dart' as globals;
|
||||
import 'src/reporting/crash_reporting.dart';
|
||||
import 'src/reporting/reporting.dart';
|
||||
import 'src/runner/flutter_command.dart';
|
||||
import 'src/runner/flutter_command_runner.dart';
|
||||
|
||||
@ -61,6 +62,44 @@ Future<int> run(
|
||||
StackTrace? firstStackTrace;
|
||||
return runZoned<Future<int>>(() async {
|
||||
try {
|
||||
// Ensure that the consent message has been displayed
|
||||
if (globals.analytics.shouldShowMessage) {
|
||||
globals.logger.printStatus(globals.analytics.getConsentMessage);
|
||||
|
||||
// Invoking this will onboard the flutter tool onto
|
||||
// the package on the developer's machine and will
|
||||
// allow for events to be sent to Google Analytics
|
||||
// on subsequent runs of the flutter tool (ie. no events
|
||||
// will be sent on the first run to allow developers to
|
||||
// opt out of collection)
|
||||
globals.analytics.clientShowedMessage();
|
||||
}
|
||||
|
||||
// Disable analytics if user passes in the `--disable-telemetry` option
|
||||
// `flutter --disable-telemetry`
|
||||
//
|
||||
// Same functionality as `flutter config --no-analytics` for disabling
|
||||
// except with the `value` hard coded as false
|
||||
if (args.contains('--disable-telemetry')) {
|
||||
const bool value = false;
|
||||
// The tool sends the analytics event *before* toggling the flag
|
||||
// intentionally to be sure that opt-out events are sent correctly.
|
||||
AnalyticsConfigEvent(enabled: value).send();
|
||||
if (!value) {
|
||||
// Normally, the tool waits for the analytics to all send before the
|
||||
// tool exits, but only when analytics are enabled. When reporting that
|
||||
// analytics have been disable, the wait must be done here instead.
|
||||
await globals.flutterUsage.ensureAnalyticsSent();
|
||||
}
|
||||
globals.flutterUsage.enabled = value;
|
||||
globals.printStatus('Analytics reporting disabled.');
|
||||
|
||||
// TODO(eliasyishak): Set the telemetry for the unified_analytics
|
||||
// package as well, the above will be removed once we have
|
||||
// fully transitioned to using the new package
|
||||
await globals.analytics.setTelemetry(value);
|
||||
}
|
||||
|
||||
await runner.run(args);
|
||||
|
||||
// Triggering [runZoned]'s error callback does not necessarily mean that
|
||||
|
@ -139,6 +139,11 @@ class ConfigCommand extends FlutterCommand {
|
||||
}
|
||||
globals.flutterUsage.enabled = value;
|
||||
globals.printStatus('Analytics reporting ${value ? 'enabled' : 'disabled'}.');
|
||||
|
||||
// TODO(eliasyishak): Set the telemetry for the unified_analytics
|
||||
// package as well, the above will be removed once we have
|
||||
// fully transitioned to using the new package
|
||||
await globals.analytics.setTelemetry(value);
|
||||
}
|
||||
|
||||
if (argResults?.wasParsed('android-sdk') ?? false) {
|
||||
|
@ -2,7 +2,9 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:intl/date_symbol_data_local.dart';
|
||||
import 'package:process/process.dart';
|
||||
import 'package:unified_analytics/unified_analytics.dart';
|
||||
|
||||
import 'android/android_sdk.dart';
|
||||
import 'android/android_studio.dart';
|
||||
@ -86,6 +88,22 @@ final BotDetector _defaultBotDetector = BotDetector(
|
||||
);
|
||||
Future<bool> get isRunningOnBot => botDetector.isRunningOnBot;
|
||||
|
||||
// Analytics instance for package:unified_analytics for telemetry
|
||||
// reporting for all Flutter and Dart related tooling
|
||||
Analytics get analytics => context.get<Analytics>() ?? getDefaultAnalytics();
|
||||
Analytics getDefaultAnalytics() {
|
||||
|
||||
initializeDateFormatting();
|
||||
final Analytics defaultAnalytics = Analytics(
|
||||
tool: DashTool.flutterTool,
|
||||
flutterChannel: flutterVersion.channel,
|
||||
flutterVersion: flutterVersion.frameworkVersion,
|
||||
dartVersion: flutterVersion.dartSdkVersion,
|
||||
);
|
||||
|
||||
return defaultAnalytics;
|
||||
}
|
||||
|
||||
/// Currently active implementation of the file system.
|
||||
///
|
||||
/// By default it uses local disk-based implementation. Override this in tests
|
||||
|
@ -78,6 +78,9 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||
argParser.addFlag('suppress-analytics',
|
||||
negatable: false,
|
||||
help: 'Suppress analytics reporting when this command runs.');
|
||||
argParser.addFlag('disable-telemetry',
|
||||
negatable: false,
|
||||
help: 'Disable telemetry reporting when this command runs.');
|
||||
argParser.addOption('packages',
|
||||
hide: !verboseHelp,
|
||||
help: 'Path to your "package_config.json" file.');
|
||||
@ -185,6 +188,11 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||
Future<void> runCommand(ArgResults topLevelResults) async {
|
||||
final Map<Type, Object?> contextOverrides = <Type, Object?>{};
|
||||
|
||||
// If the disable-telemetry flag has been passed, return out
|
||||
if (topLevelResults.wasParsed('disable-telemetry')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't set wrapColumns unless the user said to: if it's set, then all
|
||||
// wrapping will occur at this width explicitly, and won't adapt if the
|
||||
// terminal size changes during a run.
|
||||
|
@ -48,6 +48,7 @@ dependencies:
|
||||
http_multi_server: 3.2.1
|
||||
convert: 3.1.1
|
||||
async: 2.11.0
|
||||
unified_analytics: 1.0.1
|
||||
|
||||
# We depend on very specific internal implementation details of the
|
||||
# 'test' package, which change between versions, so when upgrading
|
||||
@ -104,4 +105,4 @@ dartdoc:
|
||||
# Exclude this package from the hosted API docs.
|
||||
nodoc: true
|
||||
|
||||
# PUBSPEC CHECKSUM: 7ab7
|
||||
# PUBSPEC CHECKSUM: 8913
|
||||
|
@ -18,6 +18,8 @@ import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
import 'package:flutter_tools/src/reporting/crash_reporting.dart';
|
||||
import 'package:flutter_tools/src/reporting/reporting.dart';
|
||||
import 'package:flutter_tools/src/runner/flutter_command.dart';
|
||||
import 'package:test/fake.dart';
|
||||
import 'package:unified_analytics/unified_analytics.dart';
|
||||
|
||||
import '../../src/common.dart';
|
||||
import '../../src/context.dart';
|
||||
@ -313,6 +315,29 @@ void main() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
testUsingContext('runner disable telemetry with flag', () async {
|
||||
io.setExitFunctionForTests((int exitCode) {});
|
||||
|
||||
expect(globals.analytics.telemetryEnabled, true);
|
||||
expect(globals.analytics.shouldShowMessage, true);
|
||||
|
||||
await runner.run(
|
||||
<String>['--disable-telemetry'],
|
||||
() => <FlutterCommand>[],
|
||||
// This flutterVersion disables crash reporting.
|
||||
flutterVersion: '[user-branch]/',
|
||||
shutdownHooks: ShutdownHooks(),
|
||||
);
|
||||
|
||||
expect(globals.analytics.telemetryEnabled, false);
|
||||
},
|
||||
overrides: <Type, Generator>{
|
||||
Analytics: () => FakeAnalytics(),
|
||||
FileSystem: () => MemoryFileSystem.test(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
class CrashingFlutterCommand extends FlutterCommand {
|
||||
@ -451,3 +476,30 @@ class WaitingCrashReporter implements CrashReporter {
|
||||
return _future;
|
||||
}
|
||||
}
|
||||
|
||||
/// A fake [Analytics] that will be used to test
|
||||
/// the --disable-telemetry flag
|
||||
class FakeAnalytics extends Fake implements Analytics {
|
||||
bool _fakeTelemetryStatus = true;
|
||||
bool _fakeShowMessage = true;
|
||||
|
||||
@override
|
||||
String get getConsentMessage => 'message';
|
||||
|
||||
@override
|
||||
bool get shouldShowMessage => _fakeShowMessage;
|
||||
|
||||
@override
|
||||
void clientShowedMessage() {
|
||||
_fakeShowMessage = false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setTelemetry(bool reportingBool) {
|
||||
_fakeTelemetryStatus = reportingBool;
|
||||
return Future<void>.value();
|
||||
}
|
||||
|
||||
@override
|
||||
bool get telemetryEnabled => _fakeTelemetryStatus;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user