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/common/console_message_level.h" 18 #include "ui/base/ui_base_types.h" // WindowShowState 19 #include "ui/gfx/image/image.h" 20 #include "ui/gfx/rect.h" 21 22 class GURL; 23 class Profile; 24 class SkRegion; 25 26 namespace content { 27 class WebContents; 28 } 29 30 namespace extensions { 31 class Extension; 32 class PlatformAppBrowserTest; 33 class WindowController; 34 35 struct DraggableRegion; 36 } 37 38 namespace ui { 39 class BaseWindow; 40 } 41 42 namespace apps { 43 44 class NativeAppWindow; 45 46 // Manages the web contents for Shell Windows. The implementation for this 47 // class should create and maintain the WebContents for the window, and handle 48 // any message passing between the web contents and the extension system or 49 // native window. 50 class ShellWindowContents { 51 public: 52 ShellWindowContents() {} 53 virtual ~ShellWindowContents() {} 54 55 // Called to initialize the WebContents, before the app window is created. 56 virtual void Initialize(Profile* profile, const GURL& url) = 0; 57 58 // Called to load the contents, after the app window is created. 59 virtual void LoadContents(int32 creator_process_id) = 0; 60 61 // Called when the native window changes. 62 virtual void NativeWindowChanged(NativeAppWindow* native_app_window) = 0; 63 64 // Called when the native window closes. 65 virtual void NativeWindowClosed() = 0; 66 67 virtual content::WebContents* GetWebContents() const = 0; 68 69 private: 70 DISALLOW_COPY_AND_ASSIGN(ShellWindowContents); 71 }; 72 73 // ShellWindow is the type of window used by platform apps. Shell windows 74 // have a WebContents but none of the chrome of normal browser windows. 75 class ShellWindow : public content::NotificationObserver, 76 public content::WebContentsDelegate, 77 public web_modal::WebContentsModalDialogManagerDelegate, 78 public extensions::ExtensionKeybindingRegistry::Delegate, 79 public extensions::IconImage::Observer { 80 public: 81 enum WindowType { 82 WINDOW_TYPE_DEFAULT = 1 << 0, // Default shell window. 83 WINDOW_TYPE_PANEL = 1 << 1, // OS controlled panel window (Ash only). 84 WINDOW_TYPE_V1_PANEL = 1 << 2, // For apps v1 support in Ash; deprecate 85 // with v1 apps. 86 }; 87 88 enum Frame { 89 FRAME_CHROME, // Chrome-style window frame. 90 FRAME_NONE, // Frameless window. 91 }; 92 93 struct CreateParams { 94 CreateParams(); 95 ~CreateParams(); 96 97 WindowType window_type; 98 Frame frame; 99 bool transparent_background; // Only supported on ash. 100 101 // Specify the initial content bounds of the window (excluding any window 102 // decorations). INT_MIN designates 'unspecified' for the position 103 // components, and 0 for the size components. When unspecified, they should 104 // be replaced with a default value. 105 gfx::Rect bounds; 106 107 gfx::Size minimum_size; 108 gfx::Size maximum_size; 109 110 std::string window_key; 111 112 // The process ID of the process that requested the create. 113 int32 creator_process_id; 114 115 // Initial state of the window. 116 ui::WindowShowState state; 117 118 // If true, don't show the window after creation. 119 bool hidden; 120 121 // If true, the window will be resizable by the user. Defaults to true. 122 bool resizable; 123 124 // If true, the window will be focused on creation. Defaults to true. 125 bool focused; 126 }; 127 128 class Delegate { 129 public: 130 virtual ~Delegate(); 131 132 // General initialization. 133 virtual void InitWebContents(content::WebContents* web_contents) = 0; 134 virtual NativeAppWindow* CreateNativeAppWindow( 135 ShellWindow* window, 136 const CreateParams& params) = 0; 137 138 // Link handling. 139 virtual content::WebContents* OpenURLFromTab( 140 Profile* profile, 141 content::WebContents* source, 142 const content::OpenURLParams& params) = 0; 143 virtual void AddNewContents(Profile* profile, 144 content::WebContents* new_contents, 145 WindowOpenDisposition disposition, 146 const gfx::Rect& initial_pos, 147 bool user_gesture, 148 bool* was_blocked) = 0; 149 150 // Feature support. 151 virtual content::ColorChooser* ShowColorChooser( 152 content::WebContents* web_contents, 153 SkColor initial_color) = 0; 154 virtual void RunFileChooser(content::WebContents* tab, 155 const content::FileChooserParams& params) = 0; 156 virtual void RequestMediaAccessPermission( 157 content::WebContents* web_contents, 158 const content::MediaStreamRequest& request, 159 const content::MediaResponseCallback& callback, 160 const extensions::Extension* extension) = 0; 161 virtual int PreferredIconSize() = 0; 162 163 // Web contents modal dialog support. 164 virtual void SetWebContentsBlocked(content::WebContents* web_contents, 165 bool blocked) = 0; 166 virtual bool IsWebContentsVisible(content::WebContents* web_contents) = 0; 167 }; 168 169 // Convert draggable regions in raw format to SkRegion format. Caller is 170 // responsible for deleting the returned SkRegion instance. 171 static SkRegion* RawDraggableRegionsToSkRegion( 172 const std::vector<extensions::DraggableRegion>& regions); 173 174 // The constructor and Init methods are public for constructing a ShellWindow 175 // with a non-standard render interface (e.g. v1 apps using Ash Panels). 176 // Normally ShellWindow::Create should be used. 177 // The constructed shell window takes ownership of |delegate|. 178 ShellWindow(Profile* profile, 179 Delegate* delegate, 180 const extensions::Extension* extension); 181 182 // Initializes the render interface, web contents, and native window. 183 // |shell_window_contents| will become owned by ShellWindow. 184 void Init(const GURL& url, 185 ShellWindowContents* shell_window_contents, 186 const CreateParams& params); 187 188 189 const std::string& window_key() const { return window_key_; } 190 const SessionID& session_id() const { return session_id_; } 191 const extensions::Extension* extension() const { return extension_; } 192 const std::string& extension_id() const { return extension_id_; } 193 content::WebContents* web_contents() const; 194 WindowType window_type() const { return window_type_; } 195 bool window_type_is_panel() const { 196 return (window_type_ == WINDOW_TYPE_PANEL || 197 window_type_ == WINDOW_TYPE_V1_PANEL); 198 } 199 Profile* profile() const { return profile_; } 200 const gfx::Image& app_icon() const { return app_icon_; } 201 const GURL& app_icon_url() { return app_icon_url_; } 202 203 NativeAppWindow* GetBaseWindow(); 204 gfx::NativeWindow GetNativeWindow(); 205 206 // Returns the bounds that should be reported to the renderer. 207 gfx::Rect GetClientBounds() const; 208 209 // This will return a slightly smaller icon then the app_icon to be used in 210 // application lists. 211 scoped_ptr<gfx::Image> GetAppListIcon(); 212 213 // NativeAppWindows should call this to determine what the window's title 214 // is on startup and from within UpdateWindowTitle(). 215 string16 GetTitle() const; 216 217 // Call to notify ShellRegistry and delete the window. Subclasses should 218 // invoke this method instead of using "delete this". 219 void OnNativeClose(); 220 221 // Should be called by native implementations when the window size, position, 222 // or minimized/maximized state has changed. 223 void OnNativeWindowChanged(); 224 225 // Should be called by native implementations when the window is activated. 226 void OnNativeWindowActivated(); 227 228 // Specifies a url for the launcher icon. 229 void SetAppIconUrl(const GURL& icon_url); 230 231 // Called from the render interface to modify the draggable regions. 232 void UpdateDraggableRegions( 233 const std::vector<extensions::DraggableRegion>& regions); 234 235 // Updates the app image to |image|. Called internally from the image loader 236 // callback. Also called externally for v1 apps using Ash Panels. 237 void UpdateAppIcon(const gfx::Image& image); 238 239 // Transitions window into fullscreen, maximized, minimized or restores based 240 // on chrome.app.window API. 241 void Fullscreen(); 242 void Maximize(); 243 void Minimize(); 244 void Restore(); 245 246 ShellWindowContents* shell_window_contents_for_test() { 247 return shell_window_contents_.get(); 248 } 249 250 protected: 251 virtual ~ShellWindow(); 252 253 private: 254 // PlatformAppBrowserTest needs access to web_contents() 255 friend class extensions::PlatformAppBrowserTest; 256 257 // content::WebContentsDelegate implementation. 258 virtual void CloseContents(content::WebContents* contents) OVERRIDE; 259 virtual bool ShouldSuppressDialogs() OVERRIDE; 260 virtual content::ColorChooser* OpenColorChooser( 261 content::WebContents* web_contents, SkColor color) OVERRIDE; 262 virtual void RunFileChooser( 263 content::WebContents* tab, 264 const content::FileChooserParams& params) OVERRIDE; 265 virtual bool IsPopupOrPanel( 266 const content::WebContents* source) const OVERRIDE; 267 virtual void MoveContents( 268 content::WebContents* source, const gfx::Rect& pos) OVERRIDE; 269 virtual void NavigationStateChanged(const content::WebContents* source, 270 unsigned changed_flags) OVERRIDE; 271 virtual void ToggleFullscreenModeForTab(content::WebContents* source, 272 bool enter_fullscreen) OVERRIDE; 273 virtual bool IsFullscreenForTabOrPending( 274 const content::WebContents* source) const OVERRIDE; 275 virtual void RequestMediaAccessPermission( 276 content::WebContents* web_contents, 277 const content::MediaStreamRequest& request, 278 const content::MediaResponseCallback& callback) OVERRIDE; 279 virtual content::WebContents* OpenURLFromTab( 280 content::WebContents* source, 281 const content::OpenURLParams& params) OVERRIDE; 282 virtual void AddNewContents(content::WebContents* source, 283 content::WebContents* new_contents, 284 WindowOpenDisposition disposition, 285 const gfx::Rect& initial_pos, 286 bool user_gesture, 287 bool* was_blocked) OVERRIDE; 288 virtual void HandleKeyboardEvent( 289 content::WebContents* source, 290 const content::NativeWebKeyboardEvent& event) OVERRIDE; 291 virtual void RequestToLockMouse(content::WebContents* web_contents, 292 bool user_gesture, 293 bool last_unlocked_by_target) OVERRIDE; 294 295 // content::NotificationObserver implementation. 296 virtual void Observe(int type, 297 const content::NotificationSource& source, 298 const content::NotificationDetails& details) OVERRIDE; 299 300 // web_modal::WebContentsModalDialogManagerDelegate implementation. 301 virtual void SetWebContentsBlocked(content::WebContents* web_contents, 302 bool blocked) OVERRIDE; 303 virtual bool IsWebContentsVisible( 304 content::WebContents* web_contents) OVERRIDE; 305 306 // Helper method to add a message to the renderer's DevTools console. 307 void AddMessageToDevToolsConsole(content::ConsoleMessageLevel level, 308 const std::string& message); 309 310 // Saves the window geometry/position/screen bounds. 311 void SaveWindowPosition(); 312 313 // Helper method to adjust the cached bounds so that we can make sure it can 314 // be visible on the screen. See http://crbug.com/145752 . 315 void AdjustBoundsToBeVisibleOnScreen( 316 const gfx::Rect& cached_bounds, 317 const gfx::Rect& cached_screen_bounds, 318 const gfx::Rect& current_screen_bounds, 319 const gfx::Size& minimum_size, 320 gfx::Rect* bounds) const; 321 322 // Load the app's image, firing a load state change when loaded. 323 void UpdateExtensionAppIcon(); 324 325 // extensions::ExtensionKeybindingRegistry::Delegate implementation. 326 virtual extensions::ActiveTabPermissionGranter* 327 GetActiveTabPermissionGranter() OVERRIDE; 328 329 // web_modal::WebContentsModalDialogManagerDelegate implementation. 330 virtual web_modal::WebContentsModalDialogHost* 331 GetWebContentsModalDialogHost() OVERRIDE; 332 333 // Callback from web_contents()->DownloadFavicon. 334 void DidDownloadFavicon(int id, 335 int http_status_code, 336 const GURL& image_url, 337 int requested_size, 338 const std::vector<SkBitmap>& bitmaps); 339 340 // extensions::IconImage::Observer implementation. 341 virtual void OnExtensionIconImageChanged( 342 extensions::IconImage* image) OVERRIDE; 343 344 Profile* profile_; // weak pointer - owned by ProfileManager. 345 // weak pointer - owned by ExtensionService. 346 const extensions::Extension* extension_; 347 const std::string extension_id_; 348 349 // Identifier that is used when saving and restoring geometry for this 350 // window. 351 std::string window_key_; 352 353 const SessionID session_id_; 354 WindowType window_type_; 355 content::NotificationRegistrar registrar_; 356 357 // Icon shown in the task bar. 358 gfx::Image app_icon_; 359 360 // Icon URL to be used for setting the app icon. If not empty, app_icon_ will 361 // be fetched and set using this URL. 362 GURL app_icon_url_; 363 364 // An object to load the app's icon as an extension resource. 365 scoped_ptr<extensions::IconImage> app_icon_image_; 366 367 scoped_ptr<NativeAppWindow> native_app_window_; 368 scoped_ptr<ShellWindowContents> shell_window_contents_; 369 scoped_ptr<Delegate> delegate_; 370 371 base::WeakPtrFactory<ShellWindow> image_loader_ptr_factory_; 372 373 // Fullscreen entered by app.window api. 374 bool fullscreen_for_window_api_; 375 // Fullscreen entered by HTML requestFullscreen. 376 bool fullscreen_for_tab_; 377 378 DISALLOW_COPY_AND_ASSIGN(ShellWindow); 379 }; 380 381 } // namespace apps 382 383 #endif // APPS_SHELL_WINDOW_H_ 384