// 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';

/// 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.
  ///  * [new 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(),
  );
}
