// Copyright 2017 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.

module ash.mojom;

import "ash/public/interfaces/user_info.mojom";
import "ash/public/interfaces/login_user_info.mojom";
import "ash/public/interfaces/kiosk_app_info.mojom";
import "chromeos/components/proximity_auth/public/interfaces/auth_type.mojom";
import "components/account_id/interfaces/account_id.mojom";
import "mojo/public/mojom/base/string16.mojom";
import "mojo/public/mojom/base/time.mojom";

// State of the Oobe UI dialog, which is used to update the visibility of login
// shelf buttons.
// This comes from SIGNIN_UI_STATE defined in display_manager.js, with an
// additional value HIDDEN to indicate the visibility of the oobe ui dialog.
enum OobeDialogState {
  // Showing other screen, which does not impact the visibility of login shelf
  // buttons.
  NONE = 0,

  // Showing gaia signin screen.
  GAIA_SIGNIN = 1,

  // 2 is unused to keep in sync with display_manager.js

  // Showing wrong hardware identification screen.
  WRONG_HWID_WARNING = 3,

  // Showing supervised user creation screen.
  SUPERVISED_USER_CREATION_FLOW = 4,

  // Showing SAML password confirmation screen.
  SAML_PASSWORD_CONFIRM = 5,

  // Showing password changed screen.
  PASSWORD_CHANGED = 6,

  // Showing device enrollment screen.
  ENROLLMENT = 7,

  // Showing error screen.
  ERROR = 8,

  // Showing sync consent screen.
  SYNC_CONSENT = 9,

  // Oobe UI dialog is currently hidden.
  HIDDEN = 10,
};

// Reason why the auth is disabled. This is used to personalize the UI.
enum AuthDisabledReason {
  // Auth is disabled because the device is locked by a time limit override.
  TIME_LIMIT_OVERRIDE,

  // Auth is disabled because the user has reached their daily usage limit on
  // the device.
  TIME_USAGE_LIMIT,

  // Auth is disabled because the device is within a locked time window.
  TIME_WINDOW_LIMIT,
};

// The data needed to customize the lock screen when auth is disabled.
struct AuthDisabledData {
  // Reason why auth is disabled.
  AuthDisabledReason reason;

  // A future time when auth will be enabled. This value is for display purpose
  // only, auth won't be automatically enabled when this time is reached.
  mojo_base.mojom.Time auth_reenabled_time;

  // The amount of time that the user used this device.
  mojo_base.mojom.TimeDelta device_used_time;
};

// Allows clients (e.g. the browser process) to send messages to the ash
// login/lock/user-add screens.
interface LoginScreen {
  // Sets the client interface.
  SetClient(LoginScreenClient client);

  // Displays the lock screen. |did_show| is true iff the lock UI was
  // successfully displayed.
  ShowLockScreen() => (bool did_show);

  // Displays the login screen. |did_show| is true iff the login UI was
  // successfully displayed.
  ShowLoginScreen() => (bool did_show);

  // Requests to show error message in the ash lock screen.
  // TODO(xiaoyinh): login_attempts is probably not needed from chrome,
  // remove it when we start to count the login attempts in ash lock screen.
  // |login_attempts|: The number of the login authentication attempts.
  // |error_text|:     The error text to be shown in lock screen.
  // |help_link_text|: The help link to be shown in lock screen.
  // |help_topic_id|:  The id of the help app topic regarding this error.
  ShowErrorMessage(int32 login_attempts,
                   string error_text,
                   string help_link_text,
                   int32 help_topic_id);

  // Shows a warning banner message on the login screen. A warning banner is
  // used to notify users of important messages before they log in to their
  // session. (e.g. Tell the user that an update of the user data will start
  // on login)
  // |message|: The message to show.
  ShowWarningBanner(mojo_base.mojom.String16 message);

  // Hide a warning banner if it is displayed.
  // TODO(fukino): Ideally chrome-side should not have this level of UI
  // control. Make the API simpler and let ash determine the UI behavior.
  HideWarningBanner();

  // Requests to close any displayed error messages in ash lock screen.
  ClearErrors();

  // Requests to show the custom icon in the user pod.
  // |account_id|:  The account id of the user in the user pod.
  // |icon|:        Information regarding the icon.
  ShowUserPodCustomIcon(signin.mojom.AccountId account_id,
                        EasyUnlockIconOptions icon);

  // Requests to hide the custom icon in the user pod.
  // |account_id|:  The account id of the user in the user pod.
  HideUserPodCustomIcon(signin.mojom.AccountId account_id);

  // Requests to set the authentication type.
  // |account_id|:    The account id of the user in the user pod.
  // |auth_type|:     Authentication type.
  // |initial_value|: A message shown in the password field of the user pod.
  SetAuthType(signin.mojom.AccountId account_id,
              proximity_auth.mojom.AuthType auth_type,
              mojo_base.mojom.String16 initial_value);

  // Set the users who are displayed on the login UI. |users| is filtered
  // and does not correspond to every user on the device.
  SetUserList(array<LoginUserInfo> users);

  // Notification if pin is enabled or disabled for the given user.
  // |account_id|:   The account id of the user in the user pod.
  // |is_enabled|:   True if pin unlock is enabled.
  SetPinEnabledForUser(signin.mojom.AccountId account_id, bool is_enabled);

  // Update the status of fingerprint for |account_id|.
  SetFingerprintState(signin.mojom.AccountId account_id,
                      FingerprintState state);

  // Called after a fingerprint authentication attempt has been made. If
  // |successful| is true, then the fingerprint authentication attempt was
  // successful and the device should be unlocked. If false, an error message
  // should be shown to the user.
  NotifyFingerprintAuthResult(signin.mojom.AccountId account_id,
                              bool successful);

  // Change the user's avatar. Some avatars may take a long time to load and the
  // login screen may already be visible.
  SetAvatarForUser(signin.mojom.AccountId account_id, UserAvatar avatar);

  // Called when auth should be enabled for the given user. When auth is
  // disabled, the user cannot unlock the device. Auth is enabled by default.
  // |account_id|:            The account id of the user in the user pod.
  EnableAuthForUser(signin.mojom.AccountId account_id);

  // Called when auth should be disabled for the given user. When auth is
  // disabled, the user cannot unlock the device. Auth is enabled by default.
  // |account_id|:            The account id of the user in the user pod.
  // |auth_disabled_data|:    The data needed to customize the lock screen UI.
  DisableAuthForUser(signin.mojom.AccountId account_id,
                      AuthDisabledData auth_disabled_data);

  // Called when focus is reported to be leaving a lock screen app window.
  // Requests focus to be handed off to the next suitable widget.
  // |reverse|:   Whether the tab order is reversed.
  HandleFocusLeavingLockScreenApps(bool reverse);

  // Called when new system information is available.
  // |show_if_hidden|: If true, the system information should be displayed to
  //                   the user if it is currently hidden. If false, the system
  //                   information should remain hidden if not already shown.
  //                   Hidden system information can be shown by pressing alt-v.
  // |os_version_label_text|: The OS version.
  // |enterprise_info_text|:  The enterprise info.
  // |bluetooth_name|:        The name of the bluetooth adapter.
  SetSystemInfo(bool show_if_hidden,
                string os_version_label_text,
                string enterprise_info_text,
                string bluetooth_name);

  // Check if the login/lock screen is ready for a password.
  IsReadyForPassword() => (bool is_ready);

  // Set the public session display name for user with |account_id|.
  SetPublicSessionDisplayName(signin.mojom.AccountId account_id,
                              string display_name);

  // Set the public session locales for user with |account_id|.
  // |locales|:            Available locales for this user.
  // |default_locale|:     Default locale for this user.
  // |show_advanced_view|: True if we should show the advanced expanded user
  //                       view for the public session.
  SetPublicSessionLocales(signin.mojom.AccountId account_id,
                          array<LocaleItem> locales,
                          string default_locale,
                          bool show_advanced_view);

  // Set the public session keyboard layouts for user with |account_id|.
  // |locale|: The locale that |keyboard_layouts| can be used for.
  SetPublicSessionKeyboardLayouts(signin.mojom.AccountId account_id,
                                  string locale,
                                  array<InputMethodItem> keyboard_layouts);

  // Sets whether full management disclosure is needed for the public/managed
  // session login screen.
  SetPublicSessionShowFullManagementDisclosure(
      bool show_full_management_disclosure);

  // Update the kiosk app data for the login screen.
  // Returns true on success.
  SetKioskApps(array<KioskAppInfo> kiosk_apps) => (bool success);

  // Display a toast describing the latest kiosk app launch error.
  ShowKioskAppError(string message);

  // Called when the dialog hosting oobe has changed state. The oobe dialog
  // provides support for any part of login that is implemented in JS/HTML, such
  // as add user or powerwash.
  NotifyOobeDialogState(OobeDialogState state);

  // Sets whether users can be added from the login screen.
  SetAddUserButtonEnabled(bool enable);

  // Sets whether shutdown button is enabled in the login screen.
  SetShutdownButtonEnabled(bool enable);

  // Sets if the guest button on the login shelf can be shown. Even if set to
  // true the button may still not be visible.
  SetAllowLoginAsGuest(bool allow_guest);

  // Sets if the guest button on the login shelf can be shown during OOBE.
  SetShowGuestButtonInOobe(bool show);

  // Sets whether parent access button can be shown on the login shelf.
  SetShowParentAccessButton(bool show);

  // Sets whether parent access code input dialog is shown on the lock screen.
  SetShowParentAccessDialog(bool show);

  // Transitions focus to the shelf area. If |reverse|, focuses the status area.
  FocusLoginShelf(bool reverse);
};

// Allows ash lock screen to control a client (e.g. Chrome browser). Requests
// often involve preferences or talk to cryptohome that is not available to ash.
interface LoginScreenClient {
  // Attempt to authenticate a user with a password or PIN.
  //
  // If auth succeeds:
  // chrome will hide the lock screen and clear any displayed error messages.
  // If auth fails:
  // chrome will request lock screen to show error messages.
  // |account_id|: The AccountId to authenticate against.
  // |password|: The submitted password.
  // |authenticated_by_pin|: True if we are using pin to authenticate.
  //
  // The result will be set to true if auth was successful, false if not.
  //
  // TODO(jdufault): Extract authenticated_by_pin into a separate mojom method,
  //                 similar to the other Authenticate* methods
  AuthenticateUserWithPasswordOrPin(
      signin.mojom.AccountId account_id,
      string password,
      bool authenticated_by_pin) => (bool auth_success);

  // Attempt to authenticate the user with with an external binary.
  AuthenticateUserWithExternalBinary(signin.mojom.AccountId account_id)
      => (bool auth_success);

  // Attempt to enroll a user in the external binary authentication system.
  EnrollUserWithExternalBinary() => (bool enrollment_success);

  // Try to authenticate |account_id| using easy unlock. This can be used on the
  // login or lock screen.
  // |account_id|: The account id of the user we are authenticating.
  //
  // TODO(jdufault): Refactor this method to return an auth_success, similar to
  // the other auth methods above.
  AuthenticateUserWithEasyUnlock(signin.mojom.AccountId account_id);

  // Validates parent access code for the user identified by |account_id|.
  // Passes validation result in the callback.
  // Note: This should only be used for child user.
  ValidateParentAccessCode(
    signin.mojom.AccountId account_id,
    string access_code) => (bool access_code_valid);

  // Request to hard lock the user pod.
  // |account_id|:    The account id of the user in the user pod.
  HardlockPod(signin.mojom.AccountId account_id);

  // Focus user pod of user with |account_id|.
  OnFocusPod(signin.mojom.AccountId account_id);

  // Notify that no user pod is focused.
  OnNoPodFocused();

  // Load wallpaper of user with |account_id|.
  LoadWallpaper(signin.mojom.AccountId account_id);

  // Sign out current user.
  SignOutUser();

  // Close add user screen.
  CancelAddUser();

  // Launches guest mode.
  LoginAsGuest();

  // User with |account_id| has reached maximum incorrect password attempts.
  OnMaxIncorrectPasswordAttempted(signin.mojom.AccountId account_id);

  // Should pass the focus to the active lock screen app window, if there is
  // one. This is called when a lock screen app is reported to be active (using
  // tray_action mojo interface), and is next in the tab order.
  // |HandleFocusLeavingLockScreenApps| should be called to return focus to the
  // lock screen.
  // |reverse|:   Whether the tab order is reversed.
  FocusLockScreenApps(bool reverse);

  // Passes focus to the OOBE dialog if it is showing. No-op otherwise.
  FocusOobeDialog();

  // Show the gaia sign-in dialog. If |can_close| is true, the dialog can be
  // closed. The value in |prefilled_account| will be used to prefill the
  // sign-in dialog so the user does not need to type the account email.
  ShowGaiaSignin(bool can_close, signin.mojom.AccountId? prefilled_account);

  // Notification that the remove user warning was shown.
  OnRemoveUserWarningShown();

  // Try to remove |account_id|.
  RemoveUser(signin.mojom.AccountId account_id);

  // Launch a public session for user with |account_id|.
  // |locale|:       Locale for this user.
  //                 The value is language code like "en-US", "zh-CN"
  // |input_method|: Input method for this user.
  //                 This is the id of InputMethodDescriptor like
  //                 "t:latn-post", "pinyin".
  LaunchPublicSession(signin.mojom.AccountId account_id,
                      string locale,
                      string input_method);

  // Request public session keyboard layouts for user with |account_id|.
  // This function send a request to chrome and the result will be returned by
  // SetPublicSessionKeyboardLayouts.
  // |locale|: Request a list of keyboard layouts that can be used by this
  //           locale.
  RequestPublicSessionKeyboardLayouts(signin.mojom.AccountId account_id,
                                      string locale);

  // Request to show a feedback report dialog in chrome.
  ShowFeedback();

  // Launch the specific kiosk app.
  LaunchKioskApp(string app_id);

  // Launch the specific ARC++ kiosk app.
  LaunchArcKioskApp(signin.mojom.AccountId account_id);

  // Show the powerwash (device reset) dialog.
  ShowResetScreen();

  // Show the help app for when users have trouble signing in to their account.
  ShowAccountAccessHelpApp();

  // Called when the keyboard focus is about to leave from the sytem tray in
  // the login screen / OOBE. |reverse| is true when the focus moves in the
  // reversed direction.
  OnFocusLeavingSystemTray(bool reverse);

  // Used by Ash to signal that user activity occurred on the login screen.
  OnUserActivity();
};
