-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This implements all of the logic for System Properties. This allows the SDK to fetch all of the system properties about the device, and browser. This ensures that we include basic device info for every event.
- Loading branch information
1 parent
8f133e5
commit de87a35
Showing
18 changed files
with
513 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import 'package:appfit/networking/properties/operating_system/operating_system_name.dart'; | ||
import 'package:device_info_plus/device_info_plus.dart'; | ||
|
||
class DeviceInfo { | ||
final OperatingSystemName? operatingSystem; | ||
final String? operatingSystemVersion; | ||
final String? deviceManufacturer; | ||
final String? deviceModel; | ||
final String? userAgent; | ||
final String? browserName; | ||
final String? browserVersion; | ||
|
||
const DeviceInfo({ | ||
this.operatingSystem, | ||
this.operatingSystemVersion, | ||
this.deviceManufacturer, | ||
this.deviceModel, | ||
this.userAgent, | ||
this.browserName, | ||
this.browserVersion, | ||
}); | ||
} | ||
|
||
class DeviceManager { | ||
const DeviceManager(); | ||
|
||
Future<DeviceInfo?> current() async { | ||
final deviceInfo = DeviceInfoPlugin(); | ||
switch (OperatingSystemName.current()) { | ||
case OperatingSystemName.iOS: | ||
final info = await deviceInfo.iosInfo; | ||
return DeviceInfo( | ||
operatingSystem: OperatingSystemName.iOS, | ||
operatingSystemVersion: info.systemVersion, | ||
deviceManufacturer: "Apple", | ||
deviceModel: info.utsname.machine, | ||
); | ||
|
||
case OperatingSystemName.android: | ||
final info = await deviceInfo.androidInfo; | ||
return DeviceInfo( | ||
operatingSystem: OperatingSystemName.android, | ||
operatingSystemVersion: info.version.release, | ||
deviceManufacturer: "Android", | ||
deviceModel: info.model, | ||
); | ||
|
||
case OperatingSystemName.macOS: | ||
final info = await deviceInfo.macOsInfo; | ||
return DeviceInfo( | ||
operatingSystem: OperatingSystemName.macOS, | ||
operatingSystemVersion: info.osRelease, | ||
deviceManufacturer: "Apple", | ||
deviceModel: info.model, | ||
); | ||
|
||
case OperatingSystemName.windows: | ||
// The required data for this is not available on windows. | ||
// This will need to be updated in the future. | ||
return null; | ||
|
||
case OperatingSystemName.linux: | ||
// The required data for this is not available on windows. | ||
// This will need to be updated in the future. | ||
return null; | ||
|
||
case OperatingSystemName.web: | ||
final info = await deviceInfo.webBrowserInfo; | ||
return DeviceInfo( | ||
operatingSystem: info.operatingSystem, | ||
operatingSystemVersion: null, | ||
deviceManufacturer: null, | ||
deviceModel: null, | ||
userAgent: info.userAgent, | ||
browserName: info.browserName.name, | ||
browserVersion: info.appVersion, | ||
); | ||
|
||
case OperatingSystemName.unknown: | ||
return const DeviceInfo( | ||
operatingSystem: OperatingSystemName.unknown, | ||
operatingSystemVersion: null, | ||
deviceManufacturer: "Unknown", | ||
deviceModel: "Unknown", | ||
); | ||
} | ||
} | ||
} | ||
|
||
extension OperatingSystem on WebBrowserInfo { | ||
OperatingSystemName? get operatingSystem { | ||
if (userAgent == null) return null; | ||
if (userAgent!.contains("Mac")) { | ||
return OperatingSystemName.macOS; | ||
} else if (userAgent!.contains("iPad") || | ||
userAgent!.contains("iPhone") || | ||
userAgent!.contains("iPod")) { | ||
return OperatingSystemName.iOS; | ||
} else if (userAgent!.contains("Android")) { | ||
return OperatingSystemName.android; | ||
} else if (userAgent!.contains("Windows")) { | ||
return OperatingSystemName.windows; | ||
} else if (userAgent!.contains("Linux")) { | ||
return OperatingSystemName.linux; | ||
} else { | ||
return OperatingSystemName.unknown; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import 'package:appfit/networking/managers/device_manager.dart'; | ||
import 'package:appfit/networking/properties/browser_properties.dart'; | ||
import 'package:appfit/networking/properties/device_properties.dart'; | ||
import 'package:appfit/networking/properties/event_system_properties.dart'; | ||
import 'package:appfit/networking/properties/operating_system/operating_system.dart'; | ||
import 'package:appfit/networking/properties/operating_system/operating_system_name.dart'; | ||
import 'package:flutter/foundation.dart'; | ||
import 'package:package_info_plus/package_info_plus.dart'; | ||
|
||
class SystemManager { | ||
/// The device manager | ||
/// This is used to get the current device properties | ||
/// such as the device model, manufacturer, and operating system | ||
/// version | ||
@visibleForTesting | ||
final DeviceManager deviceManager; | ||
|
||
const SystemManager({ | ||
this.deviceManager = const DeviceManager(), | ||
}); | ||
|
||
/// Returns the current properties of the system | ||
Future<EventSystemProperties> current() async { | ||
String? appVersion; | ||
try { | ||
final packageInfo = await PackageInfo.fromPlatform(); | ||
appVersion = packageInfo.version; | ||
} catch (e) { | ||
appVersion = null; | ||
} | ||
final manager = await deviceManager.current(); | ||
return EventSystemProperties( | ||
appVersion: appVersion, | ||
device: DeviceProperties( | ||
manufacturer: manager?.deviceManufacturer, | ||
model: manager?.deviceModel, | ||
), | ||
browser: BrowserProperties( | ||
name: manager?.browserName, | ||
version: manager?.browserVersion, | ||
userAgent: manager?.userAgent, | ||
), | ||
operatingSystem: OperatingSystemProperties( | ||
name: manager?.operatingSystem ?? OperatingSystemName.unknown, | ||
version: manager?.operatingSystemVersion, | ||
)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
class BrowserProperties { | ||
final String? userAgent; | ||
final String? name; | ||
final String? version; | ||
|
||
const BrowserProperties({ | ||
this.userAgent, | ||
this.name, | ||
this.version, | ||
}); | ||
|
||
/// Converts the [BrowserProperties] to a JSON object. | ||
/// This is used to convert an instance of [BrowserProperties] into a JSON object that can be sent to the server. | ||
Map<String, dynamic> toJson() { | ||
return { | ||
'userAgent': userAgent, | ||
'name': name, | ||
'version': version, | ||
}; | ||
} | ||
|
||
/// Creates a new instance of [BrowserProperties] from a JSON object. | ||
/// This is used to convert a JSON object from the server into an instance of [BrowserProperties]. | ||
factory BrowserProperties.fromJson(Map<String, dynamic> json) { | ||
return BrowserProperties( | ||
userAgent: json['userAgent'], | ||
name: json['name'], | ||
version: json['version'], | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
class DeviceProperties { | ||
/// The Device Manufacturer (Apple) | ||
final String? manufacturer; | ||
|
||
/// The Device Model (MacBookPro18,4) | ||
final String? model; | ||
|
||
const DeviceProperties({ | ||
required this.manufacturer, | ||
required this.model, | ||
}); | ||
|
||
/// Converts the [DeviceProperties] to a JSON object. | ||
Map<String, dynamic> toJson() { | ||
return { | ||
'manufacturer': manufacturer, | ||
'model': model, | ||
}; | ||
} | ||
|
||
/// Creates a new instance of [DeviceProperties] from a JSON object. | ||
factory DeviceProperties.fromJson(Map<String, dynamic> json) { | ||
return DeviceProperties( | ||
manufacturer: json['manufacturer'], | ||
model: json['model'], | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import 'package:appfit/networking/properties/browser_properties.dart'; | ||
import 'package:appfit/networking/properties/device_properties.dart'; | ||
import 'package:appfit/networking/properties/operating_system/operating_system.dart'; | ||
|
||
/// Event System Properties | ||
/// These return all of the system properties we generate based on the device type | ||
/// and data we wish to always include in every event. | ||
class EventSystemProperties { | ||
/// The version of the parent bundle | ||
final String? appVersion; | ||
|
||
/// All of the device related properties | ||
/// These include anything that is specific to the physical device | ||
/// such as model, operating system version, platform, etc | ||
final DeviceProperties? device; | ||
|
||
/// All of the browser properties | ||
/// These include the browser name, version, and user agent | ||
final BrowserProperties? browser; | ||
|
||
/// All of the operating system properties | ||
/// These include the operating system name (i.e. iOS or macOS) | ||
/// and the version number (i.e. 17.5.1) | ||
final OperatingSystemProperties? operatingSystem; | ||
|
||
/// Creates a new instance of [EventSystemProperties]. | ||
const EventSystemProperties({ | ||
this.appVersion, | ||
this.device, | ||
this.browser, | ||
this.operatingSystem, | ||
}); | ||
|
||
/// Converts the [EventSystemProperties] to a JSON object. | ||
/// This is used to convert the object to a JSON object that can be sent to the server. | ||
Map<String, dynamic> toJson() { | ||
return { | ||
'appVersion': appVersion, | ||
'device': device?.toJson(), | ||
'os': operatingSystem?.toJson(), | ||
}; | ||
} | ||
|
||
/// Creates a new instance of [EventSystemProperties] from a JSON object. | ||
/// This is used to convert a JSON object from the server into an instance of [EventSystemProperties]. | ||
factory EventSystemProperties.fromJson(Map<String, dynamic> json) { | ||
return EventSystemProperties( | ||
appVersion: json['appVersion'], | ||
device: DeviceProperties.fromJson(json['device']), | ||
operatingSystem: OperatingSystemProperties.fromJson(json['os']), | ||
); | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
lib/networking/properties/operating_system/operating_system.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import 'package:appfit/networking/properties/operating_system/operating_system_name.dart'; | ||
|
||
class OperatingSystemProperties { | ||
/// Operating System Name | ||
/// | ||
/// This returns the name of the operating system | ||
/// Example: iOS, macOS, Windows, etc | ||
final OperatingSystemName name; | ||
|
||
/// Operating System Version | ||
/// | ||
/// This will follow Semantic Versioning | ||
/// so it will return a string similar to major.minor.path (i.e. 17.5.1) | ||
final String? version; | ||
|
||
const OperatingSystemProperties({ | ||
required this.name, | ||
required this.version, | ||
}); | ||
|
||
/// Converts the [OperatingSystemProperties] to a JSON object. | ||
Map<String, dynamic> toJson() { | ||
return { | ||
'name': name.name, | ||
'version': version, | ||
}; | ||
} | ||
|
||
/// Creates a new instance of [OperatingSystemProperties] from a JSON object. | ||
factory OperatingSystemProperties.fromJson(Map<String, dynamic> json) { | ||
return OperatingSystemProperties( | ||
name: json['name'], | ||
version: json['version'], | ||
); | ||
} | ||
} |
Oops, something went wrong.