| Index: apps/shell_window.cc
 | 
| diff --git a/apps/shell_window.cc b/apps/shell_window.cc
 | 
| index 691bff8d947aaa19dc33249435b81464fc39e65f..590784ee39e954d99caca80582fd239bdd8e0f31 100644
 | 
| --- a/apps/shell_window.cc
 | 
| +++ b/apps/shell_window.cc
 | 
| @@ -56,6 +56,57 @@ const int kDefaultHeight = 384;
 | 
|  
 | 
|  namespace apps {
 | 
|  
 | 
| +ShellWindow::SizeConstraints::SizeConstraints()
 | 
| +    : maximum_size_(kUnboundedSize, kUnboundedSize) {
 | 
| +}
 | 
| +
 | 
| +ShellWindow::SizeConstraints::SizeConstraints(const gfx::Size& min_size,
 | 
| +                                              const gfx::Size& max_size)
 | 
| +    : minimum_size_(min_size),
 | 
| +      maximum_size_(max_size) {
 | 
| +}
 | 
| +
 | 
| +ShellWindow::SizeConstraints::~SizeConstraints() {}
 | 
| +
 | 
| +gfx::Size ShellWindow::SizeConstraints::ClampSize(gfx::Size size) const {
 | 
| +  const gfx::Size max_size = GetMaximumSize();
 | 
| +  if (max_size.width() != kUnboundedSize)
 | 
| +    size.set_width(std::min(size.width(), GetMaximumSize().width()));
 | 
| +  if (max_size.height() != kUnboundedSize)
 | 
| +    size.set_height(std::min(size.height(), GetMaximumSize().height()));
 | 
| +  size.SetToMax(GetMinimumSize());
 | 
| +  return size;
 | 
| +}
 | 
| +
 | 
| +bool ShellWindow::SizeConstraints::HasMinimumSize() const {
 | 
| +  return GetMinimumSize().width() != kUnboundedSize ||
 | 
| +      GetMinimumSize().height() != kUnboundedSize;
 | 
| +}
 | 
| +
 | 
| +bool ShellWindow::SizeConstraints::HasMaximumSize() const {
 | 
| +  const gfx::Size max_size = GetMaximumSize();
 | 
| +  return max_size.width() != kUnboundedSize ||
 | 
| +      max_size.height() != kUnboundedSize;
 | 
| +}
 | 
| +
 | 
| +bool ShellWindow::SizeConstraints::HasFixedSize() const {
 | 
| +  return !GetMinimumSize().IsEmpty() && GetMinimumSize() == GetMaximumSize();
 | 
| +}
 | 
| +
 | 
| +gfx::Size ShellWindow::SizeConstraints::GetMinimumSize() const {
 | 
| +  return minimum_size_;
 | 
| +}
 | 
| +
 | 
| +gfx::Size ShellWindow::SizeConstraints::GetMaximumSize() const {
 | 
| +  return gfx::Size(
 | 
| +      maximum_size_.width() == kUnboundedSize ?
 | 
| +          kUnboundedSize :
 | 
| +          std::max(maximum_size_.width(), minimum_size_.width()),
 | 
| +      maximum_size_.height() == kUnboundedSize ?
 | 
| +          kUnboundedSize :
 | 
| +          std::max(maximum_size_.height(), minimum_size_.height()));
 | 
| +}
 | 
| +
 | 
|  ShellWindow::CreateParams::CreateParams()
 | 
|    : window_type(ShellWindow::WINDOW_TYPE_DEFAULT),
 | 
|      frame(ShellWindow::FRAME_CHROME),
 | 
| @@ -101,67 +152,9 @@ void ShellWindow::Init(const GURL& url,
 | 
|    extensions::SetViewType(web_contents, extensions::VIEW_TYPE_APP_SHELL);
 | 
|  
 | 
|    // Initialize the window
 | 
| -  window_type_ = params.window_type;
 | 
| -
 | 
| -  gfx::Rect bounds = params.bounds;
 | 
| -
 | 
| -  if (bounds.width() == 0)
 | 
| -    bounds.set_width(kDefaultWidth);
 | 
| -  if (bounds.height() == 0)
 | 
| -    bounds.set_height(kDefaultHeight);
 | 
| -
 | 
| -  // If left and top are left undefined, the native shell window will center
 | 
| -  // the window on the main screen in a platform-defined manner.
 | 
| -
 | 
| -  CreateParams new_params = params;
 | 
| -
 | 
| -  // Load cached state if it exists.
 | 
| -  if (!params.window_key.empty()) {
 | 
| -    window_key_ = params.window_key;
 | 
| -
 | 
| -    ShellWindowGeometryCache* cache = ShellWindowGeometryCache::Get(profile());
 | 
| -
 | 
| -    gfx::Rect cached_bounds;
 | 
| -    gfx::Rect cached_screen_bounds;
 | 
| -    ui::WindowShowState cached_state = ui::SHOW_STATE_DEFAULT;
 | 
| -    if (cache->GetGeometry(extension()->id(), params.window_key, &cached_bounds,
 | 
| -                           &cached_screen_bounds, &cached_state)) {
 | 
| -      // App window has cached screen bounds, make sure it fits on screen in
 | 
| -      // case the screen resolution changed.
 | 
| -      gfx::Screen* screen = gfx::Screen::GetNativeScreen();
 | 
| -      gfx::Display display = screen->GetDisplayMatching(cached_bounds);
 | 
| -      gfx::Rect current_screen_bounds = display.work_area();
 | 
| -      AdjustBoundsToBeVisibleOnScreen(cached_bounds,
 | 
| -                                      cached_screen_bounds,
 | 
| -                                      current_screen_bounds,
 | 
| -                                      params.minimum_size,
 | 
| -                                      &bounds);
 | 
| -      new_params.state = cached_state;
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  gfx::Size& minimum_size = new_params.minimum_size;
 | 
| -  gfx::Size& maximum_size = new_params.maximum_size;
 | 
| -
 | 
| -  // In the case that minimum size > maximum size, we consider the minimum
 | 
| -  // size to be more important.
 | 
| -  if (maximum_size.width() && maximum_size.width() < minimum_size.width())
 | 
| -    maximum_size.set_width(minimum_size.width());
 | 
| -  if (maximum_size.height() && maximum_size.height() < minimum_size.height())
 | 
| -    maximum_size.set_height(minimum_size.height());
 | 
| -
 | 
| -  if (maximum_size.width() && bounds.width() > maximum_size.width())
 | 
| -    bounds.set_width(maximum_size.width());
 | 
| -  if (bounds.width() != INT_MIN && bounds.width() < minimum_size.width())
 | 
| -    bounds.set_width(minimum_size.width());
 | 
| -
 | 
| -  if (maximum_size.height() && bounds.height() > maximum_size.height())
 | 
| -    bounds.set_height(maximum_size.height());
 | 
| -  if (bounds.height() != INT_MIN && bounds.height() < minimum_size.height())
 | 
| -    bounds.set_height(minimum_size.height());
 | 
| -
 | 
| -  new_params.bounds = bounds;
 | 
| -
 | 
| +  CreateParams new_params = LoadDefaultsAndConstrain(params);
 | 
| +  window_type_ = new_params.window_type;
 | 
| +  window_key_ = new_params.window_key;
 | 
|    native_app_window_.reset(delegate_->CreateNativeAppWindow(this, new_params));
 | 
|  
 | 
|    if (!new_params.hidden) {
 | 
| @@ -190,7 +183,7 @@ void ShellWindow::Init(const GURL& url,
 | 
|    registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
 | 
|                   content::NotificationService::AllSources());
 | 
|  
 | 
| -  shell_window_contents_->LoadContents(params.creator_process_id);
 | 
| +  shell_window_contents_->LoadContents(new_params.creator_process_id);
 | 
|  
 | 
|    // Prevent the browser process from shutting down while this window is open.
 | 
|    chrome::StartKeepAlive();
 | 
| @@ -643,6 +636,50 @@ void ShellWindow::AdjustBoundsToBeVisibleOnScreen(
 | 
|    }
 | 
|  }
 | 
|  
 | 
| +ShellWindow::CreateParams ShellWindow::LoadDefaultsAndConstrain(
 | 
| +    CreateParams params) const {
 | 
| +  gfx::Rect bounds = params.bounds;
 | 
| +
 | 
| +  if (bounds.width() == 0)
 | 
| +    bounds.set_width(kDefaultWidth);
 | 
| +  if (bounds.height() == 0)
 | 
| +    bounds.set_height(kDefaultHeight);
 | 
| +
 | 
| +  // If left and top are left undefined, the native shell window will center
 | 
| +  // the window on the main screen in a platform-defined manner.
 | 
| +
 | 
| +  // Load cached state if it exists.
 | 
| +  if (!params.window_key.empty()) {
 | 
| +    ShellWindowGeometryCache* cache = ShellWindowGeometryCache::Get(profile());
 | 
| +
 | 
| +    gfx::Rect cached_bounds;
 | 
| +    gfx::Rect cached_screen_bounds;
 | 
| +    ui::WindowShowState cached_state = ui::SHOW_STATE_DEFAULT;
 | 
| +    if (cache->GetGeometry(extension()->id(), params.window_key,
 | 
| +                           &cached_bounds, &cached_screen_bounds,
 | 
| +                           &cached_state)) {
 | 
| +      // App window has cached screen bounds, make sure it fits on screen in
 | 
| +      // case the screen resolution changed.
 | 
| +      gfx::Screen* screen = gfx::Screen::GetNativeScreen();
 | 
| +      gfx::Display display = screen->GetDisplayMatching(cached_bounds);
 | 
| +      gfx::Rect current_screen_bounds = display.work_area();
 | 
| +      AdjustBoundsToBeVisibleOnScreen(cached_bounds,
 | 
| +                                      cached_screen_bounds,
 | 
| +                                      current_screen_bounds,
 | 
| +                                      params.minimum_size,
 | 
| +                                      &bounds);
 | 
| +      params.state = cached_state;
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  SizeConstraints size_constraints(params.minimum_size, params.maximum_size);
 | 
| +  params.bounds.set_size(size_constraints.ClampSize(bounds.size()));
 | 
| +  params.minimum_size = size_constraints.GetMinimumSize();
 | 
| +  params.maximum_size = size_constraints.GetMaximumSize();
 | 
| +
 | 
| +  return params;
 | 
| +}
 | 
| +
 | 
|  // static
 | 
|  SkRegion* ShellWindow::RawDraggableRegionsToSkRegion(
 | 
|        const std::vector<extensions::DraggableRegion>& regions) {
 | 
| 
 |