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'; |
7 | library; |
8 | |
9 | import '_platform_io.dart' |
10 | if (dart.library.js_util) '_platform_web.dart' as platform; |
11 | import 'assertions.dart'; |
12 | import '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) |
52 | TargetPlatform 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. |
66 | enum 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. |
105 | TargetPlatform? get debugDefaultTargetPlatformOverride => |
106 | _debugDefaultTargetPlatformOverride; |
107 | |
108 | set debugDefaultTargetPlatformOverride(TargetPlatform? value) { |
109 | if (!kDebugMode) { |
110 | throw FlutterError( |
111 | 'Cannot modify debugDefaultTargetPlatformOverride in non-debug builds.' ); |
112 | } |
113 | _debugDefaultTargetPlatformOverride = value; |
114 | } |
115 | |
116 | TargetPlatform? _debugDefaultTargetPlatformOverride; |
117 | |