Skip to content

Commit

Permalink
[device_info_platform_interface] handle null value from method channel (
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Yang authored Feb 23, 2021
1 parent bd88615 commit 3b42025
Show file tree
Hide file tree
Showing 5 changed files with 344 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ import 'dart:async';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';

import 'method_channel/method_channel_device_info.dart';

import 'model/android_device_info.dart';
import 'model/ios_device_info.dart';

export 'model/android_device_info.dart';
export 'model/ios_device_info.dart';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';

import 'package:flutter/services.dart';
import 'package:meta/meta.dart';

import 'package:device_info_platform_interface/device_info_platform_interface.dart';

/// An implementation of [DeviceInfoPlatform] that uses method channels.
Expand All @@ -13,16 +16,15 @@ class MethodChannelDeviceInfo extends DeviceInfoPlatform {

// Method channel for Android devices
Future<AndroidDeviceInfo> androidInfo() async {
return AndroidDeviceInfo.fromMap(
(await channel.invokeMethod('getAndroidDeviceInfo'))
.cast<String, dynamic>(),
);
return AndroidDeviceInfo.fromMap((await channel
.invokeMapMethod<String, dynamic>('getAndroidDeviceInfo')) ??
<String, dynamic>{});
}

// Method channel for iOS devices
Future<IosDeviceInfo> iosInfo() async {
return IosDeviceInfo.fromMap(
(await channel.invokeMethod('getIosDeviceInfo')).cast<String, dynamic>(),
);
(await channel.invokeMapMethod<String, dynamic>('getIosDeviceInfo')) ??
<String, dynamic>{});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,39 +38,63 @@ class AndroidDeviceInfo {
final AndroidBuildVersion version;

/// The name of the underlying board, like "goldfish".
///
/// The value is an empty String if it is not available.
final String board;

/// The system bootloader version number.
///
/// The value is an empty String if it is not available.
final String bootloader;

/// The consumer-visible brand with which the product/hardware will be associated, if any.
///
/// The value is an empty String if it is not available.
final String brand;

/// The name of the industrial design.
///
/// The value is an empty String if it is not available.
final String device;

/// A build ID string meant for displaying to the user.
///
/// The value is an empty String if it is not available.
final String display;

/// A string that uniquely identifies this build.
///
/// The value is an empty String if it is not available.
final String fingerprint;

/// The name of the hardware (from the kernel command line or /proc).
///
/// The value is an empty String if it is not available.
final String hardware;

/// Hostname.
///
/// The value is an empty String if it is not available.
final String host;

/// Either a changelist number, or a label like "M4-rc20".
///
/// The value is an empty String if it is not available.
final String id;

/// The manufacturer of the product/hardware.
///
/// The value is an empty String if it is not available.
final String manufacturer;

/// The end-user-visible name for the end product.
///
/// The value is an empty String if it is not available.
final String model;

/// The name of the overall product.
///
/// The value is an empty String if it is not available.
final String product;

/// An ordered list of 32 bit ABIs supported by this device.
Expand All @@ -83,15 +107,23 @@ class AndroidDeviceInfo {
final List<String> supportedAbis;

/// Comma-separated tags describing the build, like "unsigned,debug".
///
/// The value is an empty String if it is not available.
final String tags;

/// The type of build, like "user" or "eng".
///
/// The value is an empty String if it is not available.
final String type;

/// `false` if the application is running in an emulator, `true` otherwise.
/// The value is `true` if the application is running on a physical device.
///
/// The value is `false` when the application is running on a emulator, or the value is unavailable.
final bool isPhysicalDevice;

/// The Android hardware device ID that is unique between the device + user and app signing.
///
/// The value is an empty String if it is not available.
final String androidId;

/// Describes what features are available on the current device.
Expand All @@ -113,35 +145,41 @@ class AndroidDeviceInfo {
/// Deserializes from the message received from [_kChannel].
static AndroidDeviceInfo fromMap(Map<String, dynamic> map) {
return AndroidDeviceInfo(
version:
AndroidBuildVersion._fromMap(map['version']!.cast<String, dynamic>()),
board: map['board']!,
bootloader: map['bootloader']!,
brand: map['brand']!,
device: map['device']!,
display: map['display']!,
fingerprint: map['fingerprint']!,
hardware: map['hardware']!,
host: map['host']!,
id: map['id']!,
manufacturer: map['manufacturer']!,
model: map['model']!,
product: map['product']!,
supported32BitAbis: _fromList(map['supported32BitAbis']!),
supported64BitAbis: _fromList(map['supported64BitAbis']!),
supportedAbis: _fromList(map['supportedAbis']!),
tags: map['tags']!,
type: map['type']!,
isPhysicalDevice: map['isPhysicalDevice']!,
androidId: map['androidId']!,
systemFeatures: _fromList(map['systemFeatures']!),
version: AndroidBuildVersion._fromMap(map['version'] != null
? map['version'].cast<String, dynamic>()
: <String, dynamic>{}),
board: map['board'] ?? '',
bootloader: map['bootloader'] ?? '',
brand: map['brand'] ?? '',
device: map['device'] ?? '',
display: map['display'] ?? '',
fingerprint: map['fingerprint'] ?? '',
hardware: map['hardware'] ?? '',
host: map['host'] ?? '',
id: map['id'] ?? '',
manufacturer: map['manufacturer'] ?? '',
model: map['model'] ?? '',
product: map['product'] ?? '',
supported32BitAbis: _fromList(map['supported32BitAbis']),
supported64BitAbis: _fromList(map['supported64BitAbis']),
supportedAbis: _fromList(map['supportedAbis']),
tags: map['tags'] ?? '',
type: map['type'] ?? '',
isPhysicalDevice: map['isPhysicalDevice'] ?? false,
androidId: map['androidId'] ?? '',
systemFeatures: _fromList(map['systemFeatures']),
);
}

/// Deserializes message as List<String>
static List<String> _fromList(dynamic message) {
final List<dynamic> list = message;
return List<String>.from(list);
if (message == null) {
return <String>[];
}
assert(message is List<dynamic>);
final List<dynamic> list = List<dynamic>.from(message)
..removeWhere((value) => value == null);
return list.cast<String>();
}
}

Expand Down Expand Up @@ -173,17 +211,25 @@ class AndroidBuildVersion {
final String? securityPatch;

/// The current development codename, or the string "REL" if this is a release build.
///
/// The value is an empty String if it is not available.
final String codename;

/// The internal value used by the underlying source control to represent this build.
///
/// The value is an empty String if it is not available.
final String incremental;

/// The user-visible version string.
///
/// The value is an empty String if it is not available.
final String release;

/// The user-visible SDK version of the framework.
///
/// Possible values are defined in: https://developer.android.com/reference/android/os/Build.VERSION_CODES.html
///
/// The value is -1 if it is unavailable.
final int sdkInt;

/// Deserializes from the map message received from [_kChannel].
Expand All @@ -192,10 +238,10 @@ class AndroidBuildVersion {
baseOS: map['baseOS'],
previewSdkInt: map['previewSdkInt'],
securityPatch: map['securityPatch'],
codename: map['codename']!,
incremental: map['incremental']!,
release: map['release']!,
sdkInt: map['sdkInt']!,
codename: map['codename'] ?? '',
incremental: map['incremental'] ?? '',
release: map['release'] ?? '',
sdkInt: map['sdkInt'] ?? -1,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,40 +19,60 @@ class IosDeviceInfo {
});

/// Device name.
///
/// The value is an empty String if it is not available.
final String name;

/// The name of the current operating system.
///
/// The value is an empty String if it is not available.
final String systemName;

/// The current operating system version.
///
/// The value is an empty String if it is not available.
final String systemVersion;

/// Device model.
///
/// The value is an empty String if it is not available.
final String model;

/// Localized name of the device model.
///
/// The value is an empty String if it is not available.
final String localizedModel;

/// Unique UUID value identifying the current device.
///
/// The value is an empty String if it is not available.
final String identifierForVendor;

/// `false` if the application is running in a simulator, `true` otherwise.
/// The value is `true` if the application is running on a physical device.
///
/// The value is `false` when the application is running on a simulator, or the value is unavailable.
final bool isPhysicalDevice;

/// Operating system information derived from `sys/utsname.h`.
///
/// The value is an empty String if it is not available.
final IosUtsname utsname;

/// Deserializes from the map message received from [_kChannel].
static IosDeviceInfo fromMap(Map<String, dynamic> map) {
return IosDeviceInfo(
name: map['name']!,
systemName: map['systemName']!,
systemVersion: map['systemVersion']!,
model: map['model']!,
localizedModel: map['localizedModel']!,
identifierForVendor: map['identifierForVendor']!,
isPhysicalDevice: map['isPhysicalDevice'] == 'true',
utsname: IosUtsname._fromMap(map['utsname']!.cast<String, dynamic>()),
name: map['name'] ?? '',
systemName: map['systemName'] ?? '',
systemVersion: map['systemVersion'] ?? '',
model: map['model'] ?? '',
localizedModel: map['localizedModel'] ?? '',
identifierForVendor: map['identifierForVendor'] ?? '',
isPhysicalDevice: map['isPhysicalDevice'] != null
? map['isPhysicalDevice'] == 'true'
: false,
utsname: IosUtsname._fromMap(map['utsname'] != null
? map['utsname'].cast<String, dynamic>()
: <String, dynamic>{}),
);
}
}
Expand All @@ -69,28 +89,38 @@ class IosUtsname {
});

/// Operating system name.
///
/// The value is an empty String if it is not available.
final String sysname;

/// Network node name.
///
/// The value is an empty String if it is not available.
final String nodename;

/// Release level.
///
/// The value is an empty String if it is not available.
final String release;

/// Version level.
///
/// The value is an empty String if it is not available.
final String version;

/// Hardware type (e.g. 'iPhone7,1' for iPhone 6 Plus).
///
/// The value is an empty String if it is not available.
final String machine;

/// Deserializes from the map message received from [_kChannel].
static IosUtsname _fromMap(Map<String, dynamic> map) {
return IosUtsname._(
sysname: map['sysname']!,
nodename: map['nodename']!,
release: map['release']!,
version: map['version']!,
machine: map['machine']!,
sysname: map['sysname'] ?? '',
nodename: map['nodename'] ?? '',
release: map['release'] ?? '',
version: map['version'] ?? '',
machine: map['machine'] ?? '',
);
}
}
Loading

0 comments on commit 3b42025

Please sign in to comment.