diff options
Diffstat (limited to 'chrome/browser/extensions')
5 files changed, 125 insertions, 54 deletions
diff --git a/chrome/browser/extensions/api/app_window/app_window_api.cc b/chrome/browser/extensions/api/app_window/app_window_api.cc index a421b95..2dccb33 100644 --- a/chrome/browser/extensions/api/app_window/app_window_api.cc +++ b/chrome/browser/extensions/api/app_window/app_window_api.cc @@ -22,6 +22,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/url_constants.h" #include "googleurl/src/gurl.h" +#include "ui/base/ui_base_types.h" #include "ui/gfx/rect.h" #if defined(USE_ASH) @@ -82,6 +83,20 @@ class DevToolsRestorer : public content::NotificationObserver { content::NotificationRegistrar registrar_; }; +void SetCreateResultFromShellWindow(ShellWindow* window, + base::DictionaryValue* result) { + result->SetBoolean("fullscreen", window->GetBaseWindow()->IsFullscreen()); + result->SetBoolean("minimized", window->GetBaseWindow()->IsMinimized()); + result->SetBoolean("maximized", window->GetBaseWindow()->IsMaximized()); + DictionaryValue* boundsValue = new DictionaryValue(); + gfx::Rect bounds = window->GetClientBounds(); + boundsValue->SetInteger("left", bounds.x()); + boundsValue->SetInteger("top", bounds.y()); + boundsValue->SetInteger("width", bounds.width()); + boundsValue->SetInteger("height", bounds.height()); + result->Set("bounds", boundsValue); +} + } // namespace void AppWindowCreateFunction::SendDelayedResponse() { @@ -140,6 +155,7 @@ bool AppWindowCreateFunction::RunImpl() { window->GetBaseWindow()->Show(); base::DictionaryValue* result = new base::DictionaryValue; result->Set("viewId", base::Value::CreateIntegerValue(view_id)); + SetCreateResultFromShellWindow(window, result); result->SetBoolean("existingWindow", true); result->SetBoolean("injectTitlebar", false); SetResult(result); @@ -230,13 +246,13 @@ bool AppWindowCreateFunction::RunImpl() { case extensions::api::app_window::STATE_NORMAL: break; case extensions::api::app_window::STATE_FULLSCREEN: - create_params.state = ShellWindow::CreateParams::STATE_FULLSCREEN; + create_params.state = ui::SHOW_STATE_FULLSCREEN; break; case extensions::api::app_window::STATE_MAXIMIZED: - create_params.state = ShellWindow::CreateParams::STATE_MAXIMIZED; + create_params.state = ui::SHOW_STATE_MAXIMIZED; break; case extensions::api::app_window::STATE_MINIMIZED: - create_params.state = ShellWindow::CreateParams::STATE_MINIMIZED; + create_params.state = ui::SHOW_STATE_MINIMIZED; break; } } else { @@ -266,7 +282,7 @@ bool AppWindowCreateFunction::RunImpl() { #endif if (force_maximize) - create_params.state = ShellWindow::CreateParams::STATE_MAXIMIZED; + create_params.state = ui::SHOW_STATE_MAXIMIZED; ShellWindow* shell_window = ShellWindow::Create(profile(), GetExtension(), url, create_params); @@ -285,13 +301,7 @@ bool AppWindowCreateFunction::RunImpl() { result->Set("injectTitlebar", base::Value::CreateBooleanValue(inject_html_titlebar)); result->Set("id", base::Value::CreateStringValue(shell_window->window_key())); - DictionaryValue* boundsValue = new DictionaryValue(); - gfx::Rect bounds = shell_window->GetClientBounds(); - boundsValue->SetInteger("left", bounds.x()); - boundsValue->SetInteger("top", bounds.y()); - boundsValue->SetInteger("width", bounds.width()); - boundsValue->SetInteger("height", bounds.height()); - result->Set("bounds", boundsValue); + SetCreateResultFromShellWindow(shell_window, result); SetResult(result); if (ShellWindowRegistry::Get(profile())->HadDevToolsAttached(created_view)) { diff --git a/chrome/browser/extensions/platform_app_browsertest.cc b/chrome/browser/extensions/platform_app_browsertest.cc index 642f948..3e9551a 100644 --- a/chrome/browser/extensions/platform_app_browsertest.cc +++ b/chrome/browser/extensions/platform_app_browsertest.cc @@ -632,6 +632,18 @@ IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, ASSERT_TRUE(RunPlatformAppTest("platform_apps/geometry")); } +// This appears to be unreliable on linux. +// TODO(stevenjb): Investigate and enable +#if defined(OS_LINUX) && !defined(USE_ASH) +#define MAYBE_ShellWindowRestoreState DISABLED_ShellWindowRestoreState +#else +#define MAYBE_ShellWindowRestoreState ShellWindowRestoreState +#endif +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, + MAYBE_ShellWindowRestoreState) { + ASSERT_TRUE(RunPlatformAppTest("platform_apps/restore_state")); +} + namespace { class PlatformAppDevToolsBrowserTest : public PlatformAppBrowserTest { diff --git a/chrome/browser/extensions/shell_window_geometry_cache.cc b/chrome/browser/extensions/shell_window_geometry_cache.cc index f08f085..7d01f9c 100644 --- a/chrome/browser/extensions/shell_window_geometry_cache.cc +++ b/chrome/browser/extensions/shell_window_geometry_cache.cc @@ -40,18 +40,21 @@ ShellWindowGeometryCache::~ShellWindowGeometryCache() { void ShellWindowGeometryCache::SaveGeometry( const std::string& extension_id, const std::string& window_id, - const gfx::Rect& bounds) { + const gfx::Rect& bounds, + ui::WindowShowState window_state) { ExtensionData& extension_data = cache_[extension_id]; // If we don't have any unsynced changes and this is a duplicate of what's // already in the cache, just ignore it. if (extension_data[window_id].bounds == bounds && + extension_data[window_id].window_state == window_state && !ContainsKey(unsynced_extensions_, extension_id)) return; base::Time now = base::Time::Now(); extension_data[window_id].bounds = bounds; + extension_data[window_id].window_state = window_state; extension_data[window_id].last_change = now; if (extension_data.size() > kMaxCachedWindows) { @@ -99,6 +102,7 @@ void ShellWindowGeometryCache::SyncToStorage() { value->SetInteger("y", bounds.y()); value->SetInteger("w", bounds.width()); value->SetInteger("h", bounds.height()); + value->SetInteger("state", it->second.window_state); value->SetString( "ts", base::Int64ToString(it->second.last_change.ToInternalValue())); dict->SetWithoutPathExpansion(it->first, value); @@ -110,7 +114,8 @@ void ShellWindowGeometryCache::SyncToStorage() { bool ShellWindowGeometryCache::GetGeometry( const std::string& extension_id, const std::string& window_id, - gfx::Rect* bounds) const { + gfx::Rect* bounds, + ui::WindowShowState* window_state) const { std::map<std::string, ExtensionData>::const_iterator extension_data_it = cache_.find(extension_id); @@ -125,7 +130,10 @@ bool ShellWindowGeometryCache::GetGeometry( if (window_data == extension_data_it->second.end()) return false; - *bounds = window_data->second.bounds; + if (bounds) + *bounds = window_data->second.bounds; + if (window_state) + *window_state = window_data->second.window_state; return true; } @@ -171,8 +179,7 @@ void ShellWindowGeometryCache::OnExtensionLoaded( // overwrite that information since it is probably the result of an // application starting up very quickly. const std::string& window_id = it.key(); - ExtensionData::iterator cached_window = - extension_data.find(window_id); + ExtensionData::iterator cached_window = extension_data.find(window_id); if (cached_window == extension_data.end()) { const base::DictionaryValue* stored_window; if (it.value().GetAsDictionary(&stored_window)) { @@ -187,6 +194,10 @@ void ShellWindowGeometryCache::OnExtensionLoaded( window_data.bounds.set_width(i); if (stored_window->GetInteger("h", &i)) window_data.bounds.set_height(i); + if (stored_window->GetInteger("state", &i)) { + window_data.window_state = + static_cast<ui::WindowShowState>(i); + } std::string ts_as_string; if (stored_window->GetString("ts", &ts_as_string)) { int64 ts; diff --git a/chrome/browser/extensions/shell_window_geometry_cache.h b/chrome/browser/extensions/shell_window_geometry_cache.h index 744077c..5648b0d 100644 --- a/chrome/browser/extensions/shell_window_geometry_cache.h +++ b/chrome/browser/extensions/shell_window_geometry_cache.h @@ -16,6 +16,7 @@ #include "base/values.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" +#include "ui/base/ui_base_types.h" #include "ui/gfx/rect.h" class Profile; @@ -36,13 +37,19 @@ class ShellWindowGeometryCache virtual ~ShellWindowGeometryCache(); + // Save the geometry and state associated with |extension_id| and |window_id|. void SaveGeometry(const std::string& extension_id, const std::string& window_id, - const gfx::Rect& bounds); + const gfx::Rect& bounds, + ui::WindowShowState state); + // Get any saved geometry and state associated with |extension_id| and + // |window_id|. If saved data exists, sets |bounds| and |state| if not NULL + // and returns true. bool GetGeometry(const std::string& extension_id, const std::string& window_id, - gfx::Rect* bounds) const; + gfx::Rect* bounds, + ui::WindowShowState* state) const; // Maximum number of windows we'll cache the geometry for per app. static const size_t kMaxCachedWindows = 100; @@ -58,7 +65,9 @@ class ShellWindowGeometryCache private: // Data stored for each window. struct WindowData { + WindowData() : window_state(ui::SHOW_STATE_DEFAULT) {} gfx::Rect bounds; + ui::WindowShowState window_state; base::Time last_change; }; diff --git a/chrome/browser/extensions/shell_window_geometry_cache_unittest.cc b/chrome/browser/extensions/shell_window_geometry_cache_unittest.cc index e349da8..efab64f 100644 --- a/chrome/browser/extensions/shell_window_geometry_cache_unittest.cc +++ b/chrome/browser/extensions/shell_window_geometry_cache_unittest.cc @@ -36,9 +36,11 @@ class ShellWindowGeometryCacheTest : public testing::Test { cache_->SetSyncDelayForTests(0); } - void AddGeometryAndLoadExtension(const std::string& extension_id, - const std::string& window_id, - const gfx::Rect& bounds); + void AddGeometryAndLoadExtension( + const std::string& extension_id, + const std::string& window_id, + const gfx::Rect& bounds, + ui::WindowShowState state); // Spins the UI threads' message loops to make sure any task // posted to sync the geometry to the value store gets a chance to run. @@ -56,14 +58,17 @@ class ShellWindowGeometryCacheTest : public testing::Test { }; void ShellWindowGeometryCacheTest::AddGeometryAndLoadExtension( - const std::string& extension_id, const std::string& window_id, - const gfx::Rect& bounds) { + const std::string& extension_id, + const std::string& window_id, + const gfx::Rect& bounds, + ui::WindowShowState state) { scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); base::DictionaryValue* value = new base::DictionaryValue; value->SetInteger("x", bounds.x()); value->SetInteger("y", bounds.y()); value->SetInteger("w", bounds.width()); value->SetInteger("h", bounds.height()); + value->SetInteger("state", state); dict->SetWithoutPathExpansion(window_id, value); prefs_->prefs()->SetGeometryCache(extension_id, dict.Pass()); LoadExtension(extension_id); @@ -88,8 +93,7 @@ void ShellWindowGeometryCacheTest::UnloadExtension( // Test getting geometry from an empty store. TEST_F(ShellWindowGeometryCacheTest, GetGeometryEmptyStore) { const std::string extension_id = prefs_->AddExtensionAndReturnId("ext1"); - gfx::Rect bounds; - ASSERT_FALSE(cache_->GetGeometry(extension_id, kWindowId, &bounds)); + ASSERT_FALSE(cache_->GetGeometry(extension_id, kWindowId, NULL, NULL)); } // Test getting geometry for an unknown extension. @@ -97,32 +101,37 @@ TEST_F(ShellWindowGeometryCacheTest, GetGeometryUnkownExtension) { const std::string extension_id1 = prefs_->AddExtensionAndReturnId("ext1"); const std::string extension_id2 = prefs_->AddExtensionAndReturnId("ext2"); AddGeometryAndLoadExtension(extension_id1, kWindowId, - gfx::Rect(4, 5, 31, 43)); - gfx::Rect bounds; - ASSERT_FALSE(cache_->GetGeometry(extension_id2, kWindowId, &bounds)); + gfx::Rect(4, 5, 31, 43), + ui::SHOW_STATE_DEFAULT); + ASSERT_FALSE(cache_->GetGeometry(extension_id2, kWindowId, NULL, NULL)); } // Test getting geometry for an unknown window in a known extension. TEST_F(ShellWindowGeometryCacheTest, GetGeometryUnkownWindow) { const std::string extension_id = prefs_->AddExtensionAndReturnId("ext1"); AddGeometryAndLoadExtension(extension_id, kWindowId, - gfx::Rect(4, 5, 31, 43)); - gfx::Rect bounds; - ASSERT_FALSE(cache_->GetGeometry(extension_id, kWindowId2, &bounds)); + gfx::Rect(4, 5, 31, 43), + ui::SHOW_STATE_DEFAULT); + ASSERT_FALSE(cache_->GetGeometry(extension_id, kWindowId2, NULL, NULL)); } -// Test that loading geometry from the store works correctly. -TEST_F(ShellWindowGeometryCacheTest, GetGeometryFromStore) { +// Test that loading geometry and state from the store works correctly. +TEST_F(ShellWindowGeometryCacheTest, GetGeometryAndStateFromStore) { const std::string extension_id = prefs_->AddExtensionAndReturnId("ext1"); gfx::Rect bounds(4, 5, 31, 43); - AddGeometryAndLoadExtension(extension_id, kWindowId, bounds); - gfx::Rect newBounds; - ASSERT_TRUE(cache_->GetGeometry(extension_id, kWindowId, &newBounds)); - ASSERT_EQ(bounds, newBounds); + ui::WindowShowState state = ui::SHOW_STATE_NORMAL; + AddGeometryAndLoadExtension(extension_id, kWindowId, bounds, state); + gfx::Rect new_bounds; + ui::WindowShowState new_state = ui::SHOW_STATE_DEFAULT; + ASSERT_TRUE(cache_->GetGeometry( + extension_id, kWindowId, &new_bounds, &new_state)); + ASSERT_EQ(bounds, new_bounds); + ASSERT_EQ(state, new_state); } -// Test saving geometry to the cache and state store, and reading it back. -TEST_F(ShellWindowGeometryCacheTest, SaveGeometryToStore) { +// Test saving geometry and state to the cache and state store, and reading +// it back. +TEST_F(ShellWindowGeometryCacheTest, SaveGeometryAndStateToStore) { const std::string extension_id = prefs_->AddExtensionAndReturnId("ext1"); const std::string window_id(kWindowId); @@ -131,12 +140,16 @@ TEST_F(ShellWindowGeometryCacheTest, SaveGeometryToStore) { // update geometry stored in cache gfx::Rect bounds(4, 5, 31, 43); - gfx::Rect newBounds; - cache_->SaveGeometry(extension_id, window_id, bounds); + ui::WindowShowState state = ui::SHOW_STATE_NORMAL; + cache_->SaveGeometry(extension_id, window_id, bounds, state); // make sure that immediately reading back geometry works - ASSERT_TRUE(cache_->GetGeometry(extension_id, window_id, &newBounds)); - ASSERT_EQ(bounds, newBounds); + gfx::Rect new_bounds; + ui::WindowShowState new_state = ui::SHOW_STATE_DEFAULT; + ASSERT_TRUE(cache_->GetGeometry( + extension_id, window_id, &new_bounds, &new_state)); + ASSERT_EQ(bounds, new_bounds); + ASSERT_EQ(state, new_state); // unload extension to force cache to save data to the state store UnloadExtension(extension_id); @@ -156,15 +169,20 @@ TEST_F(ShellWindowGeometryCacheTest, SaveGeometryToStore) { ASSERT_EQ(bounds.width(), v); ASSERT_TRUE(dict->GetInteger(window_id + ".h", &v)); ASSERT_EQ(bounds.height(), v); + ASSERT_TRUE(dict->GetInteger(window_id + ".state", &v)); + ASSERT_EQ(state, v); // check to make sure cache indeed doesn't know about this extension anymore - ASSERT_FALSE(cache_->GetGeometry(extension_id, window_id, &newBounds)); + ASSERT_FALSE(cache_->GetGeometry( + extension_id, window_id, &new_bounds, &new_state)); // reload extension LoadExtension(extension_id); // and make sure the geometry got reloaded properly too - ASSERT_TRUE(cache_->GetGeometry(extension_id, window_id, &newBounds)); - ASSERT_EQ(bounds, newBounds); + ASSERT_TRUE(cache_->GetGeometry( + extension_id, window_id, &new_bounds, &new_state)); + ASSERT_EQ(bounds, new_bounds); + ASSERT_EQ(state, new_state); } // Tests that we won't do writes to the state store for SaveGeometry calls @@ -185,20 +203,30 @@ TEST_F(ShellWindowGeometryCacheTest, NoDuplicateWrites) { // Write the first bounds - it should do > 0 writes. EXPECT_CALL(observer, OnPreferenceChanged(_)); - cache_->SaveGeometry(extension_id, kWindowId, bounds1); + cache_->SaveGeometry(extension_id, kWindowId, bounds1, + ui::SHOW_STATE_DEFAULT); WaitForSync(); Mock::VerifyAndClearExpectations(&observer); // Write a different bounds - it should also do > 0 writes. EXPECT_CALL(observer, OnPreferenceChanged(_)); - cache_->SaveGeometry(extension_id, kWindowId, bounds2); + cache_->SaveGeometry(extension_id, kWindowId, bounds2, + ui::SHOW_STATE_DEFAULT); WaitForSync(); Mock::VerifyAndClearExpectations(&observer); - // Write a bounds that's a duplicate of what we already have. This should - // not do any writes. + // Write a different state - it should also do > 0 writes. + EXPECT_CALL(observer, OnPreferenceChanged(_)); + cache_->SaveGeometry(extension_id, kWindowId, bounds2, + ui::SHOW_STATE_NORMAL); + WaitForSync(); + Mock::VerifyAndClearExpectations(&observer); + + // Write a bounds and state that's a duplicate of what we already have. + // This should not do any writes. EXPECT_CALL(observer, OnPreferenceChanged(_)).Times(0); - cache_->SaveGeometry(extension_id, kWindowId, bounds2_duplicate); + cache_->SaveGeometry(extension_id, kWindowId, bounds2_duplicate, + ui::SHOW_STATE_NORMAL); WaitForSync(); Mock::VerifyAndClearExpectations(&observer); } @@ -212,15 +240,16 @@ TEST_F(ShellWindowGeometryCacheTest, MaxWindows) { gfx::Rect bounds(4, 5, 31, 43); for (size_t i = 0; i < ShellWindowGeometryCache::kMaxCachedWindows + 1; ++i) { std::string window_id = "window_" + base::IntToString(i); - cache_->SaveGeometry(extension_id, window_id, bounds); + cache_->SaveGeometry(extension_id, window_id, bounds, + ui::SHOW_STATE_DEFAULT); } // The first added window should no longer have cached geometry. - EXPECT_FALSE(cache_->GetGeometry(extension_id, "window_0", &bounds)); + EXPECT_FALSE(cache_->GetGeometry(extension_id, "window_0", NULL, NULL)); // All other windows should still exist. for (size_t i = 1; i < ShellWindowGeometryCache::kMaxCachedWindows + 1; ++i) { std::string window_id = "window_" + base::IntToString(i); - EXPECT_TRUE(cache_->GetGeometry(extension_id, window_id, &bounds)); + EXPECT_TRUE(cache_->GetGeometry(extension_id, window_id, NULL, NULL)); } } |