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

module ash.mojom;

import "ash/public/interfaces/user_info.mojom";
import "components/account_id/interfaces/account_id.mojom";
import "mojo/public/mojom/base/file_path.mojom";
import "mojo/public/mojom/base/time.mojom";
import "ui/gfx/image/mojo/image.mojom";
import "url/mojom/url.mojom";

// These values match ash::WallpaperLayout.
enum WallpaperLayout {
  CENTER,
  CENTER_CROPPED,
  STRETCH,
  TILE,
};

// User info needed to set wallpapers. Clients must specify the user because
// it's not always the same with the active user, e.g., when showing wallpapers
// for different user pods at login screen, or setting wallpapers selectively
// for primary user and active user during a multi-profile session.
struct WallpaperUserInfo {
  // The user's account id.
  signin.mojom.AccountId account_id;

  // The user type. Matches user_manager::UserType.
  UserType type;

  // True if the user's non-cryptohome data (wallpaper, avatar etc.) is
  // ephemeral. See |UserManager::IsCurrentUserNonCryptohomeDataEphemeral| for
  // more details.
  bool is_ephemeral;

  // True if the user has gaia account.
  bool has_gaia_account;
};

// Used by Chrome to set the wallpaper displayed by ash.
interface WallpaperController {
  // Do the initialization: Sets the client interface, the paths of wallpaper
  // directories and the device wallpaper policy enforcement flag. The paths
  // must be sent over IPC because chrome owns the concept of user data
  // directory.
  // |client|: The client interface.
  // |user_data_path|: Directory where user data can be written.
  // |chromeos_wallpapers_path|: Directory where downloaded chromeos wallpapers
  //                             reside.
  // |chromeos_custom_wallpapers_path|: Directory where custom wallpapers
  //                                    reside.
  // |device_policy_wallpaper_path|: The file path of the device policy
  //                                 wallpaper (if any).
  Init(WallpaperControllerClient client,
       mojo_base.mojom.FilePath user_data_path,
       mojo_base.mojom.FilePath chromeos_wallpapers_path,
       mojo_base.mojom.FilePath chromeos_custom_wallpapers_path,
       mojo_base.mojom.FilePath device_policy_wallpaper_path);

  // Sets wallpaper from a local file and updates the saved wallpaper info for
  // the user.
  // |user_info|: The user's information related to wallpaper.
  // |wallpaper_files_id|: The file id for user_info.account_id.
  // |file_name|: The name of the wallpaper file.
  // |layout|: The layout of the wallpaper, used for wallpaper resizing.
  // |image|: The wallpaper image.
  // |preview_mode|: If true, show the wallpaper immediately but doesn't change
  //                 the user wallpaper info until |ConfirmPreviewWallpaper| is
  //                 called.
  SetCustomWallpaper(WallpaperUserInfo user_info,
                     string wallpaper_files_id,
                     string file_name,
                     WallpaperLayout layout,
                     gfx.mojom.ImageSkia image,
                     bool preview_mode);

  // Sets wallpaper from the Chrome OS wallpaper picker. If the wallpaper file
  // corresponding to |url| already exists in local file system (i.e.
  // |SetOnlineWallpaperFromData| was called earlier with the same |url|),
  // returns true and sets wallpaper for the user, otherwise returns false.
  // |user_info|: The user's information related to wallpaper.
  // |url|: The wallpaper url.
  // |layout|: The layout of the wallpaper, used for wallpaper resizing.
  // |preview_mode|: If true, show the wallpaper immediately but doesn't change
  //                 the user wallpaper info until |ConfirmPreviewWallpaper| is
  //                 called.
  // |file_exists|: If the wallpaper file exists in local file system.
  SetOnlineWallpaperIfExists(WallpaperUserInfo user_info,
                             string url,
                             WallpaperLayout layout,
                             bool preview_mode) => (bool file_exists);

  // Sets wallpaper from the Chrome OS wallpaper picker and saves the wallpaper
  // to local file system. After this, |SetOnlineWallpaperIfExists| will return
  // true for the same |url|, so that there's no need to provide |image_data|
  // when the same wallpaper needs to be set again or for another user.
  // |user_info|: The user's information related to wallpaper.
  // |url|: The wallpaper url.
  // |layout|: The layout of the wallpaper, used for wallpaper resizing.
  // |preview_mode|: If true, show the wallpaper immediately but doesn't change
  //                 the user wallpaper info until |ConfirmPreviewWallpaper| is
  //                 called.
  // |success|: If the wallpaper is set successfully (i.e. no decoding error
  //            etc.).
  SetOnlineWallpaperFromData(WallpaperUserInfo user_info,
                             string image_data,
                             string url,
                             WallpaperLayout layout,
                             bool preview_mode) => (bool success);

  // Sets the user's wallpaper to be the default wallpaper. Note: different user
  // types may have different default wallpapers.
  // |wallpaper_files_id|: The file id for user_info.account_id.
  // |show_wallpaper|: If false, don't show the new wallpaper now but only
  //                   update cache.
  SetDefaultWallpaper(WallpaperUserInfo user_info,
                      string wallpaper_files_id,
                      bool show_wallpaper);

  // Sets the paths of the customized default wallpaper to be used wherever a
  // default wallpaper is needed. If a default wallpaper is being shown, updates
  // the screen to replace the old default wallpaper. Note: it doesn't change
  // the default wallpaper for guest and child accounts.
  // |customized_default_small_path|: The file path of the small-size customized
  //                                  default wallpaper, if any.
  // |customized_default_large_path|: The file path of the large-size customized
  //                                  default wallpaper, if any.
  SetCustomizedDefaultWallpaperPaths(
      mojo_base.mojom.FilePath customized_default_small_path,
      mojo_base.mojom.FilePath customized_default_large_path);

  // Sets wallpaper from policy. If the user has logged in, show the policy
  // wallpaper immediately, otherwise, the policy wallpaper will be shown the
  // next time |ShowUserWallpaper| is called. Note: it is different from device
  // policy.
  // |user_info|: The user's information related to wallpaper.
  // |wallpaper_files_id|: The file id for user_info.account_id.
  // |data|: The data used to decode the image.
  SetPolicyWallpaper(WallpaperUserInfo user_info,
                     string wallpaper_files_id,
                     string data);

  // Sets the path of device policy wallpaper.
  // |device_policy_wallpaper_path|: The file path of the device policy
  //                                 wallpaper if it was set or empty value if
  //                                 it was cleared.
  SetDevicePolicyWallpaperPath(
      mojo_base.mojom.FilePath device_policy_wallpaper_path);

  // Sets wallpaper from a third-party app (as opposed to the Chrome OS
  // wallpaper picker).
  // |user_info|: The user's information related to wallpaper.
  // |wallpaper_files_id|: The file id for user_info.account_id.
  // |file_name|: The name of the wallpaper file.
  // |layout|: The layout of the wallpaper, used for wallpaper resizing.
  // |image|: The wallpaper image.
  // |allowed|: If the wallpaper is allowed to be shown on screen. It's false if
  //            1) the user is not permitted to change wallpaper, or
  //            2) updating the on-screen wallpaper is not allowed at the
  //               given moment.
  // |image_id|: A unique id assigned to the image. Clients may be interested in
  //             observing all wallpaper changes and acting differently based on
  //             if the wallpaper change is due to their own request. In order
  //             to do so, they should compare this value with the one that's
  //             returned by |OnWallpaperChanged|.
  SetThirdPartyWallpaper(WallpaperUserInfo user_info,
                         string wallpaper_files_id,
                         string file_name,
                         WallpaperLayout layout,
                         gfx.mojom.ImageSkia image)
                         => (bool allowed, uint32 image_id);

  // Confirms the wallpaper being previewed to be set as the actual user
  // wallpaper. Must be called in preview mode.
  ConfirmPreviewWallpaper();

  // Cancels the wallpaper preview and reverts to the user wallpaper. Must be
  // called in preview mode.
  CancelPreviewWallpaper();

  // Updates the layout for the user's custom wallpaper and reloads the
  // wallpaper with the new layout.
  // |user_info|: The user's information related to wallpaper.
  // |layout|: The new layout of the wallpaper.
  UpdateCustomWallpaperLayout(WallpaperUserInfo user_info,
                              WallpaperLayout layout);

  // Shows the user's wallpaper, which is determined in the following order:
  // 1) Use device policy wallpaper if it exists AND we are at the login screen.
  // 2) Use user policy wallpaper if it exists.
  // 3) Use the wallpaper set by the user (either by |SetOnlineWallpaper| or
  //    |SetCustomWallpaper|), if any.
  // 4) Use the default wallpaper of this user.
  ShowUserWallpaper(WallpaperUserInfo user_info);

  // Used by the gaia-signin UI. Signin wallpaper is considered either as the
  // device policy wallpaper or the default wallpaper.
  ShowSigninWallpaper();

  // Shows a one-shot wallpaper, which does not belong to any particular user
  // and is not saved to file. Note: the wallpaper will never be dimmed or
  // blurred because it's assumed that the caller wants to show the image as is
  // when using this method.
  ShowOneShotWallpaper(gfx.mojom.ImageSkia image);

  // Shows a wallpaper that stays on top of everything except for the power off
  // animation. All other wallpaper requests are ignored when the always-on-top
  // wallpaper is being shown.
  // |image_path|: The file path to read the image data from.
  ShowAlwaysOnTopWallpaper(mojo_base.mojom.FilePath image_path);

  // Removes the always-on-top wallpaper. The wallpaper will revert to the
  // previous one, or a default one if there was none. No-op if the current
  // wallpaper is not always-on-top.
  RemoveAlwaysOnTopWallpaper();

  // Removes all of the user's saved wallpapers and related info.
  // |wallpaper_files_id|: The file id for user_info.account_id.
  RemoveUserWallpaper(WallpaperUserInfo user_info, string wallpaper_files_id);

  // Removes all of the user's saved wallpapers and related info if the
  // wallpaper was set by |SetPolicyWallpaper|. In addition, sets the user's
  // wallpaper to be the default. If the user has logged in, show the default
  // wallpaper immediately, otherwise, the default wallpaper will be shown the
  // next time |ShowUserWallpaper| is called.
  // |user_info|: The user's information related to wallpaper.
  // |wallpaper_files_id|: The file id for user_info.account_id.
  RemovePolicyWallpaper(WallpaperUserInfo user_info, string wallpaper_files_id);

  // Returns the urls of the wallpapers that exist in local file system (i.e.
  // |SetOnlineWallpaperFromData| was called earlier). The url is used as id
  // to identify which wallpapers are available to be set offline.
  GetOfflineWallpaperList() => (array<string> url_list);

  // Sets wallpaper animation duration. Passing an empty value disables the
  // animation.
  SetAnimationDuration(mojo_base.mojom.TimeDelta animation_duration);

  // Opens the wallpaper picker if the active user is not controlled by policy
  // and it's allowed to change wallpaper per the user type and the login state.
  OpenWallpaperPickerIfAllowed();

  // Minimizes all windows except the active window.
  // |user_id_hash|: The hash value corresponding to |User::username_hash|.
  MinimizeInactiveWindows(string user_id_hash);

  // Restores all minimized windows to their previous states. This should only
  // be called after calling |MinimizeInactiveWindows|.
  // |user_id_hash|: The hash value corresponding to |User::username_hash|.
  RestoreMinimizedWindows(string user_id_hash);

  // Calling this method triggers an initial notification of the wallpaper
  // state. Observers are automatically removed as their connections are closed.
  AddObserver(associated WallpaperObserver observer);

  // Returns the wallpaper image currently being shown.
  GetWallpaperImage() => (gfx.mojom.ImageSkia image);

  // Returns the wallpaper prominent colors.
  GetWallpaperColors() => (array<uint32> prominent_colors);

  // Returns whether the current wallpaper is blurred.
  IsWallpaperBlurred() => (bool blurred);

  // Returns true if the wallpaper of the currently active user (if any) is
  // controlled by policy (excluding device policy). If there's no active user,
  // returns false.
  IsActiveUserWallpaperControlledByPolicy() => (bool controlled);

  // Returns the location and the layout of the active user's wallpaper. The
  // location is either a url or a file path, corresponding to
  // |WallpaperInfo.location|. Returns an empty string and an invalid layout if
  // there's no active user.
  GetActiveUserWallpaperInfo() => (string location, WallpaperLayout layout);

  // Returns true if the wallpaper setting (used to open the wallpaper picker)
  // should be visible.
  ShouldShowWallpaperSetting() => (bool show);
};

// Used by ash to control a Chrome client.
interface WallpaperControllerClient {
  // Opens the wallpaper picker window.
  OpenWallpaperPicker();

  // Signals to the client that ash is ready to set wallpapers. The client is
  // able to decide whatever the first wallpaper it wants to display.
  OnReadyToSetWallpaper();

  // Notifies the client that the animation of the first wallpaper since the
  // controller initialization has completed.
  // TODO(crbug.com/875128): Remove this after web-ui login code is completely
  // removed.
  OnFirstWallpaperAnimationFinished();
};

// Used to listen for wallpaper state changed.
interface WallpaperObserver {
  // Invoked when the wallpaper is changed. |image_id| is the unique id assigned
  // to the current wallpaper image. It should only be used to compare against
  // the value returned by a setting wallpaper request earlier
  // (e.g. SetThirdPartyWallpaper). This value is unique to each |ImageSkia|
  // object and is different for two objects with the same pixels.
  OnWallpaperChanged(uint32 image_id);

  // Invoked when the colors extracted from the current wallpaper change. Colors
  // are ordered and are referenced in wallpaper::ColorProfileType.
  OnWallpaperColorsChanged(array<uint32> prominent_colors);

  // Invoked when the blur state of the wallpaper changes.
  // TODO(crbug.com/875128): Remove this after web-ui login code is completely
  // removed.
  OnWallpaperBlurChanged(bool blurred);
};
