Skip to content

Commit

Permalink
Add selection analytics for NetworkScreen (#3360)
Browse files Browse the repository at this point in the history
  • Loading branch information
kenzieschmoll authored Dec 7, 2021
1 parent 6e1bfee commit 5c3493d
Show file tree
Hide file tree
Showing 7 changed files with 343 additions and 149 deletions.
2 changes: 2 additions & 0 deletions packages/devtools_app/lib/src/analytics/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import '../inspector/inspector_screen.dart';
import '../logging/logging_screen.dart';
import '../memory/memory_screen.dart';
import '../network/network_screen.dart';
import '../performance/performance_screen.dart';
import '../profiler/profiler_screen.dart';

Expand All @@ -22,6 +23,7 @@ const String inspector = InspectorScreen.id;
const String performance = PerformanceScreen.id;
const String cpuProfiler = ProfilerScreen.id;
const String memory = MemoryScreen.id;
const String network = NetworkScreen.id;
const String logging = LoggingScreen.id;

// GA events not associated with a any screen e.g., hotReload, hotRestart, etc
Expand Down
31 changes: 25 additions & 6 deletions packages/devtools_app/lib/src/http/http_request_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import 'dart:convert';
import 'dart:typed_data';

import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:mime/mime.dart';
import 'package:vm_service/vm_service.dart';

Expand Down Expand Up @@ -169,10 +169,6 @@ abstract class HttpRequestData extends NetworkRequest {
return false;
}

/// True if the HTTP request hasn't completed yet, determined by the lack of
/// an end event.
bool get inProgress;

/// All instant events logged to the timeline for this HTTP request.
List<HttpInstantEvent> get instantEvents;

Expand Down Expand Up @@ -481,18 +477,23 @@ class TimelineHttpRequestData extends HttpRequestData {
String toString() => '$method $uri';
}

int _dartIoHttpRequestWrapperId = 0;

class DartIOHttpRequestData extends HttpRequestData {
DartIOHttpRequestData(
int timelineMicrosBase,
this._request,
) : super(timelineMicrosBase) {
) : wrapperId = _dartIoHttpRequestWrapperId++,
super(timelineMicrosBase) {
if (_request.isResponseComplete) {
getFullRequestData();
}
}

HttpProfileRequestRef _request;

final int wrapperId;

Future<void> getFullRequestData() {
return serviceManager.service
.getHttpProfileRequest(
Expand Down Expand Up @@ -674,4 +675,22 @@ class DartIOHttpRequestData extends HttpRequestData {
lastTime = instantTime;
}
}

@override
bool operator ==(other) {
return other is DartIOHttpRequestData &&
wrapperId == other.wrapperId &&
super == other;
}

@override
int get hashCode => hashValues(
wrapperId,
method,
uri,
contentType,
type,
port,
startTimestamp,
);
}
35 changes: 35 additions & 0 deletions packages/devtools_app/lib/src/network/network_model.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:flutter/material.dart';
import 'package:vm_service/vm_service.dart';

import '../http/http_request_data.dart';
Expand Down Expand Up @@ -29,6 +30,9 @@ abstract class NetworkRequest with DataSearchStateMixin {

bool get didFail;

/// True if the request hasn't completed yet.
bool get inProgress;

String get durationDisplay =>
'Duration: ${duration != null ? msText(duration) : 'Pending'}';

Expand All @@ -38,6 +42,34 @@ abstract class NetworkRequest with DataSearchStateMixin {

@override
String toString() => '$method $uri';

@override
bool operator ==(other) {
return other is NetworkRequest &&
runtimeType == other.runtimeType &&
startTimestamp == other.startTimestamp &&
method == other.method &&
uri == other.uri &&
contentType == other.contentType &&
type == other.type &&
port == other.port &&
(inProgress == other.inProgress
? (endTimestamp == other.endTimestamp &&
duration == other.duration &&
status == other.status &&
didFail == other.didFail)
: true);
}

@override
int get hashCode => hashValues(
method,
uri,
contentType,
type,
port,
startTimestamp,
);
}

class WebSocket extends NetworkRequest {
Expand Down Expand Up @@ -107,6 +139,9 @@ class WebSocket extends NetworkRequest {
@override
String get status => '101';

@override
bool get inProgress => false;

@override
bool operator ==(other) => other is WebSocket && id == other.id;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

import 'package:flutter/material.dart';

import '../analytics/constants.dart' as analytics_constants;
import '../common_widgets.dart';
import '../http/http_request_data.dart';
import '../theme.dart';
import '../ui/tab.dart';
import 'network_model.dart';
import 'network_request_inspector_views.dart';
Expand Down Expand Up @@ -39,6 +39,7 @@ class NetworkRequestInspector extends StatelessWidget {
Widget _buildTab(String tabName) {
return DevToolsTab(
key: ValueKey<String>(tabName),
gaId: 'requestInspectorTab_$tabName',
child: Text(
tabName,
overflow: TextOverflow.ellipsis,
Expand All @@ -48,51 +49,29 @@ class NetworkRequestInspector extends StatelessWidget {

@override
Widget build(BuildContext context) {
final tabs = <Tab>[
_buildTab(_overviewTabTitle),
final tabs = <DevToolsTab>[
_buildTab(NetworkRequestInspector._overviewTabTitle),
if (data is HttpRequestData) ...[
_buildTab(_headersTabTitle),
_buildTab(NetworkRequestInspector._headersTabTitle),
if ((data as HttpRequestData).requestBody != null)
_buildTab(_requestTabTitle),
_buildTab(NetworkRequestInspector._requestTabTitle),
if ((data as HttpRequestData).responseBody != null)
_buildTab(_responseTabTitle),
if ((data as HttpRequestData).hasCookies) _buildTab(_cookiesTabTitle),
_buildTab(NetworkRequestInspector._responseTabTitle),
if ((data as HttpRequestData).hasCookies)
_buildTab(NetworkRequestInspector._cookiesTabTitle),
],
];
final tabViews = [
NetworkRequestOverviewView(data),
if (data is HttpRequestData) ...[
HttpRequestHeadersView(data),
if ((data as HttpRequestData).requestBody != null)
HttpRequestView(data),
if ((data as HttpRequestData).responseBody != null)
HttpResponseView(data),
if ((data as HttpRequestData).hasCookies) HttpRequestCookiesView(data),
],
];
final tabbedContent = DefaultTabController(
length: tabs.length,
child: Column(
children: [
Row(
children: [
Flexible(
child: TabBar(
labelColor: Theme.of(context).textTheme.bodyText1.color,
tabs: tabs,
),
),
],
),
Expanded(
child: TabBarView(
physics: defaultTabBarViewPhysics,
children: [
NetworkRequestOverviewView(data),
if (data is HttpRequestData) ...[
HttpRequestHeadersView(data),
if ((data as HttpRequestData).requestBody != null)
HttpRequestView(data),
if ((data as HttpRequestData).responseBody != null)
HttpResponseView(data),
if ((data as HttpRequestData).hasCookies)
HttpRequestCookiesView(data),
],
],
),
),
],
),
);

return Card(
margin: EdgeInsets.zero,
Expand All @@ -102,11 +81,15 @@ class NetworkRequestInspector extends StatelessWidget {
? Center(
child: Text(
'No request selected',
key: noRequestSelectedKey,
key: NetworkRequestInspector.noRequestSelectedKey,
style: Theme.of(context).textTheme.headline6,
),
)
: tabbedContent,
: AnalyticsTabbedView(
tabs: tabs,
tabViews: tabViews,
gaScreen: analytics_constants.network,
),
),
);
}
Expand Down
Loading

0 comments on commit 5c3493d

Please sign in to comment.