Skip to content

Commit

Permalink
[web] Resolve OS as iOs for iDevice Safari requesting desktop version…
Browse files Browse the repository at this point in the history
… of app. (#25957)
  • Loading branch information
ditman committed May 11, 2021
1 parent af0a96b commit 3c93ad4
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 33 deletions.
20 changes: 16 additions & 4 deletions lib/web_ui/lib/src/engine/browser_detection.dart
Expand Up @@ -131,7 +131,7 @@ enum OperatingSystem {
}

/// Lazily initialized current operating system.
late final OperatingSystem _operatingSystem = _detectOperatingSystem();
late final OperatingSystem _operatingSystem = detectOperatingSystem();

/// Returns the [OperatingSystem] the current browsers works on.
///
Expand All @@ -149,11 +149,23 @@ OperatingSystem get operatingSystem {
/// This is intended to be used for testing and debugging only.
OperatingSystem? debugOperatingSystemOverride;

OperatingSystem _detectOperatingSystem() {
final String platform = html.window.navigator.platform!;
final String userAgent = html.window.navigator.userAgent;
@visibleForTesting
OperatingSystem detectOperatingSystem({
String? overridePlatform,
String? overrideUserAgent,
int? overrideMaxTouchPoints,
}) {
final String platform = overridePlatform ?? html.window.navigator.platform!;
final String userAgent = overrideUserAgent ?? html.window.navigator.userAgent;

if (platform.startsWith('Mac')) {
// iDevices requesting a "desktop site" spoof their UA so it looks like a Mac.
// This checks if we're in a touch device, or on a real mac.
final int maxTouchPoints =
overrideMaxTouchPoints ?? html.window.navigator.maxTouchPoints ?? 0;
if (maxTouchPoints > 2) {
return OperatingSystem.iOs;
}
return OperatingSystem.macOs;
} else if (platform.toLowerCase().contains('iphone') ||
platform.toLowerCase().contains('ipad') ||
Expand Down
174 changes: 145 additions & 29 deletions lib/web_ui/test/browser_detect_test.dart
Expand Up @@ -11,38 +11,154 @@ void main() {
}

void testMain() {
test('Should detect Blink', () {
// Chrome Version 89.0.4389.90 (Official Build) (x86_64) / MacOS
BrowserEngine browserEngine = detectBrowserEngineByVendorAgent(
'Google Inc.',
'mozilla/5.0 (macintosh; intel mac os x 11_2_3) applewebkit/537.36 '
'(khtml, like gecko) chrome/89.0.4389.90 safari/537.36');
expect(browserEngine, BrowserEngine.blink);
});
group('detectBrowserEngineByVendorAgent', () {
test('Should detect Blink', () {
// Chrome Version 89.0.4389.90 (Official Build) (x86_64) / MacOS
BrowserEngine browserEngine = detectBrowserEngineByVendorAgent(
'Google Inc.',
'mozilla/5.0 (macintosh; intel mac os x 11_2_3) applewebkit/537.36 '
'(khtml, like gecko) chrome/89.0.4389.90 safari/537.36');
expect(browserEngine, BrowserEngine.blink);
});

test('Should detect Firefox', () {
// 85.0.2 (64-bit) / MacOS
BrowserEngine browserEngine = detectBrowserEngineByVendorAgent(
'',
'mozilla/5.0 (macintosh; intel mac os x 10.16; rv:85.0) '
'gecko/20100101 firefox/85.0');
expect(browserEngine, BrowserEngine.firefox);
});
test('Should detect Firefox', () {
// 85.0.2 (64-bit) / MacOS
BrowserEngine browserEngine = detectBrowserEngineByVendorAgent(
'',
'mozilla/5.0 (macintosh; intel mac os x 10.16; rv:85.0) '
'gecko/20100101 firefox/85.0');
expect(browserEngine, BrowserEngine.firefox);
});

test('Should detect Safari', () {
BrowserEngine browserEngine = detectBrowserEngineByVendorAgent(
'Apple Computer, Inc.',
'mozilla/5.0 (macintosh; intel mac os x 10_15_6) applewebkit/605.1.15 '
'(khtml, like gecko) version/14.0.3 safari/605.1.15');
expect(browserEngine, BrowserEngine.webkit);
});

test('Should detect Safari', () {
BrowserEngine browserEngine = detectBrowserEngineByVendorAgent(
'Apple Computer, Inc.',
'mozilla/5.0 (macintosh; intel mac os x 10_15_6) applewebkit/605.1.15 '
'(khtml, like gecko) version/14.0.3 safari/605.1.15');
expect(browserEngine, BrowserEngine.webkit);
test('Should detect Samsung browser', () {
// Samsung 13.2.1.70 on Galaxy Tab S6.
BrowserEngine browserEngine = detectBrowserEngineByVendorAgent(
'Google Inc.',
'mozilla/5.0 (x11; linux x86_64) applewebkit/537.36 (khtml, like gecko)'
' samsungbrowser/13.2 chrome/83.0.4103.106 safari/537.36');
expect(browserEngine, BrowserEngine.samsung);
});
});

test('Should detect Samsung browser', () {
// Samsung 13.2.1.70 on Galaxy Tab S6.
BrowserEngine browserEngine = detectBrowserEngineByVendorAgent(
'Google Inc.',
'mozilla/5.0 (x11; linux x86_64) applewebkit/537.36 (khtml, like gecko)'
' samsungbrowser/13.2 chrome/83.0.4103.106 safari/537.36');
expect(browserEngine, BrowserEngine.samsung);
group('detectOperatingSystem', () {
void expectOs(
OperatingSystem expectedOs, {
String platform = 'any',
String ua = 'any',
int touchPoints = 0,
}) {
expect(
detectOperatingSystem(
overridePlatform: platform,
overrideUserAgent: ua,
overrideMaxTouchPoints: touchPoints,
),
expectedOs);
}

test('Determine unknown for weird values of platform/ua', () {
expectOs(OperatingSystem.unknown);
});

test('Determine MacOS if platform starts by Mac', () {
expectOs(
OperatingSystem.macOs,
platform: 'MacIntel',
);
expectOs(
OperatingSystem.macOs,
platform: 'MacAnythingElse',
);
});

test('Determine iOS if platform contains iPhone/iPad/iPod', () {
expectOs(
OperatingSystem.iOs,
platform: 'iPhone',
);
expectOs(
OperatingSystem.iOs,
platform: 'iPhone Simulator',
);
expectOs(
OperatingSystem.iOs,
platform: 'iPad',
);
expectOs(
OperatingSystem.iOs,
platform: 'iPad Simulator',
);
expectOs(
OperatingSystem.iOs,
platform: 'iPod',
);
expectOs(
OperatingSystem.iOs,
platform: 'iPod Simulator',
);
});

// See https://github.com/flutter/flutter/issues/81918
test('Tell apart MacOS from iOS requesting a desktop site.', () {
expectOs(
OperatingSystem.macOs,
platform: 'MacARM',
);

expectOs(
OperatingSystem.iOs,
platform: 'MacARM',
touchPoints: 5,
);
});

test('Determine Android if user agent contains Android', () {
expectOs(
OperatingSystem.android,
ua: 'Mozilla/5.0 (Linux; U; Android 2.2) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1',
);
});

test('Determine Linux if the platform begins with Linux', () {
expectOs(
OperatingSystem.linux,
platform: 'Linux',
);
expectOs(
OperatingSystem.linux,
platform: 'Linux armv8l',
);
expectOs(
OperatingSystem.linux,
platform: 'Linux x86_64',
);
});

test('Determine Windows if the platform begins with Win', () {
expectOs(
OperatingSystem.windows,
platform: 'Windows',
);
expectOs(
OperatingSystem.windows,
platform: 'Win32',
);
expectOs(
OperatingSystem.windows,
platform: 'Win16',
);
expectOs(
OperatingSystem.windows,
platform: 'WinCE',
);
});
});
}

0 comments on commit 3c93ad4

Please sign in to comment.