1
0
mirror of https://github.com/dart-lang/sdk synced 2024-07-01 07:14:29 +00:00

[pkg/analysis_server] remove use of package:usage

Change-Id: I3a18670b6131f4e8c445217f1b302e64a74f591c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/365489
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Devon Carew <devoncarew@google.com>
This commit is contained in:
Devon Carew 2024-05-07 22:11:29 +00:00 committed by Commit Queue
parent 8c85df6e6b
commit 8d6ad53c7e
33 changed files with 58 additions and 505 deletions

View File

@ -110,7 +110,7 @@ a:focus, a:hover {
<body>
<h1>Analysis Server API Specification</h1>
<h1 style="color:#999999">Version
1.37.0
1.38.0
</h1>
<p>
This document contains a specification of the API provided by the
@ -245,6 +245,11 @@ a:focus, a:hover {
ignoring the item or treating it with some default/fallback handling.
</p>
<h3>Changelog</h3>
<h4>1.38.0</h4>
<ul>
<li>Deprecated the <tt>analytics.enable</tt> request.</li>
<li>Deprecated the <tt>analytics.isEnabled</tt> request.</li>
</ul>
<h4>1.37.0</h4>
<ul>
<li><tt>SourceEdit</tt> now has an optional human-readable <tt>description</tt> that

View File

@ -6,7 +6,7 @@
// To regenerate the file, use the script
// "pkg/analysis_server/tool/spec/generate_files".
const String PROTOCOL_VERSION = '1.37.0';
const String PROTOCOL_VERSION = '1.38.0';
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';

View File

@ -17,8 +17,6 @@ class AnalysisReanalyzeHandler extends LegacyHandler {
@override
Future<void> handle() async {
unawaited(server.options.analytics?.sendEvent('analysis', 'reanalyze'));
// Send the response before starting any work so that analysis results and
// status events will only arrive after the response.
sendResult(AnalysisReanalyzeResult());

View File

@ -21,11 +21,6 @@ class AnalysisSetAnalysisRootsHandler extends LegacyHandler {
var includedPathList = params.included;
var excludedPathList = params.excluded;
unawaited(server.options.analytics?.sendEvent(
'analysis',
'setAnalysisRoots',
value: includedPathList.length,
));
server.analyticsManager.startedSetAnalysisRoots(params);
// validate

View File

@ -16,11 +16,6 @@ class AnalyticsEnableHandler extends LegacyHandler {
@override
Future<void> handle() async {
var params = AnalyticsEnableParams.fromRequest(request);
var analytics = server.options.analytics;
if (analytics != null) {
analytics.enabled = params.value;
}
sendResult(AnalyticsEnableResult());
}
}

View File

@ -16,7 +16,6 @@ class AnalyticsIsEnabledHandler extends LegacyHandler {
@override
Future<void> handle() async {
sendResult(
AnalyticsIsEnabledResult(server.options.analytics?.enabled ?? false));
sendResult(AnalyticsIsEnabledResult(false));
}
}

View File

@ -14,18 +14,8 @@ class AnalyticsSendEventHandler extends LegacyHandler {
AnalyticsSendEventHandler(
super.server, super.request, super.cancellationToken, super.performance);
String get _clientId => server.options.clientId ?? 'client';
@override
Future<void> handle() async {
var analytics = server.options.analytics;
if (analytics == null) {
sendResult(AnalyticsSendEventResult());
return;
}
var params = AnalyticsSendEventParams.fromRequest(request);
unawaited(analytics.sendEvent(_clientId, params.action));
sendResult(AnalyticsSendEventResult());
}
}

View File

@ -14,19 +14,8 @@ class AnalyticsSendTimingHandler extends LegacyHandler {
AnalyticsSendTimingHandler(
super.server, super.request, super.cancellationToken, super.performance);
String get _clientId => server.options.clientId ?? 'client';
@override
Future<void> handle() async {
var analytics = server.options.analytics;
if (analytics == null) {
sendResult(AnalyticsSendTimingResult());
return;
}
var params = AnalyticsSendTimingParams.fromRequest(request);
unawaited(
analytics.sendTiming(params.event, params.millis, category: _clientId));
sendResult(AnalyticsSendTimingResult());
}
}

View File

@ -21,11 +21,9 @@ class EditFormatHandler extends LegacyHandler {
@override
Future<void> handle() async {
unawaited(server.options.analytics?.sendEvent('edit', 'format'));
var params = EditFormatParams.fromRequest(request);
var file = params.file;
//
String unformattedCode;
try {
var resource = server.resourceProvider.getFile(file);

View File

@ -18,11 +18,6 @@ class EditGetPostfixCompletionHandler extends LegacyHandler {
@override
Future<void> handle() async {
unawaited(server.options.analytics?.sendEvent(
'edit',
'getPostfixCompletion',
));
var params = EditGetPostfixCompletionParams.fromRequest(request);
var file = params.file;

View File

@ -20,12 +20,6 @@ class EditOrganizeDirectivesHandler extends LegacyHandler {
@override
Future<void> handle() async {
// TODO(brianwilkerson): Move analytics tracking out of [handleRequest].
unawaited(server.options.analytics?.sendEvent(
'edit',
'organizeDirectives',
));
var params = EditOrganizeDirectivesParams.fromRequest(request);
var file = params.file;

View File

@ -113,7 +113,6 @@ import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
import 'package:http/http.dart' as http;
import 'package:meta/meta.dart';
import 'package:telemetry/crash_reporting.dart';
import 'package:telemetry/telemetry.dart' as telemetry;
import 'package:watcher/watcher.dart';
/// A function that can be executed to create a handler for a request.
@ -136,10 +135,6 @@ class AnalysisServerOptions {
/// If `null`, then the default discovery mechanism is used.
String? packagesFile;
/// The analytics instance; note, this object can be `null`, and should be
/// accessed via a null-aware operator.
telemetry.Analytics? analytics;
/// The crash report sender instance; note, this object can be `null`, and
/// should be accessed via a null-aware operator.
CrashReportSender? crashReportSender;
@ -876,17 +871,6 @@ class LegacyAnalysisServer extends AnalysisServer {
pubApi.close();
// TODO(brianwilkerson): Remove the following 6 lines when the
// analyticsManager is being correctly initialized.
var analytics = options.analytics;
if (analytics != null) {
unawaited(analytics
.waitForLastPing(timeout: Duration(milliseconds: 200))
.then((_) {
analytics.close();
}));
}
detachableFileSystemManager?.dispose();
// Defer closing the channel and shutting down the instrumentation server so

View File

@ -38,7 +38,6 @@ import 'package:analyzer/src/util/sdk.dart';
import 'package:args/args.dart';
import 'package:linter/src/rules.dart' as linter;
import 'package:telemetry/crash_reporting.dart';
import 'package:telemetry/telemetry.dart' as telemetry;
import 'package:unified_analytics/unified_analytics.dart';
import '../utilities/usage_tracking/usage_tracking.dart';
@ -197,23 +196,6 @@ class Driver implements ServerStarter {
disableAnalyticsForSession = true;
}
// Use sdkConfig to optionally override legacy analytics settings.
var analyticsId = sdkConfig.analyticsId ?? 'UA-26406144-29';
var forceAnalyticsEnabled = sdkConfig.analyticsForceEnabled == true;
var analytics = telemetry.createAnalyticsInstance(
analyticsId,
'analysis-server',
disableForSession: disableAnalyticsForSession,
forceEnabled: forceAnalyticsEnabled,
);
analysisServerOptions.analytics = analytics;
// Record the client name as the application installer ID.
analytics.setSessionValue('aiid', analysisServerOptions.clientId);
if (analysisServerOptions.clientVersion != null) {
analytics.setSessionValue('cd1', analysisServerOptions.clientVersion);
}
var defaultSdkPath = _getSdkPath(results);
var dartSdkManager = DartSdkManager(defaultSdkPath);
@ -255,14 +237,6 @@ class Driver implements ServerStarter {
var crashReportSender =
CrashReportSender.prod(crashProductId, shouldSendCallback);
if (telemetry.showAnalyticsUI) {
if (results.wasParsed(ANALYTICS_FLAG)) {
analytics.enabled = results[ANALYTICS_FLAG] as bool;
print(telemetry.createAnalyticsStatusMessage(analytics.enabled));
return;
}
}
{
var disableCompletion =
results[DISABLE_SERVER_FEATURE_COMPLETION] as bool;
@ -276,7 +250,7 @@ class Driver implements ServerStarter {
}
if (results[HELP_OPTION] as bool) {
_printUsage(parser, analytics, fromHelp: true);
_printUsage(parser, fromHelp: true);
return;
}
@ -328,7 +302,7 @@ class Driver implements ServerStarter {
} on FormatException {
print('Invalid port number: $portValue');
print('');
_printUsage(parser, analytics);
_printUsage(parser);
exitCode = 1;
return;
}
@ -360,7 +334,6 @@ class Driver implements ServerStarter {
crashReportingAttachmentsBuilder,
instrumentationService,
RequestStatisticsHelper(),
analytics,
diagnosticServerPort,
errorNotifier,
sendPort);
@ -381,7 +354,6 @@ class Driver implements ServerStarter {
CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder,
InstrumentationService instrumentationService,
RequestStatisticsHelper requestStatistics,
telemetry.Analytics analytics,
int? diagnosticServerPort,
ErrorNotifier errorNotifier,
SendPort? sendPort,
@ -402,9 +374,6 @@ class Driver implements ServerStarter {
var diagnosticServer = _DiagnosticServerImpl();
// Ping analytics with our initial call.
analytics.sendScreenView('home');
//
// Create the sockets and start listening for requests.
//
@ -671,24 +640,13 @@ class Driver implements ServerStarter {
/// Print information about how to use the server.
void _printUsage(
ArgParser parser,
telemetry.Analytics analytics, {
ArgParser parser, {
bool fromHelp = false,
}) {
print('Usage: $BINARY_NAME [flags]');
print('');
print('Supported flags are:');
print(parser.usage);
if (telemetry.showAnalyticsUI) {
// Print analytics status and information.
if (fromHelp) {
print('');
print(telemetry.analyticsNotice);
}
print('');
print(telemetry.createAnalyticsStatusMessage(analytics.enabled));
}
}
/// Read the UUID from disk, generating and storing a new one if necessary.
@ -803,7 +761,7 @@ class Driver implements ServerStarter {
parser.addFlag(ANALYTICS_FLAG,
help: 'Allow or disallow sending analytics information to '
'Google for this session.',
hide: !telemetry.showAnalyticsUI);
hide: true);
parser.addFlag(SUPPRESS_ANALYTICS_FLAG,
negatable: false,
help: 'Suppress analytics for this session.',

View File

@ -39,14 +39,6 @@ class SdkConfiguration {
}
}
/// Whether analytics is forced on.
bool? get analyticsForceEnabled =>
_values['server.analytics.forceEnabled'] as bool?;
/// Return an override value for the analysis server's google analytics ID, or
/// `null` if the default value should be used.
String? get analyticsId => _values['server.analytics.id'] as String?;
/// Whether crash reporting is forced on.
bool? get crashReportingForceEnabled =>
_values['server.crash.reporting.forceEnabled'] as bool?;

View File

@ -105,9 +105,6 @@ class RefactoringManager {
return;
}
server.options.analytics
?.sendEvent('refactor', params.kind.name.toLowerCase());
runZonedGuarded(() async {
await _init(
params.kind, file, params.offset, params.length, cancellationToken);

View File

@ -148,8 +148,6 @@ dependency_overrides:
path: ../../third_party/pkg/typed_data
unified_analytics:
path: ../../third_party/pkg/tools/pkgs/unified_analytics
usage:
path: ../../third_party/pkg/usage
vm_service:
path: ../vm_service
watcher:

View File

@ -1,33 +0,0 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../support/integration_tests.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(EnableTest);
});
}
@reflectiveTest
class EnableTest extends AbstractAnalysisServerIntegrationTest {
Future<void> test_call_enable() async {
await standardAnalysisSetup();
// Toggle the value twice; do light verification of the changes, as the
// analysis server - when running on our CI bots - deliberately does not
// send analytics info.
var result1 = await sendAnalyticsIsEnabled();
expect(result1.enabled, isNotNull);
await sendAnalyticsEnable(!result1.enabled);
var result2 = await sendAnalyticsIsEnabled();
expect(result2.enabled, isNotNull);
await sendAnalyticsEnable(result1.enabled);
}
}

View File

@ -1,25 +0,0 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../support/integration_tests.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(IsEnabledTest);
});
}
@reflectiveTest
class IsEnabledTest extends AbstractAnalysisServerIntegrationTest {
Future<void> test_isEnabled() async {
await standardAnalysisSetup();
var result = await sendAnalyticsIsEnabled();
// Very lightweight validation of the returned data.
expect(result, isNotNull);
}
}

View File

@ -1,30 +0,0 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../support/integration_tests.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(SendEventTest);
});
}
@reflectiveTest
class SendEventTest extends AbstractAnalysisServerIntegrationTest {
Future<void> test_send_event() async {
await standardAnalysisSetup();
// Disable analytics.
var result1 = await sendAnalyticsIsEnabled();
await sendAnalyticsEnable(false);
// Send an event.
await sendAnalyticsSendEvent('test-action');
// Restore the original value.
await sendAnalyticsEnable(result1.enabled);
}
}

View File

@ -1,30 +0,0 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../support/integration_tests.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(SendTimingTest);
});
}
@reflectiveTest
class SendTimingTest extends AbstractAnalysisServerIntegrationTest {
Future<void> test_send_timing() async {
await standardAnalysisSetup();
// Disable analytics.
var result1 = await sendAnalyticsIsEnabled();
await sendAnalyticsEnable(false);
// Send an event.
await sendAnalyticsSendTiming('test-action', 100);
// Restore the original value.
await sendAnalyticsEnable(result1.enabled);
}
}

View File

@ -1,19 +0,0 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'enable_test.dart' as enable_test;
import 'is_enabled_test.dart' as is_enabled_test;
import 'send_event_test.dart' as send_event_test;
import 'send_timing_test.dart' as send_timing_test;
void main() {
defineReflectiveSuite(() {
enable_test.main();
is_enabled_test.main();
send_event_test.main();
send_timing_test.main();
}, name: 'analytics');
}

View File

@ -91,10 +91,10 @@ server calls. This file is validated by `coverage_test.dart`.
- [ ] server.showMessageRequest
## analytics domain
- [x] analytics.isEnabled
- [x] analytics.enable
- [x] analytics.sendEvent
- [x] analytics.sendTiming
- [ ] analytics.isEnabled
- [ ] analytics.enable
- [ ] analytics.sendEvent
- [ ] analytics.sendTiming
## flutter domain
- [ ] flutter.getChangeAddForDesignTimeConstructor

View File

@ -2329,6 +2329,8 @@ abstract class IntegrationTest {
return DiagnosticGetServerPortResult.fromJson(decoder, 'result', result);
}
/// Deprecated: this flag is no longer supported.
///
/// Query whether analytics is enabled.
///
/// This flag controls whether the analysis server sends any analytics data
@ -2349,12 +2351,17 @@ abstract class IntegrationTest {
/// enabled: bool
///
/// Whether sending analytics is enabled or not.
// TODO(srawlins): Provide a deprecation message, or remove.
// ignore: provide_deprecation_message
@deprecated
Future<AnalyticsIsEnabledResult> sendAnalyticsIsEnabled() async {
var result = await server.send('analytics.isEnabled', null);
var decoder = ResponseDecoder(null);
return AnalyticsIsEnabledResult.fromJson(decoder, 'result', result);
}
/// Deprecated: this option is no longer supported.
///
/// Enable or disable the sending of analytics data. Note that there are
/// other ways for users to change this setting, so clients cannot assume
/// that they have complete control over this setting. In particular, there
@ -2366,6 +2373,9 @@ abstract class IntegrationTest {
/// value: bool
///
/// Enable or disable analytics.
// TODO(srawlins): Provide a deprecation message, or remove.
// ignore: provide_deprecation_message
@deprecated
Future<void> sendAnalyticsEnable(bool value) async {
var params = AnalyticsEnableParams(value).toJson();
var result = await server.send('analytics.enable', params);

View File

@ -5,7 +5,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'analysis/test_all.dart' as analysis;
import 'analytics/test_all.dart' as analytics;
import 'completion/test_all.dart' as completion;
import 'coverage_test.dart' as coverage_test;
import 'diagnostic/test_all.dart' as diagnostic;
@ -20,7 +19,6 @@ import 'server/test_all.dart' as server;
void main() {
defineReflectiveSuite(() {
analysis.main();
analytics.main();
completion.main();
coverage_test.main();
diagnostic.main();

View File

@ -43,8 +43,6 @@ void main() {
var config = SdkConfiguration.readFromFile(file);
expect(config.hasAnyOverrides, isFalse);
expect(config.analyticsId, isNull);
expect(config.analyticsForceEnabled, isNull);
expect(config.crashReportingId, isNull);
expect(config.crashReportingForceEnabled, isNull);
});
@ -65,8 +63,6 @@ void main() {
var config = SdkConfiguration.readFromFile(file);
expect(config.hasAnyOverrides, isTrue);
expect(config.analyticsId, 'aaaa-1234');
expect(config.analyticsForceEnabled, isTrue);
expect(config.crashReportingId, 'Test_crash_id');
expect(config.crashReportingForceEnabled, isTrue);
});

View File

@ -322,18 +322,24 @@ public interface AnalysisServer {
/**
* {@code analytics.enable}
*
* Deprecated: this option is no longer supported.
*
* Enable or disable the sending of analytics data. Note that there are other ways for users to
* change this setting, so clients cannot assume that they have complete control over this setting.
* In particular, there is no guarantee that the result returned by the isEnabled request will
* match the last value set via this request.
*
* @param value Enable or disable analytics.
*
* @deprecated
*/
public void analytics_enable(boolean value);
/**
* {@code analytics.isEnabled}
*
* Deprecated: this flag is no longer supported.
*
* Query whether analytics is enabled.
*
* This flag controls whether the analysis server sends any analytics data to the cloud. If
@ -345,6 +351,8 @@ public interface AnalysisServer {
* the value returned to decide whether or not to send the sendEvent and sendTiming requests. Those
* requests should be used unconditionally and server will determine whether or not it is
* appropriate to forward the information to the cloud at the time each request is received.
*
* @deprecated
*/
public void analytics_isEnabled(IsEnabledConsumer consumer);

View File

@ -7,7 +7,7 @@
<body>
<h1>Analysis Server API Specification</h1>
<h1 style="color:#999999">Version
<version>1.37.0</version>
<version>1.38.0</version>
</h1>
<p>
This document contains a specification of the API provided by the
@ -142,6 +142,11 @@
ignoring the item or treating it with some default/fallback handling.
</p>
<h3>Changelog</h3>
<h4>1.38.0</h4>
<ul>
<li>Deprecated the <tt>analytics.enable</tt> request.</li>
<li>Deprecated the <tt>analytics.isEnabled</tt> request.</li>
</ul>
<h4>1.37.0</h4>
<ul>
<li><tt>SourceEdit</tt> now has an optional human-readable <tt>description</tt> that
@ -3154,7 +3159,8 @@
operations performed, operating system type, SDK version). No data (from the
analysis server or from clients) will be sent if analytics is disabled.
</p>
<request method="isEnabled">
<request method="isEnabled" deprecated="true">
<p><b>Deprecated:</b> this flag is no longer supported.</p>
<p>Query whether analytics is enabled.</p>
<p>
This flag controls whether the analysis server sends any analytics data to
@ -3179,7 +3185,8 @@
</field>
</result>
</request>
<request method="enable">
<request method="enable" deprecated="true">
<p><b>Deprecated:</b> this option is no longer supported.</p>
<p>
Enable or disable the sending of analytics data. Note that there are other
ways for users to change this setting, so clients cannot assume that they

View File

@ -6,7 +6,7 @@
// To regenerate the file, use the script
// "pkg/analysis_server/tool/spec/generate_files".
const String PROTOCOL_VERSION = '1.37.0';
const String PROTOCOL_VERSION = '1.38.0';
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';

View File

@ -1,32 +1,6 @@
# telemetry
A library to facilitate reporting analytics and crash reports.
## Analytics
This library is designed to allow all Dart SDK tools to easily send analytics
information and crash reports. The tools share a common setting to configure
sending analytics data. To use this library for a specific tool:
```
import 'package:telemetry/telemetry.dart';
import 'package:usage/usage.dart';
main() async {
final String myAppTrackingID = ...;
final String myAppName = ...;
Analytics analytics = createAnalyticsInstance(myAppTrackingID, myAppName);
...
analytics.sendScreenView('home');
...
await analytics.waitForLastPing();
}
```
The analytics object reads from the correct user configuration file
automatically without any additional configuration. Analytics will not be sent
if the user has opted-out.
A library to facilitate reporting crash reports.
## Crash reporting
@ -36,9 +10,10 @@ create a new `CrashReportSender` instance:
```dart
import 'package:telemetry/crash_reporting.dart';
main() {
void main() {
Analytics analytics = ...;
CrashReportSender sender = new CrashReportSender(analytics);
CrashReportSender sender = new CrashReportSender.prod(...);
try {
...
} catch (e, st) {
@ -46,6 +21,3 @@ main() {
}
}
```
Crash reports will only be sent if the corresponding [Analytics] object is
configured to send analytics.

View File

@ -4,162 +4,6 @@
import 'dart:io';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
// ignore: implementation_imports
import 'package:usage/src/usage_impl.dart';
// ignore: implementation_imports
import 'package:usage/src/usage_impl_io.dart';
// ignore: implementation_imports
import 'package:usage/src/usage_impl_io.dart' as usage_io show getDartVersion;
import 'package:usage/usage.dart';
import 'package:usage/usage_io.dart';
export 'package:usage/usage.dart' show Analytics;
// TODO(devoncarew): Don't show the UI until we're ready to ship.
final bool showAnalyticsUI = false;
final String _dartDirectoryName = '.dart';
final String _settingsFileName = 'analytics.json';
/// Dart SDK tools with analytics should display this notice.
///
/// In addition, they should support displaying the analytics' status, and have
/// a flag to toggle analytics. This may look something like:
///
/// `Analytics are currently enabled (and can be disabled with --no-analytics).`
final String analyticsNotice =
"Dart SDK tools anonymously report feature usage statistics and basic crash\n"
"reports to help improve Dart tools over time. See Google's privacy policy:\n"
"https://www.google.com/intl/en/policies/privacy/.";
/// Return a customized message for command-line tools to display about the
/// state of analytics, and how users can enabled or disable analytics.
///
/// An example return value might be `'Analytics are currently enabled (and can
/// be disabled with --no-analytics).'`
String createAnalyticsStatusMessage(
bool enabled, {
String command = 'analytics',
}) {
String currentState = enabled ? 'enabled' : 'disabled';
String toggleState = enabled ? 'disabled' : 'enabled';
String commandToggle = enabled ? 'no-$command' : command;
return 'Analytics are currently $currentState '
'(and can be $toggleState with --$commandToggle).';
}
/// Create an [Analytics] instance with the given trackingID and
/// applicationName.
///
/// This analytics instance will share a common enablement state with the rest
/// of the Dart SDK tools.
Analytics createAnalyticsInstance(
String trackingId,
String applicationName, {
bool disableForSession = false,
bool forceEnabled = false,
}) {
final dir = getDartStorageDirectory();
if (dir == null) {
// Some systems don't support user home directories; for those, fail
// gracefully by returning a disabled analytics object.
return _DisabledAnalytics(trackingId, applicationName);
}
if (!dir.existsSync()) {
try {
dir.createSync();
} catch (e) {
// If we can't create the directory for the analytics settings, fail
// gracefully by returning a disabled analytics object.
return _DisabledAnalytics(trackingId, applicationName);
}
}
File settingsFile = File(path.join(dir.path, _settingsFileName));
return _TelemetryAnalytics(
trackingId,
applicationName,
getDartVersion(),
settingsFile,
disableForSession: disableForSession,
forceEnabled: forceEnabled,
);
}
/// The directory used to store the analytics settings file.
///
/// Typically, the directory is `~/.dart/` (and the settings file is
/// `analytics.json`).
///
/// This can return null under some conditions, including when the user's home
/// directory does not exist.
@visibleForTesting
Directory? getDartStorageDirectory() {
Directory homeDirectory = Directory(userHomeDir());
if (!homeDirectory.existsSync()) return null;
return Directory(path.join(homeDirectory.path, _dartDirectoryName));
}
/// Return the version of the Dart SDK.
String getDartVersion() => usage_io.getDartVersion();
class _TelemetryAnalytics extends AnalyticsImpl {
final bool disableForSession;
final bool forceEnabled;
_TelemetryAnalytics(
String trackingId,
String applicationName,
String applicationVersion,
File settingsFile, {
required this.disableForSession,
required this.forceEnabled,
}) : super(
trackingId,
IOPersistentProperties.fromFile(settingsFile),
IOPostHandler(),
applicationName: applicationName,
applicationVersion: applicationVersion,
) {
final locale = getPlatformLocale();
if (locale != null) {
setSessionValue('ul', locale);
}
}
@override
bool get enabled {
if (disableForSession || isRunningOnBot()) {
return false;
}
// This is only used in special cases.
if (forceEnabled) {
return true;
}
// If there's no explicit setting (enabled or disabled) then we don't send.
return (properties['enabled'] as bool?) ?? false;
}
}
class _DisabledAnalytics extends AnalyticsMock {
@override
final String trackingId;
@override
final String applicationName;
_DisabledAnalytics(this.trackingId, this.applicationName);
@override
bool get enabled => false;
}
/// Detect whether we're running on a bot or in a continuous testing
/// environment.
///

View File

@ -10,9 +10,7 @@ environment:
dependencies:
http: any
meta: any
path: any
stack_trace: any
usage: any
# Use 'any' constraints here; we get our versions from the DEPS file.
dev_dependencies:

View File

@ -8,12 +8,12 @@ import 'package:http/http.dart';
import 'package:http/testing.dart';
import 'package:telemetry/crash_reporting.dart';
import 'package:test/test.dart';
import 'package:usage/usage.dart';
const String mockTrackingId = 'UA-0';
void main() {
group('CrashReportSender', () {
late MockClient mockClient;
late AnalyticsMock analytics;
late Request request;
@ -22,8 +22,6 @@ void main() {
request = r;
return Response('crash-report-001', 200);
});
analytics = AnalyticsMock()..enabled = true;
});
EnablementCallback shouldSend;
@ -33,7 +31,7 @@ void main() {
test('general', () async {
CrashReportSender sender = CrashReportSender.prod(
analytics.trackingId, shouldSend,
mockTrackingId, shouldSend,
httpClient: mockClient);
await sender.sendReport('test-error', StackTrace.current);
@ -45,7 +43,7 @@ void main() {
test('hits pii filters', () async {
CrashReportSender sender = CrashReportSender.prod(
analytics.trackingId, shouldSend,
mockTrackingId, shouldSend,
httpClient: mockClient);
await sender.sendReport('filter this: filename.exe', StackTrace.current);
@ -57,7 +55,7 @@ void main() {
test('reportsSent', () async {
CrashReportSender sender = CrashReportSender.prod(
analytics.trackingId, shouldSend,
mockTrackingId, shouldSend,
httpClient: mockClient);
expect(sender.reportsSent, 0);
@ -73,7 +71,7 @@ void main() {
test('contains message', () async {
CrashReportSender sender = CrashReportSender.prod(
analytics.trackingId, shouldSend,
mockTrackingId, shouldSend,
httpClient: mockClient);
await sender.sendReport('test-error', StackTrace.current,
@ -87,7 +85,7 @@ void main() {
test('has attachments', () async {
CrashReportSender sender = CrashReportSender.prod(
analytics.trackingId, shouldSend,
mockTrackingId, shouldSend,
httpClient: mockClient);
await sender.sendReport(
@ -108,7 +106,7 @@ void main() {
test('has ptime', () async {
CrashReportSender sender = CrashReportSender.prod(
analytics.trackingId, shouldSend,
mockTrackingId, shouldSend,
httpClient: mockClient);
await sender.sendReport('test-error', StackTrace.current);

View File

@ -1,28 +0,0 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:telemetry/telemetry.dart';
import 'package:test/test.dart';
void main() {
group('telemetry', () {
test('getDartStorageDirectory', () {
var dir = getDartStorageDirectory();
expect(dir, isNotNull);
});
test('getDartVersion', () {
expect(getDartVersion(), isNotNull);
});
test('createAnalyticsInstance', () {
Analytics analytics = createAnalyticsInstance('UA-0', 'test-app');
expect(analytics, isNotNull);
expect(analytics.trackingId, 'UA-0');
expect(analytics.getSessionValue('an'), 'test-app');
expect(analytics.getSessionValue('av'), isNotNull);
expect(analytics.clientId, isNotNull);
});
});
}