1// Copyright 2014 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/// @docImport 'package:flutter/material.dart';
6/// @docImport 'package:flutter_test/flutter_test.dart';
7library;
8
9import '_platform_io.dart'
10 if (dart.library.js_util) '_platform_web.dart' as platform;
11import 'assertions.dart';
12import 'constants.dart';
13
14/// The [TargetPlatform] that matches the platform on which the framework is
15/// currently executing.
16///
17/// This is the default value of [ThemeData.platform] (hence the name). Widgets
18/// from the material library should use [Theme.of] to determine the current
19/// platform for styling purposes, rather than using [defaultTargetPlatform].
20/// Widgets and render objects at lower layers that try to emulate the
21/// underlying platform can depend on [defaultTargetPlatform] directly. The
22/// [dart:io.Platform] object should only be used directly when it's critical to
23/// actually know the current platform, without any overrides possible (for
24/// example, when a system API is about to be called).
25///
26/// In a test environment, the platform returned is [TargetPlatform.android]
27/// regardless of the host platform. (Android was chosen because the tests were
28/// originally written assuming Android-like behavior, and we added platform
29/// adaptations for iOS later). Tests can check iOS behavior by using the
30/// platform override APIs (such as [ThemeData.platform] in the material
31/// library) or by setting [debugDefaultTargetPlatformOverride] in debug builds.
32///
33/// Tests can also create specific platform tests by and adding a `variant:`
34/// argument to the test and using a [TargetPlatformVariant].
35///
36/// See also:
37///
38/// * [kIsWeb], a boolean which is true if the application is running on the
39/// web, where [defaultTargetPlatform] returns which platform the browser is
40/// running on.
41//
42// When adding support for a new platform (e.g. Windows Phone, Raspberry Pi),
43// first create a new value on the [TargetPlatform] enum, then add a rule for
44// selecting that platform in `_platform_io.dart` and `_platform_web.dart`.
45//
46// It would be incorrect to make a platform that isn't supported by
47// [TargetPlatform] default to the behavior of another platform, because doing
48// that would mean we'd be stuck with that platform forever emulating the other,
49// and we'd never be able to introduce dedicated behavior for that platform
50// (since doing so would be a big breaking change).
51@pragma('vm:platform-const-if', !kDebugMode)
52TargetPlatform get defaultTargetPlatform => platform.defaultTargetPlatform;
53
54/// The platform that user interaction should adapt to target.
55///
56/// The [defaultTargetPlatform] getter returns the current platform.
57///
58/// When using the "flutter run" command, the "o" key will toggle between
59/// values of this enum when updating [debugDefaultTargetPlatformOverride].
60/// This lets one test how the application will work on various platforms
61/// without having to switch emulators or physical devices.
62//
63// When you add values here, make sure to also add them to
64// nextPlatform() in flutter_tools/lib/src/resident_runner.dart so that
65// the tool can support the new platform for its "o" option.
66enum TargetPlatform {
67 /// Android: <https://www.android.com/>
68 android,
69
70 /// Fuchsia: <https://fuchsia.dev/fuchsia-src/concepts>
71 fuchsia,
72
73 /// iOS: <https://www.apple.com/ios/>
74 iOS,
75
76 /// Linux: <https://www.linux.org>
77 linux,
78
79 /// macOS: <https://www.apple.com/macos>
80 macOS,
81
82 /// Windows: <https://www.windows.com>
83 windows,
84}
85
86/// Override the [defaultTargetPlatform] in debug builds.
87///
88/// Setting this to null returns the [defaultTargetPlatform] to its original
89/// value (based on the actual current platform).
90///
91/// Generally speaking this override is only useful for tests. To change the
92/// platform that widgets resemble, consider using the platform override APIs
93/// (such as [ThemeData.platform] in the material library) instead.
94///
95/// Setting [debugDefaultTargetPlatformOverride] (as opposed to, say,
96/// [ThemeData.platform]) will cause unexpected and undesirable effects. For
97/// example, setting this to [TargetPlatform.iOS] when the application is
98/// running on Android will cause the TalkBack accessibility tool on Android to
99/// be confused because it would be receiving data intended for iOS VoiceOver.
100/// Similarly, setting it to [TargetPlatform.android] while on iOS will cause
101/// certainly widgets to work assuming the presence of a system-wide back
102/// button, which will make those widgets unusable since iOS has no such button.
103///
104/// Attempting to override this property in non-debug builds causes an error.
105TargetPlatform? get debugDefaultTargetPlatformOverride =>
106 _debugDefaultTargetPlatformOverride;
107
108set debugDefaultTargetPlatformOverride(TargetPlatform? value) {
109 if (!kDebugMode) {
110 throw FlutterError(
111 'Cannot modify debugDefaultTargetPlatformOverride in non-debug builds.');
112 }
113 _debugDefaultTargetPlatformOverride = value;
114}
115
116TargetPlatform? _debugDefaultTargetPlatformOverride;
117