// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:ui';

import 'message_codecs.dart';
import 'platform_channel.dart';

export 'platform_channel.dart' show BasicMessageChannel, MethodChannel;

/// Platform channels used by the Flutter system.
class SystemChannels {
  // This class is not meant to be instantiated or extended; this constructor
  // prevents instantiation and extension.
  SystemChannels._();

  /// A JSON [MethodChannel] for navigation.
  ///
  /// The following incoming methods are defined for this channel (registered
  /// using [MethodChannel.setMethodCallHandler]):
  ///
  ///  * `popRoute`, which is called when the system wants the current route to
  ///    be removed (e.g. if the user hits a system-level back button).
  ///
  ///  * `pushRoute`, which is called with a single string argument when the
  ///    operating system instructs the application to open a particular page.
  ///
  ///  * `pushRouteInformation`, which is called with a map, which contains a
  ///    location string and a state object, when the operating system instructs
  ///    the application to open a particular page. These parameters are stored
  ///    under the key `location` and `state` in the map.
  ///
  /// The following methods are used for the opposite direction data flow. The
  /// framework notifies the engine about the route changes.
  ///
  ///  * `selectSingleEntryHistory`, which enables a single-entry history mode.
  ///
  ///  * `selectMultiEntryHistory`, which enables a multiple-entry history mode.
  ///
  ///  * `routeInformationUpdated`, which is called when the application
  ///    navigates to a new location, and which takes two arguments, `location`
  ///    (a URL) and `state` (an object).
  ///
  ///  * `routeUpdated`, a deprecated API which can be called in the same
  ///    situations as `routeInformationUpdated` but whose arguments are
  ///    `routeName` (a URL) and `previousRouteName` (which is ignored).
  ///
  /// These APIs are exposed by the [SystemNavigator] class.
  ///
  /// See also:
  ///
  ///  * [WidgetsBindingObserver.didPopRoute] and
  ///    [WidgetsBindingObserver.didPushRoute], which expose this channel's
  ///    methods.
  ///  * [Navigator] which manages transitions from one page to another.
  ///    [Navigator.push], [Navigator.pushReplacement], [Navigator.pop] and
  ///    [Navigator.replace], utilize this channel's methods to send route
  ///    change information from framework to engine.
  static const MethodChannel navigation = OptionalMethodChannel(
      'flutter/navigation',
      JSONMethodCodec(),
  );

  /// A JSON [MethodChannel] for invoking miscellaneous platform methods.
  ///
  /// The following outgoing methods are defined for this channel (invoked using
  /// [OptionalMethodChannel.invokeMethod]):
  ///
  ///  * `Clipboard.setData`: Places the data from the `text` entry of the
  ///    argument, which must be a [Map], onto the system clipboard. See
  ///    [Clipboard.setData].
  ///
  ///  * `Clipboard.getData`: Returns the data that has the format specified in
  ///    the argument, a [String], from the system clipboard. The only format
  ///    currently supported is `text/plain` ([Clipboard.kTextPlain]). The
  ///    result is a [Map] with a single key, `text`. See [Clipboard.getData].
  ///
  ///  * `HapticFeedback.vibrate`: Triggers a system-default haptic response.
  ///    See [HapticFeedback.vibrate].
  ///
  ///  * `SystemSound.play`: Triggers a system audio effect. The argument must
  ///    be a [String] describing the desired effect; currently only `click` is
  ///    supported. See [SystemSound.play].
  ///
  ///  * `SystemChrome.setPreferredOrientations`: Informs the operating system
  ///    of the desired orientation of the display. The argument is a [List] of
  ///    values which are string representations of values of the
  ///    [DeviceOrientation] enum. See [SystemChrome.setPreferredOrientations].
  ///
  ///  * `SystemChrome.setApplicationSwitcherDescription`: Informs the operating
  ///    system of the desired label and color to be used to describe the
  ///    application in any system-level application lists (e.g. application
  ///    switchers). The argument is a [Map] with two keys, `label` giving a
  ///    [String] description, and `primaryColor` giving a 32 bit integer value
  ///    (the lower eight bits being the blue channel, the next eight bits being
  ///    the green channel, the next eight bits being the red channel, and the
  ///    high eight bits being set, as from [Color.value] for an opaque color).
  ///    The `primaryColor` can also be zero to indicate that the system default
  ///    should be used. See [SystemChrome.setApplicationSwitcherDescription].
  ///
  ///  * `SystemChrome.setEnabledSystemUIOverlays`: Specifies the set of system
  ///    overlays to have visible when the application is running. The argument
  ///    is a [List] of values which are string representations of values of the
  ///    [SystemUiOverlay] enum. See [SystemChrome.setEnabledSystemUIMode].
  ///    [SystemUiOverlay]s can only be configured individually when using
  ///    [SystemUiMode.manual].
  ///
  ///  * `SystemChrome.setEnabledSystemUIMode`: Specifies the [SystemUiMode] for
  ///    the application. The optional `overlays` argument is a [List] of values
  ///    which are string representations of values of the [SystemUiOverlay]
  ///    enum when using [SystemUiMode.manual]. See
  ///    [SystemChrome.setEnabledSystemUIMode].
  ///
  ///  * `SystemChrome.setSystemUIOverlayStyle`: Specifies whether system
  ///    overlays (e.g. the status bar on Android or iOS) should be `light` or
  ///    `dark`. The argument is one of those two strings. See
  ///    [SystemChrome.setSystemUIOverlayStyle].
  ///
  ///  * `SystemNavigator.pop`: Tells the operating system to close the
  ///    application, or the closest equivalent. See [SystemNavigator.pop].
  ///
  /// The following incoming methods are defined for this channel (registered
  /// using [MethodChannel.setMethodCallHandler]):
  ///
  ///  * `SystemChrome.systemUIChange`: The user has changed the visibility of
  ///    the system overlays. This is relevant when using [SystemUiMode]s
  ///    through [SystemChrome.setEnabledSystemUIMode]. See
  ///    [SystemChrome.setSystemUIChangeCallback] to respond to this change in
  ///    application state.
  ///
  /// Calls to methods that are not implemented on the shell side are ignored
  /// (so it is safe to call methods when the relevant plugin might be missing).
  static const MethodChannel platform = OptionalMethodChannel(
      'flutter/platform',
      JSONMethodCodec(),
  );

  /// A JSON [MethodChannel] for handling text input.
  ///
  /// This channel exposes a system text input control for interacting with IMEs
  /// (input method editors, for example on-screen keyboards). There is one
  /// control, and at any time it can have one active transaction. Transactions
  /// are represented by an integer. New Transactions are started by
  /// `TextInput.setClient`. Messages that are sent are assumed to be for the
  /// current transaction (the last "client" set by `TextInput.setClient`).
  /// Messages received from the shell side specify the transaction to which
  /// they apply, so that stale messages referencing past transactions can be
  /// ignored.
  ///
  /// In debug builds, messages sent with a client ID of -1 are always accepted.
  /// This allows tests to smuggle messages without having to mock the engine's
  /// text handling (for example, allowing the engine to still handle the text
  /// input messages in an integration test).
  ///
  /// The methods described below are wrapped in a more convenient form by the
  /// [TextInput] and [TextInputConnection] class.
  ///
  /// The following outgoing methods are defined for this channel (invoked using
  /// [OptionalMethodChannel.invokeMethod]):
  ///
  ///  * `TextInput.setClient`: Establishes a new transaction. The arguments is
  ///    a [List] whose first value is an integer representing a previously
  ///    unused transaction identifier, and the second is a [String] with a
  ///    JSON-encoded object with five keys, as obtained from
  ///    [TextInputConfiguration.toJson]. This method must be invoked before any
  ///    others (except `TextInput.hide`). See [TextInput.attach].
  ///
  ///  * `TextInput.show`: Show the keyboard. See [TextInputConnection.show].
  ///
  ///  * `TextInput.setEditingState`: Update the value in the text editing
  ///    control. The argument is a [String] with a JSON-encoded object with
  ///    seven keys, as obtained from [TextEditingValue.toJSON]. See
  ///    [TextInputConnection.setEditingState].
  ///
  ///  * `TextInput.clearClient`: End the current transaction. The next method
  ///    called must be `TextInput.setClient` (or `TextInput.hide`). See
  ///    [TextInputConnection.close].
  ///
  ///  * `TextInput.hide`: Hide the keyboard. Unlike the other methods, this can
  ///    be called at any time. See [TextInputConnection.close].
  ///
  /// The following incoming methods are defined for this channel (registered
  /// using [MethodChannel.setMethodCallHandler]). In each case, the first argument
  /// is a transaction identifier. Calls for stale transactions should be ignored.
  ///
  ///  * `TextInputClient.updateEditingState`: The user has changed the contents
  ///    of the text control. The second argument is an object with seven keys,
  ///    in the form expected by [TextEditingValue.fromJSON].
  ///
  ///  * `TextInputClient.updateEditingStateWithTag`: One or more text controls
  ///    were autofilled by the platform's autofill service. The first argument
  ///    (the client ID) is ignored, the second argument is a map of tags to
  ///    objects in the form expected by [TextEditingValue.fromJSON]. See
  ///    [AutofillScope.getAutofillClient] for details on the interpretation of
  ///    the tag.
  ///
  ///  * `TextInputClient.performAction`: The user has triggered an action. The
  ///    second argument is a [String] consisting of the stringification of one
  ///    of the values of the [TextInputAction] enum.
  ///
  ///  * `TextInputClient.requestExistingInputState`: The embedding may have
  ///    lost its internal state about the current editing client, if there is
  ///    one. The framework should call `TextInput.setClient` and
  ///    `TextInput.setEditingState` again with its most recent information. If
  ///    there is no existing state on the framework side, the call should
  ///    fizzle. (This call is made without a client ID; indeed, without any
  ///    arguments at all.)
  ///
  ///  * `TextInputClient.onConnectionClosed`: The text input connection closed
  ///    on the platform side. For example the application is moved to
  ///    background or used closed the virtual keyboard. This method informs
  ///    [TextInputClient] to clear connection and finalize editing.
  ///    `TextInput.clearClient` and `TextInput.hide` is not called after
  ///    clearing the connection since on the platform side the connection is
  ///    already finalized.
  ///
  /// Calls to methods that are not implemented on the shell side are ignored
  /// (so it is safe to call methods when the relevant plugin might be missing).
  static const MethodChannel textInput = OptionalMethodChannel(
      'flutter/textinput',
      JSONMethodCodec(),
  );

  /// A JSON [BasicMessageChannel] for keyboard events.
  ///
  /// Each incoming message received on this channel (registered using
  /// [BasicMessageChannel.setMessageHandler]) consists of a [Map] with
  /// platform-specific data, plus a `type` field which is either `keydown`, or
  /// `keyup`.
  ///
  /// On Android, the available fields are those described by
  /// [RawKeyEventDataAndroid]'s properties.
  ///
  /// On Fuchsia, the available fields are those described by
  /// [RawKeyEventDataFuchsia]'s properties.
  ///
  /// No messages are sent on other platforms currently.
  ///
  /// See also:
  ///
  ///  * [RawKeyboard], which uses this channel to expose key data.
  ///  * [RawKeyEvent.fromMessage], which can decode this data into the [RawKeyEvent]
  ///    subclasses mentioned above.
  static const BasicMessageChannel<Object?> keyEvent = BasicMessageChannel<Object?>(
      'flutter/keyevent',
      JSONMessageCodec(),
  );

  /// A string [BasicMessageChannel] for lifecycle events.
  ///
  /// Valid messages are string representations of the values of the
  /// [AppLifecycleState] enumeration. A handler can be registered using
  /// [BasicMessageChannel.setMessageHandler].
  ///
  /// See also:
  ///
  ///  * [WidgetsBindingObserver.didChangeAppLifecycleState], which triggers
  ///    whenever a message is received on this channel.
  static const BasicMessageChannel<String?> lifecycle = BasicMessageChannel<String?>(
      'flutter/lifecycle',
      StringCodec(),
  );

  /// A JSON [BasicMessageChannel] for system events.
  ///
  /// Events are exposed as [Map]s with string keys. The `type` key specifies
  /// the type of the event; the currently supported system event types are
  /// those listed below. A handler can be registered using
  /// [BasicMessageChannel.setMessageHandler].
  ///
  ///  * `memoryPressure`: Indicates that the operating system would like
  ///    applications to release caches to free up more memory. See
  ///    [WidgetsBindingObserver.didHaveMemoryPressure], which triggers whenever
  ///    a message is received on this channel.
  static const BasicMessageChannel<Object?> system = BasicMessageChannel<Object?>(
      'flutter/system',
      JSONMessageCodec(),
  );

  /// A [BasicMessageChannel] for accessibility events.
  ///
  /// See also:
  ///
  ///  * [SemanticsEvent] and its subclasses for a list of valid accessibility
  ///    events that can be sent over this channel.
  ///  * [SemanticsNode.sendEvent], which uses this channel to dispatch events.
  static const BasicMessageChannel<Object?> accessibility = BasicMessageChannel<Object?>(
    'flutter/accessibility',
    StandardMessageCodec(),
  );

  /// A [MethodChannel] for controlling platform views.
  ///
  /// See also:
  ///
  ///  * [PlatformViewsService] for the available operations on this channel.
  static const MethodChannel platform_views = MethodChannel(
    'flutter/platform_views',
  );

  /// A [MethodChannel] for configuring the Skia graphics library.
  ///
  /// The following outgoing methods are defined for this channel (invoked using
  /// [OptionalMethodChannel.invokeMethod]):
  ///
  ///  * `Skia.setResourceCacheMaxBytes`: Set the maximum number of bytes that
  ///    can be held in the GPU resource cache.
  static const MethodChannel skia = MethodChannel(
    'flutter/skia',
    JSONMethodCodec(),
  );

  /// A [MethodChannel] for configuring mouse cursors.
  ///
  /// All outgoing methods defined for this channel uses a `Map<String, Object?>`
  /// to contain multiple parameters, including the following methods (invoked
  /// using [OptionalMethodChannel.invokeMethod]):
  ///
  ///  * `activateSystemCursor`: Request to set the cursor of a pointer
  ///    device to a system cursor. The parameters are
  ///    integer `device`, and string `kind`.
  static const MethodChannel mouseCursor = OptionalMethodChannel(
    'flutter/mousecursor',
  );

  /// A [MethodChannel] for synchronizing restoration data with the engine.
  ///
  /// The following outgoing methods are defined for this channel (invoked using
  /// [OptionalMethodChannel.invokeMethod]):
  ///
  ///  * `get`: Retrieves the current restoration information (e.g. provided by
  ///    the operating system) from the engine. The method returns a map
  ///    containing an `enabled` boolean to indicate whether collecting
  ///    restoration data is supported by the embedder. If `enabled` is true,
  ///    the map may also contain restoration data stored under the `data` key
  ///    from which the state of the framework may be restored. The restoration
  ///    data is encoded as [Uint8List].
  ///  * `put`: Sends the current restoration data to the engine. Takes the
  ///    restoration data encoded as [Uint8List] as argument.
  ///
  /// The following incoming methods are defined for this channel (registered
  /// using [MethodChannel.setMethodCallHandler]).
  ///
  ///  * `push`: Called by the engine to send newly provided restoration
  ///    information to the framework. The argument given to this method has
  ///    the same format as the object that the `get` method returns.
  ///
  /// See also:
  ///
  ///  * [RestorationManager], which uses this channel and also describes how
  ///    restoration data is used in Flutter.
  static const MethodChannel restoration = OptionalMethodChannel(
    'flutter/restoration',
  );

  /// A [MethodChannel] for installing and managing deferred components.
  ///
  /// The following outgoing methods are defined for this channel (invoked using
  /// [OptionalMethodChannel.invokeMethod]):
  ///
  ///  * `installDeferredComponent`: Requests that a deferred component identified by
  ///    the provided loadingUnitId or componentName be downloaded and installed.
  ///    Providing a loadingUnitId with null componentName will install a component that
  ///    includes the desired loading unit. If a componentName is provided, then the
  ///    deferred component with the componentName will be installed. This method
  ///    returns a future that will not be completed until the feature is fully installed
  ///    and ready to use. When an error occurs, the future will complete an error.
  ///    Calling `loadLibrary()` on a deferred imported library is equivalent to calling
  ///    this method with a loadingUnitId and null componentName.
  ///  * `uninstallDeferredComponent`:  Requests that a deferred component identified by
  ///    the provided loadingUnitId or componentName be uninstalled. Since
  ///    uninstallation typically requires significant disk i/o, this method only
  ///    signals the intent to uninstall. Actual uninstallation (eg, removal of
  ///    assets and files) may occur at a later time. However, once uninstallation
  ///    is requested, the deferred component should not be used anymore until
  ///    `installDeferredComponent` or `loadLibrary` is called again.
  static const MethodChannel deferredComponent = OptionalMethodChannel(
    'flutter/deferredcomponent',
  );

  /// A JSON [MethodChannel] for localization.
  ///
  /// The following outgoing methods are defined for this channel (invoked using
  /// [OptionalMethodChannel.invokeMethod]):
  ///
  ///  * `Localization.getStringResource`: Obtains the native string resource
  ///    for a specific locale. The argument is a [Map] with two keys, `key`
  ///    giving a [String] which the resource is defined with, and an optional
  ///    `locale` which is a [String] containing the BCP47 locale identifier of
  ///    the locale requested. See [Locale.toLanguageTag]. When `locale` is not
  ///    specified, the current system locale is used instead.
  static const MethodChannel localization = OptionalMethodChannel(
    'flutter/localization',
    JSONMethodCodec(),
  );

  /// A [MethodChannel] for platform menu specification and control.
  ///
  /// The following outgoing method is defined for this channel (invoked using
  /// [OptionalMethodChannel.invokeMethod]):
  ///
  ///  * `Menu.setMenus`: sends the configuration of the platform menu, including
  ///    labels, enable/disable information, and unique integer identifiers for
  ///    each menu item. The configuration is sent as a `Map<String, Object?>`
  ///    encoding the list of top level menu items in window "0", which each
  ///    have a hierarchy of `Map<String, Object?>` containing the required
  ///    data, sent via a [StandardMessageCodec]. It is typically generated from
  ///    a list of [MenuItem]s, and ends up looking like this example:
  ///
  /// ```dart
  /// List<Map<String, Object?>> menu = <String, Object?>{
  ///   '0': <Map<String, Object?>>[
  ///     <String, Object?>{
  ///       'id': 1,
  ///       'label': 'First Menu Label',
  ///       'enabled': true,
  ///       'children': <Map<String, Object?>>[
  ///         <String, Object?>{
  ///           'id': 2,
  ///           'label': 'Sub Menu Label',
  ///           'enabled': true,
  ///         },
  ///       ],
  ///     },
  ///   ],
  /// };
  /// ```
  ///
  /// The following incoming methods are defined for this channel (registered
  /// using [MethodChannel.setMethodCallHandler]).
  ///
  ///  * `Menu.selectedCallback`: Called when a menu item is selected, along
  ///    with the unique ID of the menu item selected.
  ///
  ///  * `Menu.opened`: Called when a submenu is opened, along with the unique
  ///    ID of the submenu.
  ///
  ///  * `Menu.closed`: Called when a submenu is closed, along with the unique
  ///    ID of the submenu.
  ///
  /// See also:
  ///
  ///  * [DefaultPlatformMenuDelegate], which uses this channel.
  static const MethodChannel menu = OptionalMethodChannel('flutter/menu');
}
