Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/device_info_plus/device_info_plus/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 3.2.0

- add `deviceInfo`

## 3.1.1

- add toMap to WebBrowserInfo
Expand Down
11 changes: 11 additions & 0 deletions packages/device_info_plus/device_info_plus/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ WebBrowserInfo webBrowserInfo = await deviceInfo.webBrowserInfo;
print('Running on ${webBrowserInfo.userAgent}'); // e.g. "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0"
```

One common use case for this plugin is obtaining device information for telemetry or crash-reporting purposes. In this scenario your app is not interested in specific properties, instead it wants to send all it knows about the device to your backend service for further analysis. You can leverage `deviceInfo` property, which returns platform-specific device information in a generic way. You then use it's `toMap` method to serialize all known properties to a `Map`. Your backend service should be prepared to handle new properties, which can be added to this plugin in the future.

```dart
import 'package:device_info_plus/device_info_plus.dart';

final deviceInfoPlugin = DeviceInfoPlugin();
final deviceInfo = await deviceInfoPlugin.deviceInfo;
final map = deviceInfo.toMap();
// Push [map] to your service.
```

You will find links to the API docs on the [pub page](https://pub.dev/packages/device_info_plus).

Check out our documentation website to learn more. [Plus plugins documentation](https://plus.fluttercommunity.dev/docs/overview)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,41 +19,50 @@ void main() {
WindowsDeviceInfo windowsInfo;
LinuxDeviceInfo linuxInfo;
MacOsDeviceInfo macosInfo;
BaseDeviceInfo deviceInfo;

setUpAll(() async {
final deviceInfoPlugin = DeviceInfoPlugin();
if (Platform.isIOS) {
iosInfo = await deviceInfoPlugin.iosInfo;
} else if (Platform.isAndroid) {
androidInfo = await deviceInfoPlugin.androidInfo;
} else if (Platform.isWindows) {
windowsInfo = await deviceInfoPlugin.windowsInfo;
} else if (Platform.isLinux) {
linuxInfo = await deviceInfoPlugin.linuxInfo;
} else if (Platform.isMacOS) {
macosInfo = await deviceInfoPlugin.macOsInfo;
}

if (kIsWeb) {
webBrowserInfo = await deviceInfoPlugin.webBrowserInfo;
} else {
if (Platform.isIOS) {
iosInfo = await deviceInfoPlugin.iosInfo;
} else if (Platform.isAndroid) {
androidInfo = await deviceInfoPlugin.androidInfo;
} else if (Platform.isWindows) {
windowsInfo = await deviceInfoPlugin.windowsInfo;
} else if (Platform.isLinux) {
linuxInfo = await deviceInfoPlugin.linuxInfo;
} else if (Platform.isMacOS) {
macosInfo = await deviceInfoPlugin.macOsInfo;
}
}

deviceInfo = await deviceInfoPlugin.deviceInfo;
});

testWidgets('Can get non-null device model', (WidgetTester tester) async {
if (Platform.isIOS) {
expect(iosInfo.model, isNotNull);
} else if (Platform.isAndroid) {
expect(androidInfo.model, isNotNull);
} else if (Platform.isWindows) {
expect(windowsInfo.computerName, isNotNull);
} else if (Platform.isLinux) {
expect(linuxInfo.name, isNotNull);
} else if (Platform.isMacOS) {
expect(macosInfo.computerName, isNotNull);
}

if (kIsWeb) {
expect(webBrowserInfo.userAgent, isNotNull);
expect(deviceInfo, same(webBrowserInfo));
} else {
if (Platform.isIOS) {
expect(iosInfo.model, isNotNull);
expect(deviceInfo, same(iosInfo));
} else if (Platform.isAndroid) {
expect(androidInfo.model, isNotNull);
expect(deviceInfo, same(androidInfo));
} else if (Platform.isWindows) {
expect(windowsInfo.computerName, isNotNull);
expect(deviceInfo, same(windowsInfo));
} else if (Platform.isLinux) {
expect(linuxInfo.name, isNotNull);
expect(deviceInfo, same(linuxInfo));
} else if (Platform.isMacOS) {
expect(macosInfo.computerName, isNotNull);
expect(deviceInfo, same(macosInfo));
}
}
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,6 @@

// @dart=2.9

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter_driver/flutter_driver.dart';
import 'package:integration_test/integration_test_driver.dart';

Future<void> main() async {
final driver = await FlutterDriver.connect();
final data =
await driver.requestData(null, timeout: const Duration(minutes: 1));
await driver.close();
final Map<String, dynamic> result = jsonDecode(data);
exit(result['result'] == 'true' ? 0 : 1);
}
Future<void> main() => integrationDriver();
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
// found in the LICENSE file.

import 'dart:async';
import 'dart:io';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Doesn't this throw on web?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not anymore. There is still a problem with some cached compiler info, you cannot mix web and non-web builds (technically speaking runs, not builds) on a single cache. For example if you do:

$ flutter run --device-id macos

then

$ flutter run --device-id chrome

fails with a bunch of errors referring not only to dart:io, but hundreds of errors for dart:ffi and package:win32 which are transient dependencies from device_info_plus_windows. This is a result of merging #598. To mitigate it you have to flutter clean every time you switch running web vs. non-web platforms. When you do flutter build web this is not a problem, because it uses correct compiler every time it's invoked and does not depend on cached stuff.


import 'package:device_info_plus_platform_interface/device_info_plus_platform_interface.dart';
import 'package:flutter/foundation.dart';
export 'package:device_info_plus_platform_interface/device_info_plus_platform_interface.dart'
show
AndroidBuildVersion,
AndroidDeviceInfo,
BaseDeviceInfo,
IosDeviceInfo,
IosUtsname,
LinuxDeviceInfo,
Expand Down Expand Up @@ -76,4 +79,25 @@ class DeviceInfoPlugin {
/// Returns device information for Windows.
Future<WindowsDeviceInfo> get windowsInfo async =>
_cachedWindowsDeviceInfo ??= await _platform.windowsInfo()!;

/// Returns device information for the current platform.
Future<BaseDeviceInfo> get deviceInfo async {
if (kIsWeb) {
return webBrowserInfo;
} else {
if (Platform.isAndroid) {
return androidInfo;
} else if (Platform.isIOS) {
return iosInfo;
} else if (Platform.isLinux) {
return linuxInfo;
} else if (Platform.isMacOS) {
return macOsInfo;
} else if (Platform.isWindows) {
return windowsInfo;
}
}

throw UnsupportedError('Unsupported platform');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The error message probably should tell the user which the current platform is. We could also tell the user to create an issue or PR in this repo for unsupported platforms.

Also, does this need tests?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure about the idea of more detailed explanation. Most UnsupportedError exceptions in flutter/plugins or this repo simply states that current platform is well not supported, without any further explanation. Thats contrasting with assertion messages throughout Flutter, which are very verbose, suggesting fixes, or further actions.

}
}
4 changes: 2 additions & 2 deletions packages/device_info_plus/device_info_plus/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: device_info_plus
description: Flutter plugin providing detailed information about the device
(make, model, etc.), and Android or iOS version the app is running on.
version: 3.1.1
version: 3.2.0
homepage: https://plus.fluttercommunity.dev/
repository: https://github.com/fluttercommunity/plus_plugins/tree/main/packages/

Expand All @@ -25,7 +25,7 @@ flutter:
dependencies:
flutter:
sdk: flutter
device_info_plus_platform_interface: ^2.2.0
device_info_plus_platform_interface: ^2.3.0
device_info_plus_linux: ^2.1.0
device_info_plus_macos: ^2.2.0
device_info_plus_web: ^2.1.0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.3.0

- add `BaseDeviceInfo`

## 2.2.1

- add toMap to WebBrowserInfo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ import 'model/web_browser_info.dart';
import 'model/windows_device_info.dart';

export 'model/android_device_info.dart';
export 'model/base_device_info.dart';
export 'model/ios_device_info.dart';
export 'model/linux_device_info.dart';
export 'model/macos_device_info.dart';
export 'model/web_browser_info.dart';
export 'model/macos_device_info.dart';
export 'model/windows_device_info.dart';

/// The interface that implementations of device_info must implement.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'base_device_info.dart';

/// Information derived from `android.os.Build`.
///
/// See: https://developer.android.com/reference/android/os/Build.html
class AndroidDeviceInfo {
class AndroidDeviceInfo implements BaseDeviceInfo {
/// Android device Info class.
AndroidDeviceInfo({
required this.version,
Expand Down Expand Up @@ -110,7 +112,8 @@ class AndroidDeviceInfo {
/// https://developer.android.com/reference/android/content/pm/PackageManager
final List<String?> systemFeatures;

/// Serializes [ AndroidDeviceInfo ] to map.
/// Serializes [AndroidDeviceInfo] to map.
@override
Map<String, dynamic> toMap() {
return {
'id': id,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// The base class for platform's device info.
abstract class BaseDeviceInfo {
/// Serializes device info properties to a map.
Map<String, dynamic> toMap();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'base_device_info.dart';

/// Information derived from `UIDevice`.
///
/// See: https://developer.apple.com/documentation/uikit/uidevice
class IosDeviceInfo {
class IosDeviceInfo implements BaseDeviceInfo {
/// IOS device info class.
const IosDeviceInfo({
this.name,
Expand Down Expand Up @@ -57,7 +59,8 @@ class IosDeviceInfo {
);
}

/// Serializes [ IosDeviceInfo ] to a map.
/// Serializes [IosDeviceInfo] to a map.
@override
Map<String, dynamic> toMap() {
return {
'name': name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'base_device_info.dart';

/// Device information for a Linux system.
///
/// See:
/// - https://www.freedesktop.org/software/systemd/man/os-release.html
/// - https://www.freedesktop.org/software/systemd/man/machine-id.html
class LinuxDeviceInfo {
class LinuxDeviceInfo implements BaseDeviceInfo {
/// Constructs a LinuxDeviceInfo.
/// A string identifying the operating system, without a version component,

Expand Down Expand Up @@ -137,4 +139,22 @@ class LinuxDeviceInfo {
/// boot. The machine ID is hexadecimal, 32-character, lowercase ID. When
/// decoded from hexadecimal, this corresponds to a 16-byte/128-bit value.
final String? machineId;

/// Serializes [LinuxDeviceInfo] to a map.
@override
Map<String, dynamic> toMap() {
return {
'name': name,
'version': version,
'id': id,
'idLike': idLike,
'versionCodename': versionCodename,
'versionId': versionId,
'prettyName': prettyName,
'buildId': buildId,
'variant': variant,
'variantId': variantId,
'machineId': machineId,
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'base_device_info.dart';

/// Object encapsulating MACOS device information.
class MacOsDeviceInfo {
class MacOsDeviceInfo implements BaseDeviceInfo {
/// Constructs a MacOsDeviceInfo.
const MacOsDeviceInfo({
required this.computerName,
Expand Down Expand Up @@ -52,7 +54,8 @@ class MacOsDeviceInfo {
/// Device GUID
final String? systemGUID;

/// Serializes [ MacOsDeviceInfo ] to map.
/// Serializes [MacOsDeviceInfo] to map.
@override
Map<String, dynamic> toMap() {
return {
'arch': arch,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'base_device_info.dart';

/// List of supported browsers
enum BrowserName {
/// Mozilla Firefox
Expand Down Expand Up @@ -32,7 +34,7 @@ enum BrowserName {
/// Information derived from `navigator`.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/Window/navigator
class WebBrowserInfo {
class WebBrowserInfo implements BaseDeviceInfo {
/// Web Browser info class.
WebBrowserInfo({
required this.appCodeName,
Expand Down Expand Up @@ -126,7 +128,8 @@ class WebBrowserInfo {
);
}

/// Serializes [ WebBrowserInfo ] to a map.
/// Serializes [WebBrowserInfo] to a map.
@override
Map<String, dynamic> toMap() {
return {
'browserName': browserName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'base_device_info.dart';

/// Object encapsulating WINDOWS device information.
class WindowsDeviceInfo {
class WindowsDeviceInfo implements BaseDeviceInfo {
/// Constructs a [WindowsDeviceInfo].
WindowsDeviceInfo({
required this.computerName,
Expand All @@ -20,4 +22,14 @@ class WindowsDeviceInfo {
/// The physically installed memory in the computer.
/// This may not be the same as available memory.
final int systemMemoryInMegabytes;

/// Serializes [WindowsDeviceInfo] to a map.
@override
Map<String, dynamic> toMap() {
return {
'computerName': computerName,
'numberOfCores': numberOfCores,
'systemMemoryInMegabytes': systemMemoryInMegabytes,
};
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: device_info_plus_platform_interface
description: A common platform interface for the device_info_plus plugin.
version: 2.2.1
version: 2.3.0
homepage: https://plus.fluttercommunity.dev/
repository: https://github.com/fluttercommunity/plus_plugins/tree/main/packages/

Expand Down
Loading