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