platform.dart 3.98 KB
Newer Older
1 2 3 4
// Copyright 2016 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.

5 6 7 8
import 'dart:io' show Platform;

import 'assertions.dart';

9
/// The platform that user interaction should adapt to target.
10 11
///
/// The [defaultTargetPlatform] getter returns the current platform.
12 13 14 15
enum TargetPlatform {
  /// Android: <https://www.android.com/>
  android,

16 17 18
  /// Fuchsia: <https://fuchsia.googlesource.com/>
  fuchsia,

19 20 21
  /// iOS: <http://www.apple.com/ios/>
  iOS,
}
22

23 24 25
/// The [TargetPlatform] that matches the platform on which the framework is
/// currently executing.
///
26 27 28 29 30 31 32 33
/// This is the default value of [ThemeData.platform] (hence the name). Widgets
/// from the material library should use [Theme.of] to determine the current
/// platform, rather than using [defaultTargetPlatform]. However, if there is
/// widget behavior that depends on the actual underlying platform (e.g. because
/// it is controlling data being sent to the platform APIs, not just trying to
/// follow the platform's conventions) then depending on [defaultTargetPlatform]
/// makes sense.
///
34 35 36 37
/// In a test environment, the platform returned is [TargetPlatform.android]
/// regardless of the host platform. (Android was chosen because the tests were
/// originally written assuming Android-like behavior, and we added platform
/// adaptations for iOS later). Tests can check iOS behavior by using the
38
/// platform override APIs (such as [ThemeData.platform] in the material
39 40 41 42 43 44 45 46 47 48 49
/// library) or by setting [debugDefaultTargetPlatformOverride].
//
// When adding support for a new platform (e.g. Windows Phone, macOS), first
// create a new value on the [TargetPlatform] enum, then add a rule for
// selecting that platform here.
//
// It would be incorrect to make a platform that isn't supported by
// [TargetPlatform] default to the behavior of another platform, because doing
// that would mean we'd be stuck with that platform forever emulating the other,
// and we'd never be able to introduce dedicated behavior for that platform
// (since doing so would be a big breaking change).
50
TargetPlatform get defaultTargetPlatform {
51
  TargetPlatform result;
52
  if (Platform.isIOS) {
53
    result = TargetPlatform.iOS;
54
  } else if (Platform.isAndroid) {
55
    result = TargetPlatform.android;
56
  } else if (Platform.isFuchsia) {
57
    result = TargetPlatform.fuchsia;
58 59 60 61 62
  }
  assert(() {
    if (Platform.environment.containsKey('FLUTTER_TEST'))
      result = TargetPlatform.android;
    return true;
63
  }());
64 65
  if (debugDefaultTargetPlatformOverride != null)
    result = debugDefaultTargetPlatformOverride;
66 67 68 69 70 71 72 73
  if (result == null) {
    throw new FlutterError(
      'Unknown platform.\n'
      '${Platform.operatingSystem} was not recognized as a target platform. '
      'Consider updating the list of TargetPlatforms to include this platform.'
    );
  }
  return result;
74
}
75

76 77 78 79 80
/// Override the [defaultTargetPlatform].
///
/// Setting this to null returns the [defaultTargetPlatform] to its original
/// value (based on the actual current platform).
///
81 82 83 84 85 86 87 88 89 90 91 92 93 94
/// Generally speaking this override is only useful for tests. To change the
/// platform that widgets resemble, consider using the platform override APIs
/// (such as [ThemeData.platform] in the material library) instead.
///
/// Setting [debugDefaultTargetPlatformOverride] (as opposed to, say,
/// [ThemeData.platform]) will cause unexpected and undesireable effects. For
/// example, setting this to [TargetPlatform.iOS] when the application is
/// running on Android will cause the TalkBack accessibility tool on Android to
/// be confused because it would be receiving data intended for iOS VoiceOver.
/// Similarly, setting it to [TargetPlatform.android] while on iOS will cause
/// certainly widgets to work assuming the presence of a system-wide back
/// button, which will make those widgets unusable since iOS has no such button.
///
/// In general, therefore, this property should not be used in release builds.
95
TargetPlatform debugDefaultTargetPlatformOverride;