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

#ifndef EXTENSIONS_BROWSER_APP_WINDOW_APP_WINDOW_H_
#define EXTENSIONS_BROWSER_APP_WINDOW_APP_WINDOW_H_

#include <stdint.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/sessions/core/session_id.h"
#include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "extensions/browser/extension_function_dispatcher.h"
#include "extensions/browser/extension_registry_observer.h"
#include "ui/base/ui_base_types.h"  // WindowShowState
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/image/image.h"

class GURL;
class SkRegion;

namespace base {
class DictionaryValue;
}

namespace content {
class BrowserContext;
class RenderFrameHost;
class WebContents;
}

namespace extensions {

class AppDelegate;
class AppWebContentsHelper;
class Extension;
class NativeAppWindow;
class PlatformAppBrowserTest;

struct DraggableRegion;

// Manages the web contents for app windows. The implementation for this
// class should create and maintain the WebContents for the window, and handle
// any message passing between the web contents and the extension system or
// native window.
class AppWindowContents {
 public:
  AppWindowContents() {}
  virtual ~AppWindowContents() {}

  // Called to initialize the WebContents, before the app window is created.
  virtual void Initialize(content::BrowserContext* context,
                          content::RenderFrameHost* creator_frame,
                          const GURL& url) = 0;

  // Called to load the contents, after the app window is created.
  virtual void LoadContents(int32_t creator_process_id) = 0;

  // Called when the native window changes.
  virtual void NativeWindowChanged(NativeAppWindow* native_app_window) = 0;

  // Called when the native window closes. |send_oncloded| is flag to indicate
  // whether the OnClosed event should be sent. It is true except when the
  // native window is closed before AppWindowCreateFunction responds.
  virtual void NativeWindowClosed(bool send_onclosed) = 0;

  virtual content::WebContents* GetWebContents() const = 0;

  virtual extensions::WindowController* GetWindowController() const = 0;

 private:
  DISALLOW_COPY_AND_ASSIGN(AppWindowContents);
};

// AppWindow is the type of window used by platform apps. App windows
// have a WebContents but none of the chrome of normal browser windows.
class AppWindow : public content::WebContentsDelegate,
                  public content::WebContentsObserver,
                  public web_modal::WebContentsModalDialogManagerDelegate,
                  public ExtensionFunctionDispatcher::Delegate,
                  public ExtensionRegistryObserver {
 public:
  // Enum values should not be changed since they are used by UMA.
  enum WindowType {
    WINDOW_TYPE_DEFAULT = 0,  // Default app window.
    DEPRECATED_WINDOW_TYPE_PANEL = 1,
    WINDOW_TYPE_COUNT = 2,
  };

  enum Frame {
    FRAME_CHROME,  // Chrome-style window frame.
    FRAME_NONE,    // Frameless window.
  };

  enum FullscreenType {
    // Not fullscreen.
    FULLSCREEN_TYPE_NONE = 0,

    // Fullscreen entered by the app.window api.
    FULLSCREEN_TYPE_WINDOW_API = 1 << 0,

    // Fullscreen entered by HTML requestFullscreen().
    FULLSCREEN_TYPE_HTML_API = 1 << 1,

    // Fullscreen entered by the OS. ChromeOS uses this type of fullscreen to
    // enter immersive fullscreen when the user hits the <F4> key.
    FULLSCREEN_TYPE_OS = 1 << 2,

    // Fullscreen mode that could not be exited by the user. ChromeOS uses
    // this type of fullscreen to run an app in kiosk mode.
    FULLSCREEN_TYPE_FORCED = 1 << 3,
  };

  using ShapeRects = std::vector<gfx::Rect>;

  struct BoundsSpecification {
    // INT_MIN represents an unspecified position component.
    static const int kUnspecifiedPosition;

    BoundsSpecification();
    ~BoundsSpecification();

    // INT_MIN designates 'unspecified' for the position components, and 0
    // designates 'unspecified' for the size components. When unspecified,
    // they should be replaced with a default value.
    gfx::Rect bounds;

    gfx::Size minimum_size;
    gfx::Size maximum_size;

    // Reset the bounds fields to their 'unspecified' values. The minimum and
    // maximum size constraints remain unchanged.
    void ResetBounds();
  };

  struct CreateParams {
    CreateParams();
    CreateParams(const CreateParams& other);
    ~CreateParams();

    WindowType window_type;
    Frame frame;

    bool has_frame_color;
    SkColor active_frame_color;
    SkColor inactive_frame_color;
    bool alpha_enabled;
    bool is_ime_window;

    // The initial content/inner bounds specification (excluding any window
    // decorations).
    BoundsSpecification content_spec;

    // The initial window/outer bounds specification (including window
    // decorations).
    BoundsSpecification window_spec;

    std::string window_key;

    // The process ID of the process that requested the create.
    int32_t creator_process_id;

    // Initial state of the window.
    ui::WindowShowState state;

    // If true, don't show the window after creation.
    bool hidden;

    // If true, the window will be resizable by the user. Defaults to true.
    bool resizable;

    // If true, the window will be focused on creation. Defaults to true.
    bool focused;

    // If true, the window will stay on top of other windows that are not
    // configured to be always on top. Defaults to false.
    bool always_on_top;

    // If true, the window will be visible on all workspaces. Defaults to false.
    bool visible_on_all_workspaces;

    // Whether the app window should be shown on the lock screen.
    // Chrome OS only.
    bool show_on_lock_screen;

    // If true, the window will have its own shelf icon. Otherwise the window
    // will be grouped in the shelf with other windows that are associated with
    // the app. Defaults to false.
    bool show_in_shelf;

    // Icon URL to be used for setting the window icon.
    GURL window_icon_url;

    // The API enables developers to specify content or window bounds. This
    // function combines them into a single, constrained window size.
    gfx::Rect GetInitialWindowBounds(const gfx::Insets& frame_insets) const;

    // The API enables developers to specify content or window size constraints.
    // These functions combine them so that we can work with one set of
    // constraints.
    gfx::Size GetContentMinimumSize(const gfx::Insets& frame_insets) const;
    gfx::Size GetContentMaximumSize(const gfx::Insets& frame_insets) const;
    gfx::Size GetWindowMinimumSize(const gfx::Insets& frame_insets) const;
    gfx::Size GetWindowMaximumSize(const gfx::Insets& frame_insets) const;
  };

  // Convert draggable regions in raw format to SkRegion format. Caller is
  // responsible for deleting the returned SkRegion instance.
  static SkRegion* RawDraggableRegionsToSkRegion(
      const std::vector<DraggableRegion>& regions);

  // The constructor and Init methods are public for constructing a AppWindow
  // with a non-standard render interface (e.g.
  // lock_screen_apps::StateController, ChromeAppWindowClient). Normally
  // AppWindow::Create should be used. Takes ownership of |app_delegate| and
  // |delegate|.
  AppWindow(content::BrowserContext* context,
            AppDelegate* app_delegate,
            const Extension* extension);

  // Initializes the render interface, web contents, and native window.
  // |app_window_contents| will become owned by AppWindow.
  void Init(const GURL& url,
            AppWindowContents* app_window_contents,
            content::RenderFrameHost* creator_frame,
            const CreateParams& params);

  const std::string& window_key() const { return window_key_; }
  const SessionID& session_id() const { return session_id_; }
  const std::string& extension_id() const { return extension_id_; }
  content::WebContents* web_contents() const;
  WindowType window_type() const { return window_type_; }
  content::BrowserContext* browser_context() const { return browser_context_; }
  const gfx::Image& custom_app_icon() const { return custom_app_icon_; }
  const GURL& app_icon_url() const { return app_icon_url_; }
  const GURL& initial_url() const { return initial_url_; }
  bool is_hidden() const { return is_hidden_; }

  const Extension* GetExtension() const;
  NativeAppWindow* GetBaseWindow();
  gfx::NativeWindow GetNativeWindow();

  // Returns the bounds that should be reported to the renderer.
  gfx::Rect GetClientBounds() const;

  // NativeAppWindows should call this to determine what the window's title
  // is on startup and from within UpdateWindowTitle().
  base::string16 GetTitle() const;

  // |callback| will be called when the first navigation in the window is
  // ready to commit or when the window goes away before that. |ready_to_commit|
  // argument of the |callback| is set to true for the former case and false for
  // the later.
  using FirstCommitOrWindowClosedCallback =
      base::OnceCallback<void(bool ready_to_commit)>;
  void SetOnFirstCommitOrWindowClosedCallback(
      FirstCommitOrWindowClosedCallback callback);

  // Called when the first navigation in the window is ready to commit.
  void OnReadyToCommitFirstNavigation();

  // Call to notify ShellRegistry and delete the window. Subclasses should
  // invoke this method instead of using "delete this".
  void OnNativeClose();

  // Should be called by native implementations when the window size, position,
  // or minimized/maximized state has changed.
  void OnNativeWindowChanged();

  // Should be called by native implementations when the window is activated.
  void OnNativeWindowActivated();

  // Specifies a url for the launcher icon.
  void SetAppIconUrl(const GURL& icon_url);

  // Sets the window shape. Passing a nullptr |rects| sets the default shape.
  void UpdateShape(std::unique_ptr<ShapeRects> rects);

  // Called from the render interface to modify the draggable regions.
  void UpdateDraggableRegions(const std::vector<DraggableRegion>& regions);

  // Updates the app image to |image|. Called internally from the image loader
  // callback.
  void UpdateAppIcon(const gfx::Image& image);

  // Enable or disable fullscreen mode. |type| specifies which type of
  // fullscreen mode to change (note that disabling one type of fullscreen may
  // not exit fullscreen mode because a window may have a different type of
  // fullscreen enabled). If |type| is not FORCED, checks that the extension has
  // the required permission.
  void SetFullscreen(FullscreenType type, bool enable);

  // Returns true if the app window is in a fullscreen state.
  bool IsFullscreen() const;

  // Returns true if the app window is in a forced fullscreen state (one that
  // cannot be exited by the user).
  bool IsForcedFullscreen() const;

  // Returns true if the app window is in a fullscreen state entered from an
  // HTML API request.
  bool IsHtmlApiFullscreen() const;

  bool IsOsFullscreen() const;

  // Transitions window into fullscreen, maximized, minimized or restores based
  // on chrome.app.window API.
  void Fullscreen();
  void Maximize();
  void Minimize();
  void Restore();

  // Transitions to OS fullscreen. See FULLSCREEN_TYPE_OS for more details.
  void OSFullscreen();

  // Transitions to forced fullscreen. See FULLSCREEN_TYPE_FORCED for more
  // details.
  void ForcedFullscreen();

  // Set the minimum and maximum size of the content bounds.
  void SetContentSizeConstraints(const gfx::Size& min_size,
                                 const gfx::Size& max_size);

  enum ShowType { SHOW_ACTIVE, SHOW_INACTIVE };

  // Shows the window if its contents have been painted; otherwise flags the
  // window to be shown as soon as its contents are painted for the first time.
  void Show(ShowType show_type);

  // Hides the window. If the window was previously flagged to be shown on
  // first paint, it will be unflagged.
  void Hide();

  AppWindowContents* app_window_contents_for_test() {
    return app_window_contents_.get();
  }

  int fullscreen_types_for_test() {
    return fullscreen_types_;
  }

  // Set whether the window should stay above other windows which are not
  // configured to be always-on-top.
  void SetAlwaysOnTop(bool always_on_top);

  // Whether the always-on-top property has been set by the chrome.app.window
  // API. Note that the actual value of this property in the native app window
  // may be false if the bit is silently switched off for security reasons.
  bool IsAlwaysOnTop() const;

  // Restores the always-on-top property according to |cached_always_on_top_|.
  void RestoreAlwaysOnTop();

  // Retrieve the current state of the app window as a dictionary, to pass to
  // the renderer.
  void GetSerializedState(base::DictionaryValue* properties) const;

  // Whether the app window wants to be alpha enabled.
  bool requested_alpha_enabled() const { return requested_alpha_enabled_; }

  // Whether the app window is created by IME extensions.
  // TODO(bshe): rename to hide_app_window_in_launcher if it is not used
  // anywhere other than app_window_launcher_controller after M45. Otherwise,
  // remove this TODO.
  bool is_ime_window() const { return is_ime_window_; }

  bool show_on_lock_screen() const { return show_on_lock_screen_; }

  bool show_in_shelf() const { return show_in_shelf_; }

  AppDelegate* app_delegate() { return app_delegate_.get(); }

  void SetAppWindowContentsForTesting(
      std::unique_ptr<AppWindowContents> contents) {
    app_window_contents_ = std::move(contents);
  }

 protected:
  ~AppWindow() override;

 private:
  // PlatformAppBrowserTest needs access to web_contents()
  friend class PlatformAppBrowserTest;

  // content::WebContentsDelegate implementation.
  void ActivateContents(content::WebContents* contents) override;
  void CloseContents(content::WebContents* contents) override;
  bool ShouldSuppressDialogs(content::WebContents* source) override;
  content::ColorChooser* OpenColorChooser(
      content::WebContents* web_contents,
      SkColor color,
      const std::vector<blink::mojom::ColorSuggestionPtr>& suggestions)
      override;
  void RunFileChooser(content::RenderFrameHost* render_frame_host,
                      std::unique_ptr<content::FileSelectListener> listener,
                      const blink::mojom::FileChooserParams& params) override;
  void SetContentsBounds(content::WebContents* source,
                         const gfx::Rect& bounds) override;
  void NavigationStateChanged(content::WebContents* source,
                              content::InvalidateTypes changed_flags) override;
  void EnterFullscreenModeForTab(
      content::WebContents* source,
      const GURL& origin,
      const blink::WebFullscreenOptions& options) override;
  void ExitFullscreenModeForTab(content::WebContents* source) override;
  bool IsFullscreenForTabOrPending(
      const content::WebContents* source) const override;
  blink::WebDisplayMode GetDisplayMode(
      const content::WebContents* source) const override;
  void RequestMediaAccessPermission(
      content::WebContents* web_contents,
      const content::MediaStreamRequest& request,
      content::MediaResponseCallback callback) override;
  bool CheckMediaAccessPermission(content::RenderFrameHost* render_frame_host,
                                  const GURL& security_origin,
                                  blink::MediaStreamType type) override;
  content::WebContents* OpenURLFromTab(
      content::WebContents* source,
      const content::OpenURLParams& params) override;
  void AddNewContents(content::WebContents* source,
                      std::unique_ptr<content::WebContents> new_contents,
                      WindowOpenDisposition disposition,
                      const gfx::Rect& initial_rect,
                      bool user_gesture,
                      bool* was_blocked) override;
  content::KeyboardEventProcessingResult PreHandleKeyboardEvent(
      content::WebContents* source,
      const content::NativeWebKeyboardEvent& event) override;
  bool HandleKeyboardEvent(
      content::WebContents* source,
      const content::NativeWebKeyboardEvent& event) override;
  void RequestToLockMouse(content::WebContents* web_contents,
                          bool user_gesture,
                          bool last_unlocked_by_target) override;
  bool PreHandleGestureEvent(content::WebContents* source,
                             const blink::WebGestureEvent& event) override;
  std::unique_ptr<content::BluetoothChooser> RunBluetoothChooser(
      content::RenderFrameHost* frame,
      const content::BluetoothChooser::EventHandler& event_handler) override;
  bool TakeFocus(content::WebContents* source, bool reverse) override;
  gfx::Size EnterPictureInPicture(content::WebContents* web_contents,
                                  const viz::SurfaceId& surface_id,
                                  const gfx::Size& natural_size) override;
  void ExitPictureInPicture() override;

  // content::WebContentsObserver implementation.
  bool OnMessageReceived(const IPC::Message& message,
                         content::RenderFrameHost* render_frame_host) override;
  void RenderViewCreated(content::RenderViewHost* render_view_host) override;

  // ExtensionFunctionDispatcher::Delegate implementation.
  WindowController* GetExtensionWindowController() const override;
  content::WebContents* GetAssociatedWebContents() const override;

  // ExtensionRegistryObserver implementation.
  void OnExtensionUnloaded(content::BrowserContext* browser_context,
                           const Extension* extension,
                           UnloadedExtensionReason reason) override;

  // web_modal::WebContentsModalDialogManagerDelegate implementation.
  void SetWebContentsBlocked(content::WebContents* web_contents,
                             bool blocked) override;
  bool IsWebContentsVisible(content::WebContents* web_contents) override;

  // IPC handler for ExtensionHostMsg_AppWindowReady.
  void OnAppWindowReady();

  void ToggleFullscreenModeForTab(content::WebContents* source,
                                  bool enter_fullscreen);

  // Saves the window geometry/position/screen bounds.
  void SaveWindowPosition();

  // Helper method to adjust the cached bounds so that we can make sure it can
  // be visible on the screen. See http://crbug.com/145752.
  void AdjustBoundsToBeVisibleOnScreen(const gfx::Rect& cached_bounds,
                                       const gfx::Rect& cached_screen_bounds,
                                       const gfx::Rect& current_screen_bounds,
                                       const gfx::Size& minimum_size,
                                       gfx::Rect* bounds) const;

  // Loads the appropriate default or cached window bounds. Returns a new
  // CreateParams that should be used to create the window.
  CreateParams LoadDefaults(CreateParams params) const;

  // Set the fullscreen state in the native app window.
  void SetNativeWindowFullscreen();

  // Returns true if there is any overlap between the window and the taskbar
  // (Windows only).
  bool IntersectsWithTaskbar() const;

  // Update the always-on-top bit in the native app window.
  void UpdateNativeAlwaysOnTop();

  // Sends the onWindowShown event to the app if the window has been shown. Only
  // has an effect in tests.
  void SendOnWindowShownIfShown();

  // web_modal::WebContentsModalDialogManagerDelegate implementation.
  web_modal::WebContentsModalDialogHost* GetWebContentsModalDialogHost()
      override;

  // Starts custom app icon download. To avoid race condition with loading app
  // itself it is started in case |app_icon_url_| is set and app window is
  // ready.
  void StartAppIconDownload();

  // Callback from web_contents()->DownloadFavicon.
  void DidDownloadFavicon(int id,
                          int http_status_code,
                          const GURL& image_url,
                          const std::vector<SkBitmap>& bitmaps,
                          const std::vector<gfx::Size>& original_bitmap_sizes);

  // The browser context with which this window is associated. AppWindow does
  // not own this object.
  content::BrowserContext* browser_context_;

  const std::string extension_id_;

  // Identifier that is used when saving and restoring geometry for this
  // window.
  std::string window_key_;

  const SessionID session_id_;
  WindowType window_type_ = WINDOW_TYPE_DEFAULT;

  // Custom icon shown in the task bar or in Chrome OS shelf.
  gfx::Image custom_app_icon_;

  // Icon URL to be used for setting the app icon. If not empty, app_icon_ will
  // be fetched and set using this URL.
  GURL app_icon_url_;

  std::unique_ptr<NativeAppWindow> native_app_window_;
  std::unique_ptr<AppWindowContents> app_window_contents_;
  std::unique_ptr<AppDelegate> app_delegate_;
  std::unique_ptr<AppWebContentsHelper> helper_;

  // The initial url this AppWindow was navigated to.
  GURL initial_url_;

  // Bit field of FullscreenType.
  int fullscreen_types_ = FULLSCREEN_TYPE_NONE;

  // Whether the window has been shown or not.
  bool has_been_shown_ = false;

  // Whether the window is hidden or not. Hidden in this context means actively
  // by the chrome.app.window API, not in an operating system context. For
  // example windows which are minimized are not hidden, and windows which are
  // part of a hidden app on OS X are not hidden. Windows which were created
  // with the |hidden| flag set to true, or which have been programmatically
  // hidden, are considered hidden.
  bool is_hidden_ = false;

  // Cache the desired value of the always-on-top property. When windows enter
  // fullscreen or overlap the Windows taskbar, this property will be
  // automatically and silently switched off for security reasons. It is
  // reinstated when the window exits fullscreen and moves away from the
  // taskbar.
  bool cached_always_on_top_ = false;

  // Whether |alpha_enabled| was set in the CreateParams.
  bool requested_alpha_enabled_ = false;

  // Whether |is_ime_window| was set in the CreateParams.
  bool is_ime_window_ = false;

  // Whether |show_on_lock_screen| was set in the CreateParams.
  bool show_on_lock_screen_ = false;

  // Whether |show_in_shelf| was set in the CreateParams.
  bool show_in_shelf_ = false;

  // Whether the app window is loaded and ready. It is used to resolve the
  // race condition of loading custom app icon and app content simultaneously.
  bool window_ready_ = false;

  // PlzNavigate: this is called when the first navigation is ready to commit or
  // when the window is closed.
  FirstCommitOrWindowClosedCallback on_first_commit_or_window_closed_callback_;

  base::WeakPtrFactory<AppWindow> image_loader_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(AppWindow);
};

}  // namespace extensions

#endif  // EXTENSIONS_BROWSER_APP_WINDOW_APP_WINDOW_H_
