Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / apps / app_window.h
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef APPS_APP_WINDOW_H_
6 #define APPS_APP_WINDOW_H_
7
8 #include "base/memory/scoped_ptr.h"
9 #include "base/memory/weak_ptr.h"
10 #include "chrome/browser/extensions/extension_icon_image.h"
11 #include "chrome/browser/extensions/extension_keybinding_registry.h"
12 #include "chrome/browser/sessions/session_id.h"
13 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
14 #include "content/public/browser/notification_observer.h"
15 #include "content/public/browser/notification_registrar.h"
16 #include "content/public/browser/web_contents_delegate.h"
17 #include "content/public/browser/web_contents_observer.h"
18 #include "content/public/common/console_message_level.h"
19 #include "ui/base/ui_base_types.h"  // WindowShowState
20 #include "ui/gfx/image/image.h"
21 #include "ui/gfx/rect.h"
22
23 class GURL;
24 class SkRegion;
25
26 namespace base {
27 class DictionaryValue;
28 }
29
30 namespace content {
31 class BrowserContext;
32 class WebContents;
33 }
34
35 namespace extensions {
36 class Extension;
37 class PlatformAppBrowserTest;
38 class WindowController;
39
40 struct DraggableRegion;
41 }
42
43 namespace ui {
44 class BaseWindow;
45 }
46
47 namespace apps {
48
49 class NativeAppWindow;
50
51 // Manages the web contents for app windows. The implementation for this
52 // class should create and maintain the WebContents for the window, and handle
53 // any message passing between the web contents and the extension system or
54 // native window.
55 class AppWindowContents {
56  public:
57   AppWindowContents() {}
58   virtual ~AppWindowContents() {}
59
60   // Called to initialize the WebContents, before the app window is created.
61   virtual void Initialize(content::BrowserContext* context,
62                           const GURL& url) = 0;
63
64   // Called to load the contents, after the app window is created.
65   virtual void LoadContents(int32 creator_process_id) = 0;
66
67   // Called when the native window changes.
68   virtual void NativeWindowChanged(NativeAppWindow* native_app_window) = 0;
69
70   // Called when the native window closes.
71   virtual void NativeWindowClosed() = 0;
72
73   virtual content::WebContents* GetWebContents() const = 0;
74
75  private:
76   DISALLOW_COPY_AND_ASSIGN(AppWindowContents);
77 };
78
79 // AppWindow is the type of window used by platform apps. App windows
80 // have a WebContents but none of the chrome of normal browser windows.
81 class AppWindow : public content::NotificationObserver,
82                   public content::WebContentsDelegate,
83                   public content::WebContentsObserver,
84                   public web_modal::WebContentsModalDialogManagerDelegate,
85                   public extensions::ExtensionKeybindingRegistry::Delegate,
86                   public extensions::IconImage::Observer {
87  public:
88   enum WindowType {
89     WINDOW_TYPE_DEFAULT = 1 << 0,   // Default app window.
90     WINDOW_TYPE_PANEL = 1 << 1,     // OS controlled panel window (Ash only).
91     WINDOW_TYPE_V1_PANEL = 1 << 2,  // For apps v1 support in Ash; deprecate
92                                     // with v1 apps.
93   };
94
95   enum Frame {
96     FRAME_CHROME,  // Chrome-style window frame.
97     FRAME_NONE,    // Frameless window.
98   };
99
100   enum FullscreenType {
101     // Not fullscreen.
102     FULLSCREEN_TYPE_NONE = 0,
103
104     // Fullscreen entered by the app.window api.
105     FULLSCREEN_TYPE_WINDOW_API = 1 << 0,
106
107     // Fullscreen entered by HTML requestFullscreen().
108     FULLSCREEN_TYPE_HTML_API = 1 << 1,
109
110     // Fullscreen entered by the OS. ChromeOS uses this type of fullscreen to
111     // enter immersive fullscreen when the user hits the <F4> key.
112     FULLSCREEN_TYPE_OS = 1 << 2,
113
114     // Fullscreen mode that could not be exited by the user. ChromeOS uses
115     // this type of fullscreen to run an app in kiosk mode.
116     FULLSCREEN_TYPE_FORCED = 1 << 3,
117   };
118
119   class SizeConstraints {
120    public:
121     // The value SizeConstraints uses to represent an unbounded width or height.
122     // This is an enum so that it can be declared inline here.
123     enum { kUnboundedSize = 0 };
124
125     SizeConstraints();
126     SizeConstraints(const gfx::Size& min_size, const gfx::Size& max_size);
127     ~SizeConstraints();
128
129     // Returns the bounds with its size clamped to the min/max size.
130     gfx::Size ClampSize(gfx::Size size) const;
131
132     // When gfx::Size is used as a min/max size, a zero represents an unbounded
133     // component. This method checks whether either component is specified.
134     // Note we can't use gfx::Size::IsEmpty as it returns true if either width
135     // or height is zero.
136     bool HasMinimumSize() const;
137     bool HasMaximumSize() const;
138
139     // This returns true if all components are specified, and min and max are
140     // equal.
141     bool HasFixedSize() const;
142
143     gfx::Size GetMaximumSize() const;
144     gfx::Size GetMinimumSize() const;
145
146     void set_minimum_size(const gfx::Size& min_size);
147     void set_maximum_size(const gfx::Size& max_size);
148
149    private:
150     gfx::Size minimum_size_;
151     gfx::Size maximum_size_;
152   };
153
154   struct CreateParams {
155     CreateParams();
156     ~CreateParams();
157
158     WindowType window_type;
159     Frame frame;
160     bool transparent_background;  // Only supported on ash.
161
162     // Specify the initial content bounds of the window (excluding any window
163     // decorations). INT_MIN designates 'unspecified' for the position
164     // components, and 0 for the size components. When unspecified, they should
165     // be replaced with a default value.
166     gfx::Rect bounds;
167
168     gfx::Size minimum_size;
169     gfx::Size maximum_size;
170
171     std::string window_key;
172
173     // The process ID of the process that requested the create.
174     int32 creator_process_id;
175
176     // Initial state of the window.
177     ui::WindowShowState state;
178
179     // If true, don't show the window after creation.
180     bool hidden;
181
182     // If true, the window will be resizable by the user. Defaults to true.
183     bool resizable;
184
185     // If true, the window will be focused on creation. Defaults to true.
186     bool focused;
187
188     // If true, the window will stay on top of other windows that are not
189     // configured to be always on top. Defaults to false.
190     bool always_on_top;
191   };
192
193   class Delegate {
194    public:
195     virtual ~Delegate();
196
197     // General initialization.
198     virtual void InitWebContents(content::WebContents* web_contents) = 0;
199     virtual NativeAppWindow* CreateNativeAppWindow(
200         AppWindow* window,
201         const CreateParams& params) = 0;
202
203     // Link handling.
204     virtual content::WebContents* OpenURLFromTab(
205         content::BrowserContext* context,
206         content::WebContents* source,
207         const content::OpenURLParams& params) = 0;
208     virtual void AddNewContents(content::BrowserContext* context,
209                                 content::WebContents* new_contents,
210                                 WindowOpenDisposition disposition,
211                                 const gfx::Rect& initial_pos,
212                                 bool user_gesture,
213                                 bool* was_blocked) = 0;
214
215     // Feature support.
216     virtual content::ColorChooser* ShowColorChooser(
217         content::WebContents* web_contents,
218         SkColor initial_color) = 0;
219     virtual void RunFileChooser(content::WebContents* tab,
220                                 const content::FileChooserParams& params) = 0;
221     virtual void RequestMediaAccessPermission(
222         content::WebContents* web_contents,
223         const content::MediaStreamRequest& request,
224         const content::MediaResponseCallback& callback,
225         const extensions::Extension* extension) = 0;
226     virtual int PreferredIconSize() = 0;
227
228     // Web contents modal dialog support.
229     virtual void SetWebContentsBlocked(content::WebContents* web_contents,
230                                        bool blocked) = 0;
231     virtual bool IsWebContentsVisible(content::WebContents* web_contents) = 0;
232   };
233
234   // Convert draggable regions in raw format to SkRegion format. Caller is
235   // responsible for deleting the returned SkRegion instance.
236   static SkRegion* RawDraggableRegionsToSkRegion(
237       const std::vector<extensions::DraggableRegion>& regions);
238
239   // The constructor and Init methods are public for constructing a AppWindow
240   // with a non-standard render interface (e.g. v1 apps using Ash Panels).
241   // Normally AppWindow::Create should be used.
242   // The constructed app window takes ownership of |delegate|.
243   AppWindow(content::BrowserContext* context,
244             Delegate* delegate,
245             const extensions::Extension* extension);
246
247   // Initializes the render interface, web contents, and native window.
248   // |app_window_contents| will become owned by AppWindow.
249   void Init(const GURL& url,
250             AppWindowContents* app_window_contents,
251             const CreateParams& params);
252
253   const std::string& window_key() const { return window_key_; }
254   const SessionID& session_id() const { return session_id_; }
255   const extensions::Extension* extension() const { return extension_; }
256   const std::string& extension_id() const { return extension_id_; }
257   content::WebContents* web_contents() const;
258   WindowType window_type() const { return window_type_; }
259   bool window_type_is_panel() const {
260     return (window_type_ == WINDOW_TYPE_PANEL ||
261             window_type_ == WINDOW_TYPE_V1_PANEL);
262   }
263   content::BrowserContext* browser_context() const { return browser_context_; }
264   const gfx::Image& app_icon() const { return app_icon_; }
265   const GURL& app_icon_url() const { return app_icon_url_; }
266   const gfx::Image& badge_icon() const { return badge_icon_; }
267   const GURL& badge_icon_url() const { return badge_icon_url_; }
268
269   NativeAppWindow* GetBaseWindow();
270   gfx::NativeWindow GetNativeWindow();
271
272   // Returns the bounds that should be reported to the renderer.
273   gfx::Rect GetClientBounds() const;
274
275   // NativeAppWindows should call this to determine what the window's title
276   // is on startup and from within UpdateWindowTitle().
277   base::string16 GetTitle() const;
278
279   // Call to notify ShellRegistry and delete the window. Subclasses should
280   // invoke this method instead of using "delete this".
281   void OnNativeClose();
282
283   // Should be called by native implementations when the window size, position,
284   // or minimized/maximized state has changed.
285   void OnNativeWindowChanged();
286
287   // Should be called by native implementations when the window is activated.
288   void OnNativeWindowActivated();
289
290   // Specifies a url for the launcher icon.
291   void SetAppIconUrl(const GURL& icon_url);
292
293   // Specifies a url for the window badge.
294   void SetBadgeIconUrl(const GURL& icon_url);
295
296   // Clear the current badge.
297   void ClearBadge();
298
299   // Set the window shape. Passing a NULL |region| sets the default shape.
300   void UpdateShape(scoped_ptr<SkRegion> region);
301
302   // Called from the render interface to modify the draggable regions.
303   void UpdateDraggableRegions(
304       const std::vector<extensions::DraggableRegion>& regions);
305
306   // Updates the app image to |image|. Called internally from the image loader
307   // callback. Also called externally for v1 apps using Ash Panels.
308   void UpdateAppIcon(const gfx::Image& image);
309
310   // Transitions window into fullscreen, maximized, minimized or restores based
311   // on chrome.app.window API.
312   void Fullscreen();
313   void Maximize();
314   void Minimize();
315   void Restore();
316
317   // Transitions to OS fullscreen. See FULLSCREEN_TYPE_OS for more details.
318   void OSFullscreen();
319
320   // Transitions to forced fullscreen. See FULLSCREEN_TYPE_FORCED for more
321   // details.
322   void ForcedFullscreen();
323
324   // Set the minimum and maximum size that this window is allowed to be.
325   void SetMinimumSize(const gfx::Size& min_size);
326   void SetMaximumSize(const gfx::Size& max_size);
327
328   enum ShowType { SHOW_ACTIVE, SHOW_INACTIVE };
329
330   // Shows the window if its contents have been painted; otherwise flags the
331   // window to be shown as soon as its contents are painted for the first time.
332   void Show(ShowType show_type);
333
334   // Hides the window. If the window was previously flagged to be shown on
335   // first paint, it will be unflagged.
336   void Hide();
337
338   AppWindowContents* app_window_contents_for_test() {
339     return app_window_contents_.get();
340   }
341
342   // Get the size constraints.
343   const SizeConstraints& size_constraints() const { return size_constraints_; }
344
345   // Set whether the window should stay above other windows which are not
346   // configured to be always-on-top.
347   void SetAlwaysOnTop(bool always_on_top);
348
349   // Whether the always-on-top property has been set by the chrome.app.window
350   // API. Note that the actual value of this property in the native app window
351   // may be false if the bit is silently switched off for security reasons.
352   bool IsAlwaysOnTop() const;
353
354   // Retrieve the current state of the app window as a dictionary, to pass to
355   // the renderer.
356   void GetSerializedState(base::DictionaryValue* properties) const;
357
358  protected:
359   virtual ~AppWindow();
360
361  private:
362   // PlatformAppBrowserTest needs access to web_contents()
363   friend class extensions::PlatformAppBrowserTest;
364
365   // content::WebContentsDelegate implementation.
366   virtual void CloseContents(content::WebContents* contents) OVERRIDE;
367   virtual bool ShouldSuppressDialogs() OVERRIDE;
368   virtual content::ColorChooser* OpenColorChooser(
369       content::WebContents* web_contents,
370       SkColor color,
371       const std::vector<content::ColorSuggestion>& suggestions) OVERRIDE;
372   virtual void RunFileChooser(content::WebContents* tab,
373                               const content::FileChooserParams& params)
374       OVERRIDE;
375   virtual bool IsPopupOrPanel(const content::WebContents* source)
376       const OVERRIDE;
377   virtual void MoveContents(content::WebContents* source,
378                             const gfx::Rect& pos) OVERRIDE;
379   virtual void NavigationStateChanged(const content::WebContents* source,
380                                       unsigned changed_flags) OVERRIDE;
381   virtual void ToggleFullscreenModeForTab(content::WebContents* source,
382                                           bool enter_fullscreen) OVERRIDE;
383   virtual bool IsFullscreenForTabOrPending(const content::WebContents* source)
384       const OVERRIDE;
385   virtual void RequestMediaAccessPermission(
386       content::WebContents* web_contents,
387       const content::MediaStreamRequest& request,
388       const content::MediaResponseCallback& callback) OVERRIDE;
389   virtual content::WebContents* OpenURLFromTab(
390       content::WebContents* source,
391       const content::OpenURLParams& params) OVERRIDE;
392   virtual void AddNewContents(content::WebContents* source,
393                               content::WebContents* new_contents,
394                               WindowOpenDisposition disposition,
395                               const gfx::Rect& initial_pos,
396                               bool user_gesture,
397                               bool* was_blocked) OVERRIDE;
398   virtual bool PreHandleKeyboardEvent(
399       content::WebContents* source,
400       const content::NativeWebKeyboardEvent& event,
401       bool* is_keyboard_shortcut) OVERRIDE;
402   virtual void HandleKeyboardEvent(content::WebContents* source,
403                                    const content::NativeWebKeyboardEvent& event)
404       OVERRIDE;
405   virtual void RequestToLockMouse(content::WebContents* web_contents,
406                                   bool user_gesture,
407                                   bool last_unlocked_by_target) OVERRIDE;
408   virtual bool PreHandleGestureEvent(content::WebContents* source,
409                                      const blink::WebGestureEvent& event)
410       OVERRIDE;
411
412   // content::WebContentsObserver implementation.
413   virtual void DidFirstVisuallyNonEmptyPaint(int32 page_id) OVERRIDE;
414
415   // content::NotificationObserver implementation.
416   virtual void Observe(int type,
417                        const content::NotificationSource& source,
418                        const content::NotificationDetails& details) OVERRIDE;
419
420   // web_modal::WebContentsModalDialogManagerDelegate implementation.
421   virtual void SetWebContentsBlocked(content::WebContents* web_contents,
422                                      bool blocked) OVERRIDE;
423   virtual bool IsWebContentsVisible(content::WebContents* web_contents)
424       OVERRIDE;
425
426   // Helper method to add a message to the renderer's DevTools console.
427   void AddMessageToDevToolsConsole(content::ConsoleMessageLevel level,
428                                    const std::string& message);
429
430   // Saves the window geometry/position/screen bounds.
431   void SaveWindowPosition();
432
433   // Helper method to adjust the cached bounds so that we can make sure it can
434   // be visible on the screen. See http://crbug.com/145752 .
435   void AdjustBoundsToBeVisibleOnScreen(const gfx::Rect& cached_bounds,
436                                        const gfx::Rect& cached_screen_bounds,
437                                        const gfx::Rect& current_screen_bounds,
438                                        const gfx::Size& minimum_size,
439                                        gfx::Rect* bounds) const;
440
441   // Loads the appropriate default or cached window bounds and constrains them
442   // based on screen size and minimum/maximum size. Returns a new CreateParams
443   // that should be used to create the window.
444   CreateParams LoadDefaultsAndConstrain(CreateParams params) const;
445
446   // Load the app's image, firing a load state change when loaded.
447   void UpdateExtensionAppIcon();
448
449   // Called when size_constraints is changed.
450   void OnSizeConstraintsChanged();
451
452   // Set the fullscreen state in the native app window.
453   void SetNativeWindowFullscreen();
454
455   // Returns true if there is any overlap between the window and the taskbar
456   // (Windows only).
457   bool IntersectsWithTaskbar() const;
458
459   // Update the always-on-top bit in the native app window.
460   void UpdateNativeAlwaysOnTop();
461
462   // extensions::ExtensionKeybindingRegistry::Delegate implementation.
463   virtual extensions::ActiveTabPermissionGranter*
464       GetActiveTabPermissionGranter() OVERRIDE;
465
466   // web_modal::WebContentsModalDialogManagerDelegate implementation.
467   virtual web_modal::WebContentsModalDialogHost* GetWebContentsModalDialogHost()
468       OVERRIDE;
469
470   // Updates the badge to |image|. Called internally from the image loader
471   // callback.
472   void UpdateBadgeIcon(const gfx::Image& image);
473
474   // Callback from web_contents()->DownloadFavicon.
475   void DidDownloadFavicon(int id,
476                           int http_status_code,
477                           const GURL& image_url,
478                           const std::vector<SkBitmap>& bitmaps,
479                           const std::vector<gfx::Size>& original_bitmap_sizes);
480
481   // extensions::IconImage::Observer implementation.
482   virtual void OnExtensionIconImageChanged(extensions::IconImage* image)
483       OVERRIDE;
484
485   // The browser context with which this window is associated. AppWindow does
486   // not own this object.
487   content::BrowserContext* browser_context_;
488
489   // weak pointer - owned by ExtensionService.
490   const extensions::Extension* extension_;
491   const std::string extension_id_;
492
493   // Identifier that is used when saving and restoring geometry for this
494   // window.
495   std::string window_key_;
496
497   const SessionID session_id_;
498   WindowType window_type_;
499   content::NotificationRegistrar registrar_;
500
501   // Icon shown in the task bar.
502   gfx::Image app_icon_;
503
504   // Icon URL to be used for setting the app icon. If not empty, app_icon_ will
505   // be fetched and set using this URL.
506   GURL app_icon_url_;
507
508   // An object to load the app's icon as an extension resource.
509   scoped_ptr<extensions::IconImage> app_icon_image_;
510
511   // Badge for icon shown in the task bar.
512   gfx::Image badge_icon_;
513
514   // URL to be used for setting the badge on the app icon.
515   GURL badge_icon_url_;
516
517   // An object to load the badge as an extension resource.
518   scoped_ptr<extensions::IconImage> badge_icon_image_;
519
520   scoped_ptr<NativeAppWindow> native_app_window_;
521   scoped_ptr<AppWindowContents> app_window_contents_;
522   scoped_ptr<Delegate> delegate_;
523
524   base::WeakPtrFactory<AppWindow> image_loader_ptr_factory_;
525
526   // Bit field of FullscreenType.
527   int fullscreen_types_;
528
529   // Size constraints on the window.
530   SizeConstraints size_constraints_;
531
532   // Show has been called, so the window should be shown once the first visually
533   // non-empty paint occurs.
534   bool show_on_first_paint_;
535
536   // The first visually non-empty paint has completed.
537   bool first_paint_complete_;
538
539   // Whether the delayed Show() call was for an active or inactive window.
540   ShowType delayed_show_type_;
541
542   // Cache the desired value of the always-on-top property. When windows enter
543   // fullscreen or overlap the Windows taskbar, this property will be
544   // automatically and silently switched off for security reasons. It is
545   // reinstated when the window exits fullscreen and moves away from the
546   // taskbar.
547   bool cached_always_on_top_;
548
549   DISALLOW_COPY_AND_ASSIGN(AppWindow);
550 };
551
552 }  // namespace apps
553
554 #endif  // APPS_APP_WINDOW_H_