// 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 was completed or window
  // is closed before that. |did_finish| argument of the |callback| is set to
  // true for the former case and false for the latter.
  using DidFinishFirstNavigationCallback =
      base::OnceCallback<void(bool did_finish)>;
  void AddOnDidFinishFirstNavigationCallback(
      DidFinishFirstNavigationCallback callback);

  // Called when first navigation was completed.
  void OnDidFinishFirstNavigation();

  // 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);
  }

  bool DidFinishFirstNavigation() { return did_finish_first_navigation_; }

 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,
                      scoped_refptr<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::RenderFrameHost* requesting_frame,
      const blink::mojom::FullscreenOptions& options) override;
  void ExitFullscreenModeForTab(content::WebContents* source) override;
  bool IsFullscreenForTabOrPending(const content::WebContents* source) override;
  blink::mojom::DisplayMode GetDisplayMode(
      const content::WebContents* source) 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::mojom::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,
                      const GURL& target_url,
                      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;
  bool TakeFocus(content::WebContents* source, bool reverse) override;
  content::PictureInPictureResult EnterPictureInPicture(
      content::WebContents* web_contents,
      const viz::SurfaceId& surface_id,
      const gfx::Size& natural_size) override;
  void ExitPictureInPicture() override;
  bool ShouldShowStaleContentOnEviction(content::WebContents* source) 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;

  // These callbacks are called when the navigation is finished on both browser
  // and renderer sides.
  std::vector<DidFinishFirstNavigationCallback>
      on_did_finish_first_navigation_callbacks_;
  // Whether the first navigation was completed in both browser and renderer
  // processes.
  bool did_finish_first_navigation_ = false;

  base::WeakPtrFactory<AppWindow> image_loader_ptr_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(AppWindow);
};

}  // namespace extensions

#endif  // EXTENSIONS_BROWSER_APP_WINDOW_APP_WINDOW_H_
