Skip to content

Commit ba14169

Browse files
authored
Update logic for getting Analytics instance from package:unified_analytics (flutter#134756)
Part of: - flutter#128251 Currently, when we want to use the analytics instance from `package:unified_analytics`, we are just grabbing it from globals. However, with the legacy analytics instance, there are some things we check to return a no-op version of the instance.. for example, if we are running on bots or a non standard branch, we use a no-op instance This PR uses the same previous checks for the new analytics instance
1 parent 57b5c3c commit ba14169

File tree

6 files changed

+201
-8
lines changed

6 files changed

+201
-8
lines changed

packages/flutter_tools/lib/src/context_runner.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import 'persistent_tool_state.dart';
6161
import 'reporting/crash_reporting.dart';
6262
import 'reporting/first_run.dart';
6363
import 'reporting/reporting.dart';
64+
import 'reporting/unified_analytics.dart';
6465
import 'resident_runner.dart';
6566
import 'run_hot.dart';
6667
import 'runner/local_engine.dart';
@@ -88,11 +89,10 @@ Future<T> runInContext<T>(
8889
body: runnerWrapper,
8990
overrides: overrides,
9091
fallbacks: <Type, Generator>{
91-
Analytics: () => Analytics(
92-
tool: DashTool.flutterTool,
93-
flutterChannel: globals.flutterVersion.channel,
94-
flutterVersion: globals.flutterVersion.frameworkVersion,
95-
dartVersion: globals.flutterVersion.dartSdkVersion,
92+
Analytics: () => getAnalytics(
93+
runningOnBot: runningOnBot,
94+
flutterVersion: globals.flutterVersion,
95+
environment: globals.platform.environment,
9696
),
9797
AndroidBuilder: () => AndroidGradleBuilder(
9898
java: globals.java,
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:unified_analytics/unified_analytics.dart';
6+
7+
import '../version.dart';
8+
9+
/// This function is called from within the context runner to perform
10+
/// checks that are necessary for determining if a no-op version of
11+
/// [Analytics] gets returned.
12+
///
13+
/// When [enableAsserts] is set to `true`, various assert statements
14+
/// will be enabled to ensure usage of this class is within GA4 limitations.
15+
///
16+
/// For testing purposes, pass in a [FakeAnalytics] instance initialized with
17+
/// an in-memory [FileSystem] to prevent writing to disk.
18+
Analytics getAnalytics({
19+
required bool runningOnBot,
20+
required FlutterVersion flutterVersion,
21+
required Map<String, String> environment,
22+
bool enableAsserts = false,
23+
FakeAnalytics? analyticsOverride,
24+
}) {
25+
final String version = flutterVersion.getVersionString(redactUnknownBranches: true);
26+
final bool suppressEnvFlag = environment['FLUTTER_SUPPRESS_ANALYTICS']?.toLowerCase() == 'true';
27+
28+
if (// Ignore local user branches.
29+
version.startsWith('[user-branch]') ||
30+
// Many CI systems don't do a full git checkout.
31+
version.endsWith('/unknown') ||
32+
// Ignore bots.
33+
runningOnBot ||
34+
// Ignore when suppressed by FLUTTER_SUPPRESS_ANALYTICS.
35+
suppressEnvFlag) {
36+
return NoOpAnalytics();
37+
}
38+
39+
// Providing an override of the [Analytics] instance is preferred when
40+
// running tests for this function to prevent writing to the filesystem
41+
if (analyticsOverride != null) {
42+
return analyticsOverride;
43+
}
44+
45+
return Analytics(
46+
tool: DashTool.flutterTool,
47+
flutterChannel: flutterVersion.channel,
48+
flutterVersion: flutterVersion.frameworkVersion,
49+
dartVersion: flutterVersion.dartSdkVersion,
50+
enableAsserts: enableAsserts,
51+
);
52+
}

packages/flutter_tools/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ dependencies:
4848
http_multi_server: 3.2.1
4949
convert: 3.1.1
5050
async: 2.11.0
51-
unified_analytics: 4.0.0
51+
unified_analytics: 4.0.1
5252

5353
cli_config: 0.1.1
5454
graphs: 2.3.1
@@ -112,4 +112,4 @@ dartdoc:
112112
# Exclude this package from the hosted API docs.
113113
nodoc: true
114114

115-
# PUBSPEC CHECKSUM: 887b
115+
# PUBSPEC CHECKSUM: 0f7c
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:file/memory.dart';
6+
import 'package:flutter_tools/src/base/file_system.dart';
7+
import 'package:flutter_tools/src/reporting/unified_analytics.dart';
8+
import 'package:unified_analytics/src/enums.dart';
9+
import 'package:unified_analytics/unified_analytics.dart';
10+
11+
import '../src/common.dart';
12+
import '../src/fakes.dart';
13+
14+
void main() {
15+
const String userBranch = 'abc123';
16+
const String homeDirectoryName = 'home';
17+
const DashTool tool = DashTool.flutterTool;
18+
19+
late FileSystem fs;
20+
late Directory home;
21+
late FakeAnalytics analyticsOverride;
22+
23+
setUp(() {
24+
fs = MemoryFileSystem.test();
25+
home = fs.directory(homeDirectoryName);
26+
27+
// Prepare the tests by "onboarding" the tool into the package
28+
// by invoking the [clientShowedMessage] method for the provided
29+
// [tool]
30+
final FakeAnalytics initialAnalytics = FakeAnalytics(
31+
tool: tool,
32+
homeDirectory: home,
33+
dartVersion: '3.0.0',
34+
platform: DevicePlatform.macos,
35+
fs: fs,
36+
surveyHandler: SurveyHandler(
37+
homeDirectory: home,
38+
fs: fs,
39+
),
40+
);
41+
initialAnalytics.clientShowedMessage();
42+
43+
analyticsOverride = FakeAnalytics(
44+
tool: tool,
45+
homeDirectory: home,
46+
dartVersion: '3.0.0',
47+
platform: DevicePlatform.macos,
48+
fs: fs,
49+
surveyHandler: SurveyHandler(
50+
homeDirectory: home,
51+
fs: fs,
52+
),
53+
);
54+
});
55+
56+
group('Unit testing getAnalytics', () {
57+
testWithoutContext('Successfully creates the instance for standard branch', () {
58+
final Analytics analytics = getAnalytics(
59+
runningOnBot: false,
60+
flutterVersion: FakeFlutterVersion(),
61+
environment: const <String, String>{},
62+
analyticsOverride: analyticsOverride,
63+
);
64+
65+
expect(analytics.clientId, isNot(NoOpAnalytics.staticClientId),
66+
reason: 'The CLIENT ID should be a randomly generated id');
67+
expect(analytics, isNot(isA<NoOpAnalytics>()));
68+
});
69+
70+
testWithoutContext('NoOp instance for user branch', () {
71+
final Analytics analytics = getAnalytics(
72+
runningOnBot: false,
73+
flutterVersion: FakeFlutterVersion(
74+
branch: userBranch,
75+
frameworkRevision: '3.14.0-14.0.pre.370',
76+
),
77+
environment: const <String, String>{},
78+
analyticsOverride: analyticsOverride,
79+
);
80+
81+
expect(
82+
analytics.clientId,
83+
NoOpAnalytics.staticClientId,
84+
reason: 'The client ID should match the NoOp client id',
85+
);
86+
expect(analytics, isA<NoOpAnalytics>());
87+
});
88+
89+
testWithoutContext('NoOp instance for unknown branch', () {
90+
final Analytics analytics = getAnalytics(
91+
runningOnBot: false,
92+
flutterVersion: FakeFlutterVersion(
93+
frameworkRevision: 'unknown',
94+
),
95+
environment: const <String, String>{},
96+
analyticsOverride: analyticsOverride,
97+
);
98+
99+
expect(
100+
analytics.clientId,
101+
NoOpAnalytics.staticClientId,
102+
reason: 'The client ID should match the NoOp client id',
103+
);
104+
expect(analytics, isA<NoOpAnalytics>());
105+
});
106+
107+
testWithoutContext('NoOp instance when running on bots', () {
108+
final Analytics analytics = getAnalytics(
109+
runningOnBot: true,
110+
flutterVersion: FakeFlutterVersion(),
111+
environment: const <String, String>{},
112+
analyticsOverride: analyticsOverride,
113+
);
114+
115+
expect(
116+
analytics.clientId,
117+
NoOpAnalytics.staticClientId,
118+
reason: 'The client ID should match the NoOp client id',
119+
);
120+
expect(analytics, isA<NoOpAnalytics>());
121+
});
122+
123+
testWithoutContext('NoOp instance when suppressing via env variable', () {
124+
final Analytics analytics = getAnalytics(
125+
runningOnBot: true,
126+
flutterVersion: FakeFlutterVersion(),
127+
environment: const <String, String>{'FLUTTER_SUPPRESS_ANALYTICS': 'true'},
128+
analyticsOverride: analyticsOverride,
129+
);
130+
131+
expect(
132+
analytics.clientId,
133+
NoOpAnalytics.staticClientId,
134+
reason: 'The client ID should match the NoOp client id',
135+
);
136+
expect(analytics, isA<NoOpAnalytics>());
137+
});
138+
});
139+
}

packages/flutter_tools/test/src/context.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import 'package:flutter_tools/src/reporting/reporting.dart';
3535
import 'package:flutter_tools/src/version.dart';
3636
import 'package:meta/meta.dart';
3737
import 'package:test/fake.dart';
38+
import 'package:unified_analytics/unified_analytics.dart';
3839

3940
import 'common.dart';
4041
import 'fake_http_client.dart';
@@ -120,6 +121,7 @@ void testUsingContext(
120121
Pub: () => ThrowingPub(), // prevent accidentally using pub.
121122
CrashReporter: () => const NoopCrashReporter(),
122123
TemplateRenderer: () => const MustacheTemplateRenderer(),
124+
Analytics: () => NoOpAnalytics(),
123125
},
124126
body: () {
125127
return runZonedGuarded<Future<dynamic>>(() {

packages/flutter_tools/test/src/fakes.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ class FakeFlutterVersion implements FlutterVersion {
426426

427427
@override
428428
String getVersionString({bool redactUnknownBranches = false}) {
429-
return 'v0.0.0';
429+
return '${getBranchName(redactUnknownBranches: redactUnknownBranches)}/$frameworkRevision';
430430
}
431431

432432
@override

0 commit comments

Comments
 (0)