summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r--chrome/browser/extensions/api/app_window/app_window_api.cc32
-rw-r--r--chrome/browser/extensions/platform_app_browsertest.cc12
-rw-r--r--chrome/browser/extensions/shell_window_geometry_cache.cc21
-rw-r--r--chrome/browser/extensions/shell_window_geometry_cache.h13
-rw-r--r--chrome/browser/extensions/shell_window_geometry_cache_unittest.cc101
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));
}
}